Tôi đã viết một hàm Emacs Lisp gọi lệnh shell để xử lý một chuỗi đã cho và trả về chuỗi kết quả. Đây là một đơn giản hóa ví dụ mà chỉ gọi tr
để chuyển đổi văn bản thành chữ hoa:Làm thế nào để ngăn chặn Emacs thiết lập một ranh giới hoàn tác?
(defun test-shell-command (str)
"Apply tr to STR to convert lowercase letters to uppercase."
(let ((buffer (generate-new-buffer "*temp*")))
(with-current-buffer buffer
(insert str)
(call-process-region (point-min) (point-max) "tr" t t nil "'a-z'" "'A-Z'")
(buffer-string))))
Chức năng này tạo ra một bộ đệm tạm thời, chèn văn bản, gọi tr
, thay thế văn bản với kết quả, và trả về kết quả.
Hàm trên hoạt động như mong đợi, khi tôi viết trình bao bọc xung quanh chức năng này để áp dụng lệnh cho khu vực, hai bước là đang được thêm vào lịch sử hoàn tác. Dưới đây là một ví dụ khác:
(defun test-shell-command-region (begin end)
"Apply tr to region from BEGIN to END."
(interactive "*r")
(insert (test-shell-command (delete-and-extract-region begin end))))
Khi tôi gọi M-x test-shell-command-on-region
, khu vực này được thay thế với văn bản chữ hoa, nhưng khi tôi nhấn C-_
(undo
), các bước đầu tiên trong lịch sử undo là trạng thái với các văn bản đã xóa . Di chuyển hai bước trở lại, văn bản gốc được khôi phục.
Câu hỏi của tôi là, làm cách nào để ngăn chặn bước trung gian bị thêm vào lịch sử hoàn tác? Tôi đã đọc số Emacs documentation on undo, nhưng dường như nó không giải quyết được điều này.
Dưới đây là một chức năng để thực hiện chức điều tương tự bằng cách gọi built-in Emacs chức năng upcase
, giống như trước: trên kết quả của delete-and-extract-region
với kết quả được đưa ra để insert
:
(defun test-upcase-region (begin end)
"Apply upcase to region from BEGIN to END."
(interactive "*r")
(insert (upcase (delete-and-extract-region begin end))))
Khi gọi M-x test-upcase-region
, chỉ có một bước trong lịch sử hoàn tác , như mong đợi. Vì vậy, có vẻ như trường hợp gọi test-shell-command
sẽ tạo một đường biên hoàn tác. Điều đó có thể tránh được bằng cách nào đó không?
Cách thông thường để ngăn chặn các lệnh từ cluttering '(undo)' là phải tìm một cách khác nhau một cái không làm điều đó. Ví dụ ở đây là bạn hầu như không bao giờ nên tạo một bộ đệm tạm thời, nhưng thay vào đó làm việc với các đối tượng. – PascalVKooten
Khác với việc đọc và ghi thủ công vào các tệp tạm thời, tôi không chắc chắn về một cách khác để nắm bắt đầu ra quy trình. Ngay cả các lệnh xử lý không đồng bộ như 'start-process' dường như muốn gửi đầu ra tới một bộ đệm. –
@JasonBlevins Tham số thứ năm cho 'shell-command-on-region' là REPLACE, vậy tại sao bạn cần bọc nó? –