我编写了一个 Emacs Lisp 函数,它调用一个 shell 命令来处理给定的字符串,并返回结果字符串。这里是一个简化的示例,它只调用
该函数创建一个临时缓冲区,插入文本,调用
上述函数按预期工作,但是当我编写一个包装器来将命令应用于区域时,会向撤消历史记录添加两个步骤。以下是另一个示例:
当我调用
我的问题是,如何防止将中间步骤添加到撤消历史记录中? 我已经阅读了 Emacs documentation on undo, 但据我所知,它似乎没有解决这个问题。
以下是一个函数,通过调用内置的Emacs函数
tr
将文本转换为大写:(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))))
该函数创建一个临时缓冲区,插入文本,调用
tr
,替换文本为结果,并返回结果。上述函数按预期工作,但是当我编写一个包装器来将命令应用于区域时,会向撤消历史记录添加两个步骤。以下是另一个示例:
(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))))
当我调用
M-x test-shell-command-on-region
时,区域内的文本将被替换为大写文本,但是当我按下C-_
(undo
)时,撤销历史记录中的第一步是删除文本的状态。向后两步,原始文本将被恢复。我的问题是,如何防止将中间步骤添加到撤消历史记录中? 我已经阅读了 Emacs documentation on undo, 但据我所知,它似乎没有解决这个问题。
以下是一个函数,通过调用内置的Emacs函数
upcase
来完成相同的操作:使用delete-and-extract-region
的结果,并将结果传递给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))))
当调用M-x test-upcase-region
时,撤销历史记录中只有一个步骤,这是预期的。因此,似乎调用test-shell-command
会创建一个撤销边界。是否可以以某种方式避免这种情况?
(undo)
的常规方法是找到另一种不会这样做的方式。这里的例子是,你几乎永远不应该创建临时缓冲区,而是应该使用对象进行操作。 - PascalVKootenstart-process
),似乎也希望将输出发送到缓冲区。 - Jason Blevinsshell-command-on-region
的第五个参数是 REPLACE,那你为什么需要将其包装起来呢? - event_jr