在使用 evil-ex,也就是冒号+命令时,有一个非常有趣的功能,输入冒号后,minibuffer 会显示上一次执行的命令,比如
:wq
, 确认可以直接执行这个命令,但是输入任意字符,就会把原先的wq
直接覆盖,接收新的命令输入
我觉得这是一个非常有趣且有用的功能,像 read-string
函数,如果我想要一个默认的输入,可以直接使用
(let ((input (read-string "prompt: " "默认内容"))) (message input))
但我想覆盖这个默认, 则需要先把 默认内容
删除,再输入我想要的字符, 如果不想先删除默认再输入,还可以使用
(let ((input (read-string "prompt: " nil nil "默认内容"))) (message input))
但是这样的话我无法看到默认的内容,当然,也许可以把默认内容追加到 prompt
里,我认为这样不太好看,不是吗
(let* ((default "默认内容") (input (read-string (format "prompt (default %s): " default) nil nil default))) (message input))
evil-ex
提示我一个新的解决方式, 通过查看 evil-ex
源码,可以发现它是使用 minibuffer-with-setup-hook
和 after-change-functions
在minibuffer里插入新内容时先清理默认内容, 再插入新内容, 我简化了相关代码
(let ((input (minibuffer-with-setup-hook 'maple-input-setup (read-string "prompt: " (propertize "默认内容" 'face 'shadow))))) (message input)) (defun maple-input-setup() (add-hook 'after-change-functions 'maple-input-update nil t)) (defun maple-input-update(&optional beg end len string) (let ((string (buffer-substring-no-properties beg end))) (delete-minibuffer-contents) (insert string) (remove-hook 'after-change-functions 'maple-input-update t)))
OK, 就这样