2

現在のディレクトリと親ディレクトリで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)

なぜdired-do-shell-commandが'。'で動作しないのですか?また '..'?

4

5 に答える 5

3

私はむしろ、3番目の引数tで呼び出す呼び出しとの間でコピーdired-do-shell-commandしたいと思います。my:dired-do-shell-commandmy:dired-get-marked-filesdired-get-filename

このようにして、2つの関数をコピーして貼り付けますが、頻繁に使用する関数をアドバイスすることによる副作用を最小限に抑えます。

于 2012-10-24T19:44:19.710 に答える
3

を介して、一度に1つのレイヤーでスタックトレースにアクセスできますbacktrace-frame。しかし、これは本当にハックを推進しています。との作業もM-x report-emacs-bugリクエストすることをお勧めします。!...

于 2012-10-24T21:07:29.543 に答える
1

間違いなく機能リクエストを提出してください。

ただし、つまり、関数内でのみ再バインドするためmy:dired-do-shell-commandに使用することで、「コードをコピー」せずに独自のコードを作成できます。これは@olegのソリューションに近いものです。fletdired-get-filename

この質問でも議論されています:

このコードはテストされていませんが、あなたはその考えを理解しています。

(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しすぎています。それは物事をひどく曖昧にし、最後の手段の解決策としてのみ予約されるべきです。

于 2012-10-25T01:05:27.210 に答える
1

リストとしてスタックにアクセスするのは素晴らしいことですが、残念ながら、elispからはアクセスできないように見えます。(編集:ああ、私は盲目です;backtrace-frameこれを提供します、そして私はそれを見さえしませんでした。ステファンに感謝します。)

2番目のオプション(追加のアドバイスとマーカー変数を使用する)と同様のアプローチは、外側のアドバイスに基づいて内側のアドバイスを有効または無効にすることです。次に例を示します。

emacsフォローモード-フレーム間

于 2012-10-24T20:50:32.847 に答える
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)))
于 2012-10-25T02:14:39.947 に答える