如何找到哪个文件提供(d)emacs elisp中的功能

时间:2012-03-08 11:48:47

标签: emacs elisp

目前我正在使用 load-history 变量来查找功能来自的文件。

假设找到 gnus 功能来自的文件。

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

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

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

这种方法有什么问题,或者存在更好的方法。

4 个答案:

答案 0 :(得分:8)

我真的不知道你在尝试做什么,但这里有一些注意事项。

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

  • @Tom是正确的,你不应该真的需要这样做,因为问题已经由帮助系统解决了。即 C-h f

但那不是那么有趣。假设你真的想要一个自动,更优雅的解决方案。你想要一个带有这个签名的函数 - locate-feature

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

方法1 load-history方法

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

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

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

    M- :(插入(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询问您不理解的功能。

  5. 方法2帮助方法

    方法一适用于功能。但是,如果我想知道哪里有什么 可用功能定义了吗?不只是功能。

    C-h f 已经告诉我了,但我想要一个字符串中的文件名,而不是所有详细的帮助文本。我想要这个:

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

    我们走了。

    1. C-h f 是我的出发点,但我真的想阅读定义describe-function的代码。我这样做:

      C-h k C-h f C-x o tab 输入

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

      C-x n d

    3. 我有一种预感,有趣的命令会在其名称中“找到”或“找到”,所以我使用occur来搜索有趣的行:

      M-s o find \ | locate

      没有比赛。嗯。在这个defun中没有很多线。 describe-function-1似乎在做真正的工作,所以我们试试。

    4. 我可以通过 C-h f 访问describe-function-1的定义。但我已经打开了文件。 imenu现已发布:

      Cx nw Mx imenu desc * 1 tab 输入

    5. 缩小并再次搜索:

      C-x n d M-s o up 输入

      我看到find-lisp-object-file-name看起来很有希望。

    6. 读完 C-h f find-lisp-object-file-name 后,我想出了:

      (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))
      
    7. 现在去探索Emacs吧。

答案 1 :(得分:4)

只需使用symbol-file即可。它扫描格式为load-history的{​​{1}}

Each entry has the form `(provide . FEATURE)',
`(require . FEATURE)', `(defun . FUNCTION)', `(autoload . SYMBOL)',
`(defface . SYMBOL)', or `(t . SYMBOL)'.  Entries like `(t . SYMBOL)'
may precede a `(defun . FUNCTION)' entry, and means that SYMBOL was an
autoload before this file redefined it as a function.  In addition,
entries may also be single symbols, which means that SYMBOL was
defined by `defvar' or `defconst'.

所以称之为:

(symbol-file 'scheme 'provide)        ; Who provide feature.
(symbol-file 'nxml-mode-hook 'defvar) ; Where variable defined.
(symbol-file 'message-send 'defun)    ; Where function defined.
(symbol-file 'scheme)    ; Look for symbol despite its type.

答案 2 :(得分:2)

locate-library

...尝试 M - : (locate-library "my-feature")

例如:(locate-library "gnus")

答案 3 :(得分:1)

它没有任何问题,但为什么它比获得关键或功能的帮助更简单?例如,如果您使用gnus命令并且想要知道它来自何处,那么您可以使用C-h k并告诉您其定义来自哪个elisp文件。

相关问题