emacs 交互调用和按键模拟

emacs call-interactively and key simulation

我想写一个小函数来保存光标的当前位置,标记整个缓冲区,缩进它然后返回到上一个光标位置。我知道可能有更简单的方法可以达到相同的结果,但我想了解这些原则在 Elisp 中是如何工作的。

这是我尝试做的事情:

(defun indent-whole-buffer () (interactive)                                                                                                                                                                        
    (call-interactively 'point-to-register)                                                                                                                                                                    
    (call-interactively (kbd "RET"))                                                                                                                                                                                 
    (mark-whole-buffer)                                                                                                                                                                                              
    (call-interactively 'indent-region)                                                                                                                                                                              
    (call-interactively 'jump-to-register)                                                                                                                                                                           
    (call-interactively (kbd "RET"))                                                                                                                                                                                 
  )  

这里的阻塞点是(call-interactively (kbd "RET"))如何模拟RET键,就像我在做的那样

M-x point-to-register RET

只需使用save-excursion。这就是它的用途。它保存点和标记以及哪个缓冲区是当前的,然后为您恢复它们。

(如果您确实决定自己推出,并且确实决定按照您计划的方式进行,那么只需直接调用您需要的功能 - 无需使用 call-interactively。使用 C-h f 查看每个函数是如何调用的。例如 (point-to-register ?a) 在寄存器 a 中捕获 point,而 (indent-region (point-min) (point-max)) 缩进整个缓冲区。)

Emacs Lisp 不仅仅是 Emacs 使用的宏语言 — 它是实现语言。许多 Emacs 函数比通过 UI 公开的功能更多的功能,并且通常可以使用此功能编写更紧凑和优雅的代码。

特别是,如果您的目标是缩进整个缓冲区,则无需移动点和标记 — 函数 indent-region 能够缩进任意区域:

(defun indent-whole-buffer ()
  (interactive)
  (indent-region (point-min) (point-max)))