我是一款Emacs包的维护者,该包的整个目的都与用户交互有关。每当我更改代码时,我必须手动测试它是否有效。如果能进行自动化测试就好了,但我不知道如何以所需的方式模拟用户输入。是否有一种交互式函数可以提示用户,然后用模拟打字(包括像C-j这样的组合键)来响应该提示呢?
新内容: 我已经重新实现了with-simulated-input
宏,使用execute-kbd-macro
,所以现在它也可以在批处理模式下工作。您可以在这里查看新的实现。
我在Emacs SX网站上的一个问题中找到了答案。基本上,您必须将所需的按键序列转换为正确的格式,并将其放入unread-command-events
中。例如:
(let ((unread-command-events (listify-key-sequence (kbd "blu RET"))))
(ido-completing-read "Select a color: " '("yellow" "blue")))
正确返回"blue"
。
需要注意的一件事是,你必须确保你的键序列一定会终止命令的交互部分,否则命令将会继续等待输入。确保终止的一种方法是在键序列末尾添加"C-g",以便在命令到达键序列末尾时中止该命令,如果命令已经完成,则任何未使用的输入都将在 let-bindings 超出范围时被丢弃,所以C-g事件不会发出错误信号。因此,更合适的测试可能是:
;; Runs successfully
(condition-case nil
(let ((unread-command-events (listify-key-sequence (kbd "blu RET C-g"))))
(ido-completing-read "Select a color: " '("yellow" "blue")))
(quit (error "Reached end of `unread-command-events' without terminating")))
;; Throws an error
(condition-case nil
(let ((unread-command-events (listify-key-sequence (kbd "blu C-g"))))
(ido-completing-read "Select a color: " '("yellow" "blue")))
(quit (error "Reached end of `unread-command-events' without terminating")))
这种方法的一个重要限制是,尽管它允许您完全非交互式地运行交互式函数,但在批处理模式下的emacs会话中,它将无法工作,可能是因为emacs在批处理模式下根本不处理键盘输入。
execute-kbd-macro
和ERT。我在我的测试文件中实现了一个非常简单的实现。
实际上,这些测试看起来非常整洁 - 几乎就像我在交互式地按键一样:(ert-deftest ivy-read ()
(should (equal
(ivy-with '(ivy-read "pattern: " '("blue" "yellow"))
"C-m")
"blue"))
(should (equal
(ivy-with '(ivy-read "pattern: " '("blue" "yellow"))
"y C-m")
"yellow"))
(should (equal
(ivy-with '(ivy-read "pattern: " '("blue" "yellow"))
"y DEL b C-m")
"blue"))
(should (equal
(ivy-with '(ivy-read "pattern: " '("blue" "yellow"))
"z C-m")
"z")))
ivy-with
实现,似乎需要定义一个命令并将其绑定到一个键上,这是可行的,但如果用户想在他们的 Emacs 会话中运行测试,这会有点混乱。 - Ryan C. Thompsonexecute-kbd-macro
的概念,并重写成尽可能卫生的方式 这里。 它使用 cl-letf
词法地定义命令,确保命令的绑定不会干扰普通键绑定,使用 cl-gensym
来保证没有名称冲突,并处理不完整的输入(例如,在结尾处没有按下RET)或过度的输入(例如,按下两次RET,而一次就足够了)。 结果是...有点长,但不应泄漏任何抽象的部分。 - Ryan C. Thompsonwith-simulated-input
替代了,可以在 https://github.com/DarwinAwardWinner/with-simulated-input 和 MELPA 上找到。 - Sam Brightman
C-x ( "一些命令" C-x )
并编辑它C-x C-k RET
。 - djangolivcompleting-read
的选择,因此我不能通过运行一个命令来测试它。 - Ryan C. Thompson