如何准确执行键盘宏?

How to execute keyboard macros exactly?

在许多情况下,emacs 不会完全按照它应该执行的方式执行 kbd 宏。例如

(execute-kbd-macro (read-kbd-macro "C-x C-f"))

而不是用打开的迷你缓冲区结束这个宏的执行 Find file: ... emacs 只是打开第一个可用的文件或 dired 缓冲区(视情况而定)。如何在没有这种误解的情况下执行这种类型的 kbd 宏指令?

Upd 2。这只是此类键盘宏指令的示例,其行为不同于原始行为(即 C-x C-f 按下)。下面是 grep.

的另一个例子

更新。正如@lawlist 提到的,我可以使用

(key-binding (kbd "C-x C-f"))

用于将键序列转换为命令名称。但它只有在有命令时才有效。在更复杂的情况下,例如

(execute-kbd-macro (read-kbd-macro "C-u M-x grep RET"))

此"brute-force"方法不起作用(我想继续为grep编辑模式,但emacs强制完成交互)。

函数 kbd-macro-query 可以在这种情况下提供帮助

(execute-kbd-macro (read-kbd-macro "C-x C-f C-u C-x q"))

但是有一个问题:命令循环级别增加(你可以看到 模式行中方括号的出现)。如果 find-file 例子没关系,但是

(execute-kbd-macro (read-kbd-macro "M-x helm-do-grep RET C-u C-x q"))

给出了错误的行为。我设计了有趣的解决方法

(defun eab/kbd-macro-query ()
  (interactive)
  (let ((executing-kbd-macro defining-kbd-macro))
    (run-with-timer 0.1 nil 'abort-recursive-edit)
    (recursive-edit)))

(global-set-key (kbd "C-x Q") 'eab/kbd-macro-query)

(let ((minibuffer-message-timeout 0))
  (execute-kbd-macro (read-kbd-macro "M-x helm-do-grep RET C-x Q")))

而且效果很好。

(let ((minibuffer-message-timeout 0))
  (execute-kbd-macro (read-kbd-macro "C-u M-x grep RET C-x Q")))

也能正常工作。

但是现在还有一个问题 ido-find-file (C-x C-fido-mode)

(let ((minibuffer-message-timeout 0))
  (execute-kbd-macro (read-kbd-macro "C-x C-f C-x Q")))

ido-text 和 [不匹配]​​ 有问题。

求和。这个方法的主要思想是拦截kbd宏 使用 recursive-edit 执行。 (kbd-macro-query 与 非 nil arg 使用它)。 ido-mode 有一些问题,但是在 一般即使使用复杂的 kbd 序列也能很好地工作

(let ((minibuffer-message-timeout 0))
  (execute-kbd-macro (read-kbd-macro "C-u M-x helm-do-grep RET C-x Q")))