2012-10-24 67 views
1

我正試圖解決dired-do-shell-command(綁定到!)無法在當前和父目錄...'上調用的限制'。堆棧跟蹤粘貼在底部。僅當從某個其他函數調用時觸發函數的建議

我可以如下定義一個建議繞過此錯誤:

(defadvice dired-get-filename (before h-no-error-if-not-filep activate) 
    (ad-set-arg 1 t)) 

但是,這會影響到dired-get-filename所有呼叫。我希望它只在堆棧爲dired-do-shell-command -> dired-get-marked-files -> dired-get-filename時觸發。是

我能想到的唯一辦法如下

  • (with-output-to-string (backtrace))在勸定義搜索匹配
  • 添加周圍建議其他方法來設置一些變量,可以在提醒測試定義。

有沒有更好的方法來做到這一點?我想我從(backtrace)

Debugger entered--Lisp error: (error "Cannot operate on `.' or `..'") 
    signal(error ("Cannot operate on `.' or `..'")) 
    error("Cannot operate on `.' or `..'") 
    dired-get-filename(t) 
    dired-get-marked-files(t nil) 
    (let ((files (dired-get-marked-files t current-prefix-arg))) (list (dired-read-shell-command (concat "! on " "%s: ") current-prefix-arg files) current-prefix-arg files)) 
    call-interactively(dired-do-shell-command nil nil) 

Why can dired-do-shell-command not operate on '.' or '..'?

+0

對於任何人來到這個Q&A後期,這個問題已經被提出,並固定 - 'dired-DO殼command'適用於'.'和'.. '在Emacs的穩定版本中。 – phils

回答

2

您可以在同一時間訪問堆棧跟蹤,一層,通過backtrace-frame。但這真的是在推動黑客攻擊。我建議你也M-x report-emacs-bug要求!工作...

2

尋找訪問當前堆棧跟蹤的數據結構,而不是字符串,我寧願dired-do-shell-command複製到my:dired-do-shell-command,並從那裏調用my:dired-get-marked-files這將調用帶有第三個參數t的dired-get-filename

這樣我複製/粘貼兩個功能,但我最大限度地減少建議常用功能的副作用。

+0

我寧願*不*複製沒有很好的理由。我不知道這些函數經常被使用,但是我從你的答案中得到的建議(:)是最好避免'backtrace',因爲假設它會增加更多的小建議會更加昂貴。 –

+0

最好避免defadvice儘可能。看到我的答案。 –

1

以列表形式訪問堆棧會很好,但不幸的是,它看起來像從elisp無法訪問。 (編輯:啊,我是盲人; backtrace-frame提供了這個,我甚至沒有看到它,謝謝斯特凡。)

第二種選擇(使用額外的建議和標記變量)類似的方法是以啓用或禁用基於外部建議的內部建議。這裏有一個例子:

emacs follow-mode across frames

+0

謝謝。我的第一個想法是啓用/禁用,但我仍然需要頂級函數中的標記變量,對吧? –

1

絕對存檔功能請求。

但在此,你可以使自己的my:dired-do-shell-command沒有 「複製任何代碼」利用flet重新綁定dired-get-filename僅在 你的函數。這接近@ oleg的解決方案。

在此question還討論:

此代碼是未經測試,但你的想法。

(eval-when-compile (require 'cl)) 
(defun my:dired-do-shell-command (&rest args) 
    (interactive) 
    (let ((old-func (symbol-function 'dired-get-filename))) 
    (flet ((dired-get-filename (&rest args) 
           (let ((file (funcall old-func 'verbatim))) 
           (if (memberq file '("." "..")) 
            (if (car args) 
             file 
             (expand-file-name file default-directory)) 
            (apply old-func args))))) 
     (apply 'dired-do-shell-command args)))) 

Emacs黑客濫用defadvice太多了。它混淆可怕的事情 ,應該只保留作爲最後的解決方案。

+0

我很確定我以前見過'flet',但現在'我沒有apropos匹配\'flet'' –

+0

您需要加載cl軟件包以獲取文檔,我已更改代碼以反映此問題。 –

1

使用this-command變量:

(defadvice dired-get-filename (before h-no-error-if-not-filep activate) 
    (when (equal this-command 'dired-do-shell-command) 
    (ad-set-arg 1 t))) 
相關問題