2012-03-05 87 views
0

[我爲窮人標題道歉,但未能拿出一個更好的]之前defadvice不執行功能?

bin chen問在Google+上:

如何輸入相對路徑(緩衝文件名稱)在#emacs中M-!之後在minibuffer中?

我認爲如果buffer-file-name被保存在寄存器中,它應該是通過調用insert-register訪問(C-X R I),而在shell-command提示。

(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-registerC-X R I),我得到錯誤信息:Register does not contain any text

但是,當我運行list-registers我確實看到FD設置了適當的值。如果我再次運行shell-command,則可以訪問先前保存的寄存器中的值。

是否有可能第一次將寄存器設置得太遲?我如何修復代碼以做我想做的事?

編輯:改變aroundbefore(感謝@phils)

回答

2

注:你已經定義了around意見,而不是before意見。

圍繞通知作爲包裝,並且必須包含標記ad-do-it來執行它正在包裝的函數的代碼。

您已經有效地替換爲調用shell-command功能的身體save-buffer-file-name-in-register

至於你的主要問題,我需要檢查的文件,但我懷疑,因爲參數的建議功能是可以提供建議,原始函數的interactive聲明可能在通知執行之前執行,這可以解釋爲什麼您的寄存器值在交互式shell命令提示符處不可見。

(如果在上面的代碼around確實是你使用的是什麼,但事實上,你還在被提示輸入shell命令似乎驗證這個順序)。當交互形式運行

+0

感謝您的回覆。我正在玩'around'和'before',上面代碼中的「around」是我的emacs緩衝區粘貼不正確的結果。我實際試過並希望問的版本是「之前」版本。 – 2012-03-06 03:42:51

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) 

的替代,但方式awesomer方法是使用yasnippet

+0

感謝您的回覆並鏈接到其他問題。你能否詳細說明你爲什麼認爲它是花哨褲?爲了花哨的褲子?我不熟悉elisp,也沒有正確的做事方式。我認爲'defadvice'是以最少的代碼實現它的完美方式,並且不需要定義額外的鍵綁定。 – 2012-03-06 03:53:43

+0

'defadvice'是最後的解決方案。如果你想堅持原來的方法(即把值放入寄存器),那麼使用自己的命令來調用'shell-command'而不是建議它是非常直接的。此外,命令通常不會大量使用寄存器。 – 2012-03-06 07:36:44