您可以使用C-u M-:(eval-expression 带有通用前缀参数)来评估任何 Lisp 表达式并将其值插入当前缓冲区(包括迷你缓冲区,只要您将 enable-recursive-minibuffers 设置为非-nil 值)。
在您的示例中:C-u M-: buffer-file-name RET。
请注意,表达式的结果是以 Lisp 形式打印的:也就是说,以这样一种方式引用:随后对 read 的调用将构造一个 equal Lisp 值。对于字符串,这意味着用双引号括起来,这可能会被劣质 shell 解释为您所期望的。但是,您可能会遇到包含特殊字符的字符串的问题,这需要 Elisp 和 shell 进行不同的转义。
更正确的方法是使用shell-quote-argument,就像在菲尔斯的解决方案中一样。这是一个快速定义,它读取 Lisp 表达式并将其值插入到点作为正确引用的 shell 单词:
(defun eval-to-shell-argument (form)
(interactive "XEval: ")
(insert (shell-quote-argument form)))
读取和评估步骤通过使用"X" 作为interactive 的参数自动发生。
编辑添加:正如@tenpn 所指出的,上述解决方案不适用于在弹出M-! 之类的迷你缓冲区中插入像buffer-file-name 这样的缓冲区局部变量(更准确地说,它插入了小缓冲区的缓冲区本地值,这不太可能有用)。这是一个似乎可行的修订版。如果 minibuffer 处于活动状态,它会在读取和评估表达式时使先前选择的窗口的缓冲区暂时处于活动状态。
最终编辑:从@Stefan 的回答中,我看到我应该使用(minibuffer-selected-window) 来查找先前选择的窗口。我还添加了(format "%s" ..) 以允许插入非字符串值,同时仍引用字符串中的特殊字符。这是最终版本:
(defun eval-to-shell-argument ()
(interactive)
(let* ((buffer
(if (minibufferp)
(window-buffer (minibuffer-selected-window))
(current-buffer)))
(result
(with-current-buffer buffer
(eval-minibuffer "Eval: "))))
(insert (shell-quote-argument (format "%s" result)))))