如何在 emacs elisp 中查找哪个文件提供该功能

2024-04-10

目前我正在使用加载历史记录变量来查找某个功能来自的文件。

假设找到该文件的特征gnus来自。

我在暂存缓冲区中执行以下代码,该代码在单独的行中连续打印文件名和符号。

(dolist (var load-history)
  (princ (format "%s\n" (car var)))
  (princ (format "\t%s\n" (cdr var))))

然后搜索“(provide .gnus)”,然后将点移动到行首(Ctrl+A)。 前一行中的文件名是该功能所来自的文件。

这个方法有什么问题吗,或者有更好的方法吗?


我真的不知道你想用这个做什么,但这里有一些注释。

  • 你的方法很好。在我的书中,任何自己解决问题的方法都是好的。

  • @Tom is correct that you shouldn't really need to do this, because the problem is already solved for you by the help system. i.e. C-h f

但这没那么有趣。假设您确实想要一个自动的、更优雅的解决方案。你想要一个函数——locate-feature带有此签名:

(defun locate-feature (feature)
  "Return file-name as string where `feature' was provided"
  ...)

方法一load-history方法

我将仅描述我为解决此问题所采取的步骤:

  1. 您已经完成了最重要的部分 - 找到包含您需要的信息的变量。

  2. 我立即注意到这个变量有很多数据。如果我将它作为单行插入到缓冲区中,Emacs 不会高兴,因为它在处理长行方面非常糟糕。我知道 prett-print 包能够很好地格式化这些数据。所以我打开我的*scratch*缓冲并运行

    M-: (insert (pp-to-string load-history))

  3. 我现在可以看到我正在处理的数据结构。似乎是(伪代码):

    ((file-name
      ((defun|t|provide . symbol)|symbol)*)
     ...)
    
  4. 现在我只写函数

    (eval-when-compile (require 'cl))
    (defun locate-feature (feature)
      "Return file name as string where `feature' was provided"
      (interactive "Sfeature: ")
      (dolist (file-info load-history)
        (mapc (lambda (element)
                (when (and (consp element)
                           (eq (car element) 'provide)
                           (eq (cdr element) feature))
                  (when (called-interactively-p 'any)
                    (message "%s defined in %s" feature (car file-info)))
                  (return (car file-info))))
              (cdr file-info))))
    

    这里的代码非常简单。有不懂的功能可以向 Emacs 询问。

方法2帮助方法

方法一适用于特征。但如果我想知道哪里有 可用函数已定义?不仅仅是功能。

C-h f already tells me that, but I want the file-name in a string, not all of the verbose help text. I want this:

(defun locate-function (func)
  "Return file-name as string where `func' was defined or will be autoloaded"
  ...)

开始了。

  1. C-h f is my starting point, but I really want to read the code that defines describe-function. I do this:

    C-h k C-h f C-x o tab enter

  2. 现在我在help-fns.el在定义describe-function。我只想使用这个函数定义。所以缩小范围是这样的:

    C-x n d

  3. 我有预感,有趣的命令名称中将包含“find”或“locate”,所以我使用occur搜索有趣的线路:

    M-s o find\|locate

    无匹配。嗯。这个 defun 中的台词不多。describe-function-1似乎正在做真正的工作,所以我们尝试一下。

  4. I can visit the definition of describe-function-1 via C-h f. But I already have the file open. imenu is available now:

    C-x n w M-x imenu desc*1 tab enter

  5. 缩小范围并再次搜索:

    C-x n d M-s o up enter

    I see find-lisp-object-file-name这看起来很有希望。

  6. After reading C-h f find-lisp-object-file-name I come up with:

    (defun locate-function (func)
      "Return file-name as string where `func' was defined or will be autoloaded"
      (interactive "Ccommand: ")
      (let ((res (find-lisp-object-file-name func (symbol-function func))))
        (when (called-interactively-p 'any)
          (message "%s defined in %s" func res))
        res))
    

现在去探索 Emacs 吧。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 emacs elisp 中查找哪个文件提供该功能 的相关文章

随机推荐