
























Emacs 31 新增的 ert-play-keys 填补了上面两个工具留下的空白。它的实现只有一行:
(defun ert-play-keys (keys) "Play the key sequence KEYS as if it was user input." (funcall (kmacro keys)))
它调用 kmacro 把按键序列当作键盘宏来执行。因为键盘宏走的是完整的命令循环路径——包括 keymap 查找、命令执行、hook 触发——所以它可以触发 keymap 绑定的命令,也能正确处理 called-interactively-p 。
使用时需要配合 ert-with-test-buffer 的 :selected t 参数(或 ert-with-buffer-selected ),这会在临时窗口中选中 buffer,让按键序列能正确路由到目标 buffer:
(ert-deftest test-play-keys-triggers-keymap () "ert-play-keys 可以触发 keymap 绑定的命令。" (ert-with-test-buffer (:selected t) (let (command-ran) (let* ((map (let ((map (make-sparse-keymap))) (define-key map [?b] (lambda () (interactive) (setq command-ran t) (insert "ran"))) map)) (minor-mode-map-alist (cons (cons t map) minor-mode-map-alist))) (ert-play-keys (vconcat [?b]))) (should (eq command-ran t)) (should (string= "ran" (buffer-substring (point-min) (point-max)))))))
ert-play-keys 还可以在一次调用中混合不同类型的输入——既有触发命令的按键,也有直接插入的文本:
(ert-deftest test-play-keys-mixed-input () "ert-play-keys 可以混合按键命令和文本插入。" (ert-with-test-buffer (:selected t) (let* ((map (let ((map (make-sparse-keymap))) (define-key map [?X] (lambda () (interactive) (insert "[pressed-X]"))) map)) (minor-mode-map-alist (cons (cons t map) minor-mode-map-alist))) (ert-play-keys (vconcat [?X] "hello"))) (should (string= "[pressed-X]hello" (buffer-substring (point-min) (point-max))))))
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。