编辑内置函数的正确方法是什么?

What is the correct way to edit an in-built function?

假设我想为内置函数添加一个钩子,例如 dired-find-file

所以我声明并添加我的钩子如下:

(defvar my/dired-find-file-hook nil)
(add-hook 'my/dired-find-file-hook 'my-find-file-function)

我现在需要 运行 (run-hooks 'my/dired-find-file-hook)dired-find-file 的末尾,最好的方法是什么?

我一直在做的只是再次声明整个函数,如下所示,但这感觉像是一种混乱的实现方式。

  (defun dired-find-file ()
    "In Dired, visit the file or directory named on this line."
    (interactive)
    ;; Bind `find-file-run-dired' so that the command works on directories
    ;; too, independent of the user's setting.
    (let ((find-file-run-dired t)
          ;; This binding prevents problems with preserving point in
          ;; windows displaying Dired buffers, because reverting a Dired
          ;; buffer empties it, which changes the places where the
          ;; markers used by switch-to-buffer-preserve-window-point
          ;; point.
          (switch-to-buffer-preserve-window-point
           (if dired-auto-revert-buffer
               nil
             switch-to-buffer-preserve-window-point)))
      (find-file (dired-get-file-for-visit)))
    (run-hooks 'my/dired-find-file-hook))

有没有更好的方法来实现这个目标?

我认为您实际上是在寻求“建议”。你的例子可能是这样的:

(define-advice dired-find-file (:after () my-find-file)
  "Display a message whenever `dired-find-file' is called."
  (message "I'm running after `dired-find-file'."))

可以 运行 自定义代码中的一个钩子,但我希望你直接将 my-find-file-function 中的所有代码直接放在这里,代替该消息。

查看C-hig (elisp)Advice Combinators了解不同的方式您的自定义代码可以相对于原始函数执行。

在 Emacs 中有两种不同的通知实现。这个例子(以及手册中的所有内容)使用的是 nadvice.el 这是较新的方法,但如果你环顾四周,你可能还会发现使用 advice.el 的例子有很多不同之处。 defadvice 是旧式 advice.el,而 define-adviceadvice-add 是新式 nadvice.el