Emacs笔记之minibuffer默认输入


在使用 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-hookafter-change-functionsminibuffer里插入新内容时先清理默认内容, 再插入新内容, 我简化了相关代码

(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, 就这样

作者: honmaple
链接: https://honmaple.me/articles/2021/11/Emacs笔记之minibuffer默认输入.html
版权: 知识共享署名-非商业性使用-相同方式共享4.0国际许可协议
wechat