建议使用emacs交互功能:之前

art*_*can 6 emacs defadvice advising-functions

我想在之前建议一些使用交互式参数的函数,例如find-dired:

(defadvice find-dired (before eab-find-dired activate)
  (message "before!")
  (setq find-args '("-iname '**'" . 10)))
Run Code Online (Sandbox Code Playgroud)

但emacs只在find-dired交互式会话之后执行此建议,而我find-args之前无法设置.如何解决矛盾?

UPD.请注意,不推荐使用defadvice宏.

Tre*_*son 9

artscan以一个可行的答案回答了他自己的问题,但它有点不完整和误导.这也涉及到'interactive,可以在其本身是混乱-因为它看起来是命令的体内定义,但实际使用之前进入功能-在执行任何建议之前(除非这个建议有'interactive电话...)

咨询文件缺少一些细节,这将有助于在这种情况下,让更好的地方看实际上是来源:advice.el.看一下,找到评论部分@ Foo games: An advice tutorial.您也可以在Emacs中找到源代码M-x find-library advice RET.

具体来说,对于这个问题,请查看advice.el标记的部分@@ Advising interactive behavior:- 因为这正是您尝试做的事情.

如果你仔细看,你会发现,建议并没有需要这样的形式around,但可以before为好,它可以是after-虽然这只是自找麻烦.这是因为interactive(并且必须)处理特殊.

因此,以下代码有效(注意before):

(defadvice find-dired (before eab-find-dired (dir args) activate)
  "ignore find-args, hard code \"-iname '**'\""
  (interactive
   (list (read-directory-name "Run find in directory: " nil "" t)
         (read-string "Run find (with args): " '("-iname '**'" . 10)
                      '(find-args-history . 1)))))
Run Code Online (Sandbox Code Playgroud)

正如其他人所说,可能更清洁的方法是编写自己的函数,我认为最简单的是Lindydancer答案.

建议是一个非常诱人的工具,但很容易过度使用.我不会说它很危险,但应该谨慎使用.当编写自己的函数不起作用时,似乎最好使用它 - 例如,更改由您无法修改的代码调用的函数的行为.我认为这种情况的好例子可以在这里,这里这里找到(为了自己的号角).


Lin*_*cer 5

Emacs interactive在调用函数之前先获取规范。

通常,使用并不是一个好主意defadvice,因此我建议您定义自己的函数并将其绑定到适当的键。例如:

(defun my-find-dired ()
  (interactive)
  (let ((find-args '("-iname '**'" . 10)))
    (call-interactively 'find-dired)))
Run Code Online (Sandbox Code Playgroud)

当然,如果您认为此设置是您希望对所有调用进行以下操作,则也可以简单地执行以下操作find-dired

(setq find-args '("-iname '**'" . 10))
Run Code Online (Sandbox Code Playgroud)