Search code examples
emacselispadvising-functionsdefadvice

trigger advice on a function only when called from a certain other function


I am trying to work around the restriction that dired-do-shell-command (bound to !) cannot be called on current and parent directories . and ..'. The stack-trace is pasted at the bottom.

I can define an advice as below to bypass this error:

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

But this affects all calls to the dired-get-filename. I would like it to trigger only when the stack is dired-do-shell-command -> dired-get-marked-files -> dired-get-filename.

The only approaches I can think of are as follows

  • Search for matches in (with-output-to-string (backtrace)) in the advise definition
  • Add around advises to the other methods to set some variable which can be tested in the advise definition.

Is there better way to do it? I guess I am looking for access to the current stack-trace as a data structure instead of the string from (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 '..'?


Solution

  • You can access the stack trace, one layer at a time, via backtrace-frame. But this is really pushing the hack. I recommend you also M-x report-emacs-bug requesting for ! to work on . and ...