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

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 ...

于 2012-10-24T21:07:29.543 回答
3

我宁愿从那里复制调用dired-do-shell-command,该调用将使用第三个参数 t 调用。my:dired-do-shell-commandmy:dired-get-marked-filesdired-get-filename

这样我复制/粘贴了两个函数,但我最大限度地减少了建议常用函数的副作用。

于 2012-10-24T19:44:19.710 回答
1

将堆栈作为列表访问会很棒,但不幸的是,这似乎无法从 elisp 访问。(编辑:啊,我是盲人;backtrace-frame提供了这个,我什至没有看它。谢谢斯特凡。)

与您的第二个选项(使用额外建议和标记变量)类似的方法是仅根据外部建议启用或禁用内部建议。这是一个例子:

跨帧的emacs跟随模式

于 2012-10-24T20:50:32.847 回答
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

使用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 回答