如何找到哪个文件提供(d)emacs elisp中的功能 [英] How to find which file provide(d) the feature in emacs elisp

查看:125
本文介绍了如何找到哪个文件提供(d)emacs elisp中的功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



假设找到文件特征 gnus 来自



我在临时缓冲区中执行以下代码,连续打印文件名和符号。

 (dolist(var load-history)
(princ(格式%s\\\
(car var)))
(princ(格式\t%s\\\
(cdr var))))

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



此方法是否有任何错误或更好的方法存在

解决方案

我真的不知道你在做什么,但这里有一些注释。 / p>


  • 您的方法很好。任何一种方法来解决您自己的问题解决方案在我的书中很好。


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




但这不是很有趣。假设你真的想要一个自动,更优雅的解决方案。您需要一个功能 - locate-feature 与此签名:

 (defun locate-feature(feature)
返回文件名作为字符串,其中提供功能
...)



方法1 负载历史方法



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




  1. 你已经有了最重要的部分 - 找到所需信息的变量。


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



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


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

     ((文件名
    ((defun | t |提供。符号)|符号)*)
    ...)


  4. 只需编写函数

     (eval-when-compile(require'cl))
    (defun locate-feature
    (交互式Sfeature:)
    (dolist(file-info load-history)
    (mapc) (lambda(元素)
    (当(和(consp元素)
    (eq(car element)'提供)
    (eq(cdr元素)功能))
    调用交互式p'any)
    (消息%s在%s中定义功能(car file-info)))
    (return(car file-info))))
    (cdr file-info))))

    这里的代码很简单。向Emacs询问您不明白的功能。




方法2帮助方法



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



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

 (defun locate-function(func)
返回文件名作为字符串,其中`func '被定义或将被自动加载
...)

/ p>


  1. Chf 是我的出发点,但我真的想读取定义描述功能。我这样做:



    Ch k Ch f Cx o 选项卡 输入


  2. 现在我在 help-fns.el 中定义描述功能。我只想使用这个功能定义。所以缩小的顺序是:



    Cx nd


  3. 希望有趣的命令将以其名称找到或定位,所以我使用发现来搜索有趣的行:



    Ms o find\ | locate



    没有匹配。嗯。在这个defun不是很多的线。 describe-function-1 似乎正在做真正的工作,所以我们尝试。


  4. 我可以通过 Chf 访问 describe-function-1 的定义。但是我已经打开了这个文件。 imenu 现在可用:



    Cx nw Mx imenu desc * 1 标签 输入


  5. 缩小搜索范围



    Cx nd Ms o up 输入 / p>

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


  6. 阅读 Ch f find-lisp-object-file-name 后,我想出:

     (defun locate-function(func)
    将文件名作为字符串返回func被定义或将被自动加载
    (interactiveCcommand:)
    (let((find-lisp-object-file-name func(symbol-function func))))
    (when(called-interactiveively-p'any)
    %s在%s中定义func res))
    res))




现在去探索Emacs一些乐趣。


Currently i am using the load-history variable to find the file from which a feature came from.

suppose to find the file the feature gnus came from.

I execute the following code in scratch buffer which prints filename and the symbols in separate lines consecutively.

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

and then search for "(provide . gnus)" and then move the point to the start of line(Ctrl+A). The file name in the previous line is the file from which the feature came from.

Is there any thing wrong with this method, or does a better method exist.

解决方案

I don't really know what you're trying to do with this, but here are some notes.

  • Your method is fine. Any way to hack your own solution to a problem is good in my book.

  • @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

But that's not so interesting. Let's say you really want an automatic, more elegant solution. You want a function -- locate-feature with this signature:

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

Method 1 load-history approach

I'll just describe the steps I took to solve this:

  1. You've already got the most important part -- find the variable with the information you need.

  2. I notice immediately that this variable has a lot of data. If I insert it into a buffer as a single line, Emacs will not be happy, because it's notoriously bad at handling long lines. I know that the prett-print package will be able to format this data nicely. So I open up my *scratch* buffer and run

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

  3. I can now see the data structure I'm dealing with. It seems to be (in pseudo code):

    ((file-name
      ((defun|t|provide . symbol)|symbol)*)
     ...)
    

  4. Now I just write the function

    (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))))
    

    The code here is pretty straight forward. Ask Emacs about the functions you don't understand.

Method 2 help approach

Method one works for features. But what if by I want to know where any available function is defined? Not just features.

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

Here we go.

  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. Now I'm in help-fns.el at the definition of describe-function. I want to work only with this function definition. So narrowing is in order:

    C-x n d

  3. I have a hunch that the interesting command will have "find" or "locate" in its name, so I use occur to search for interesting lines:

    M-s o find\|locate

    No matches. Hmmm. Not a lot of lines in this defun. describe-function-1 seems to be doing the real work, so we try that.

  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. Narrow and search again:

    C-x n d M-s o up enter

    I see find-lisp-object-file-name which looks promising.

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

Now go have some fun exploring Emacs.

这篇关于如何找到哪个文件提供(d)emacs elisp中的功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆