[我为糟糕的头衔道歉,但无法想出更好的头衔。]
bin chen在Google +上询问:
如何在#emacs中
M-!
后的迷你缓冲区中输入(buffer-file-name)的相对路径?
我想如果buffer-file-name
保存在寄存器中,则应该在insert-register
提示符处调用shell-command
( Cx ri )来访问它。
(defun save-buffer-file-name-in-register ()
(set-register ?F (buffer-file-name))
(set-register ?D (file-name-directory buffer-file-name)))
(defadvice shell-command (before save-buffer-file-name)
"Save buffer-file-name to register F before running shell-command"
(save-buffer-file-name-in-register))
(ad-activate 'shell-command)
当我调用shell-command
( M - !)后跟insert-register
( Cx ri )时,收到错误消息:{{ 1}}。
但是当我运行Register does not contain any text
时,我确实看到寄存器list-registers
和F
设置了适当的值。如果我再次运行D
,我可以访问先前保存的寄存器中的值。
寄存器第一次设置得太晚了吗?如何修复代码以执行我想要的操作?
修改:将shell-command
更改为around
(感谢@phils)
答案 0 :(得分:2)
n.b。您已定义around
建议,而不是before
建议。
Around通知充当包装器,并且必须包含令牌ad-do-it
以执行它正在包装的函数的代码。
您通过调用shell-command
save-buffer-file-name-in-register
函数的正文
关于你的主要问题,我需要检查文档,但我怀疑因为建议函数的参数可用于建议,原始函数的interactive
声明可能在建议之前执行,这可以解释为什么你的寄存器值在交互式shell命令提示符下不可见。
(如果上面代码中的around
确实是您正在使用的,那么您仍然被提示输入shell命令的事实似乎会验证此序列。)
答案 1 :(得分:2)
当交互式表单运行时,您的建议尚未执行。请参阅:此question
如果您希望坚持使用此方法,则需要在建议中指定一个重新定义原始内容的交互式表单。然而,这种方法对于花哨的裤子来说有点花哨。
只需定义您自己的交互式功能,无需注册即可完成您想要的任务。
(defun insert-cur-dir ()
(interactive)
(let ((dir-name (file-name-directory (buffer-file-name (window-buffer (minibuffer-selected-window))))))
(insert (or dir-name ""))))
(define-key minibuffer-local-map (kbd "C-c i") 'insert-cur-dir)
另一种方法是使用yasnippet。