简体   繁体   English

在emacs中的Lisp位置

[英]Lisp location in emacs

Where can I find the all Emacs' elisp scripts? 我在哪里可以找到所有Emacs的elisp脚本? I don't mean scripts users developed or installed themselves, but the common elisp script already there. 我并不是说脚本用户自己开发或安装,而是已经存在常见的elisp脚本。

For example, 例如,

if I have a function like describe-char or insert-file , how can I find the file contained these functions? 如果我有像describe-charinsert-file这样的函数,我怎样才能找到包含这些函数的文件?

Ctrl-h f will tell a function's explanation and where it is contained. Ctrl-h f将告诉函数的解释以及它的包含位置。

And if you want a function to do this automaticlly, here's a draft: 如果你想要一个函数自动执行此操作,这里是一个草稿:

(defun my-find-lisp-object-file-name (function)
  "Display the lisp file name of FUNCTION (a symbol)."
  (interactive
   (let ((fn (function-called-at-point))
     (enable-recursive-minibuffers t)
     val)
     (setq val (completing-read (if fn
                    (format "Describe function (default %s): " fn)
                  "Describe function: ")
                obarray 'fboundp t nil nil
                (and fn (symbol-name fn))))
     (list (if (equal val "")
           fn (intern val)))))
  (if (null function)
      (message "You didn't specify a function")
    (setq object-file-name (find-lisp-object-file-name function (symbol-function function)))
    (if (eq object-file-name 'C-source)
        (message "%s is in %s" function "C source code")
      (setq buff (find-function-search-for-symbol function nil object-file-name))
      (setq buf-name (buffer-name(car buff)))
      (setq buf-pos (cdr buff))
      (switch-to-buffer (car buff))
      (message "%s is in %s(%s, %d)" function object-file-name buf-name buf-pos))))

I guess Mx locate-library RET <libname> RET could be an answer tho it needs the library name rather than the function name. 我猜Mx locate-library RET <libname> RET可能是一个答案,它需要库名而不是函数名。 Else, Mx find-function-other-window will not just tell you where the file is, but instead will open the file, after which you can use Mx pwd to know where you are. 另外, Mx find-function-other-window会告诉你文件的位置,而是会打开文件,之后你可以使用Mx pwd知道你的位置。

One more thing: you can do Ch v load-path RET to see the directories that Emacs uses to find its libraries, so that should give you a good idea of where all the bundled Elisp files reside. 还有一件事:你可以使用Ch v load-path RET来查看Emacs用来查找其库的目录,这样可以让你很好地了解所有捆绑的Elisp文件所在的位置。

INITIAL DRAFT (March 25, 2014): First rough draft. 初始草案 (2014年3月25日):第一份草稿。

EDIT (March 26, 2014): Added a global-set-key . 编辑 (2014年3月26日):添加了global-set-key Added one more car to the final message in order to fully extract the path of the file name from the list of button text properties. 为最终消息添加了一个car ,以便从按钮文本属性列表中完全提取文件名的路径。 Added some colorization to the initial and final messages. 为初始和最终消息添加了一些着色。 Added return cursor to beginning of buffer at the end of the function. 在函数末尾添加了返回光标到缓冲区的开头。 Added options for find-variable-other-window and find-function-other-window . 添加了find-variable-other-windowfind-function-other-window Added conditions so that no messages are generated if there is no file name. 添加了条件,以便在没有文件名时不生成任何消息。


Here is a fun little function that I whipped up -- it displays a message with a file path if an *.el file is displayed in the *Help* buffer. 这是一个有趣的小功能,我掀起了它 - 如果在*Help*缓冲区中显示*.el文件,它会显示带有文件路径的消息。


(global-set-key (kbd "C-h z") 'lawlist-describe-find-function-variable)

(defun lawlist-describe-find-function-variable ()
"Describe or find a function / variable.  Displays the path of filename."
(interactive)
  (message (concat
    (propertize "Describe" 'face 'font-lock-keyword-face)
    " ["
    (propertize "f" 'face 'font-lock-warning-face)
    "]unction / ["
    (propertize "v" 'face 'font-lock-warning-face)
    "]ariable | "
    (propertize "Find" 'face 'font-lock-keyword-face)
    " ["
    (propertize "F" 'face 'font-lock-warning-face)
    "]unction / ["
    (propertize "V" 'face 'font-lock-warning-face)
    "]ariable"))
  (let* (
      (select-f-or-v (read-char-exclusive))
      function
      variable)
    (cond
      ((eq select-f-or-v ?f)
        (setq function (read (read-string "Please enter a function name:  ")))
        (describe-function function)
        (select-window (get-buffer-window "*Help*")))
      ((eq select-f-or-v ?v)
        (setq variable (read (read-string "Please enter a variable name:  ")))
        (describe-variable variable)
        (select-window (get-buffer-window "*Help*")))
      ((eq select-f-or-v ?F)
        (setq function (read (read-string "Please enter a function name:  ")))
        (find-function-other-window function)
        (when buffer-file-name
          (message (propertize buffer-file-name 'face 'font-lock-warning-face))))
      ((eq select-f-or-v ?V)
        (setq variable (read (read-string "Please enter a variable name:  ")))
        (find-variable-other-window variable)
        (when buffer-file-name
          (message (propertize buffer-file-name 'face 'font-lock-warning-face))))
      (t
        (message "Thanks and come again!")))
    (when (and
        (equal (buffer-name) "*Help*")
        (save-excursion
          (goto-char (point-max))
          (re-search-backward "\\(`*[.]el'\\)" nil t)))
      (goto-char (point-max))
      (re-search-backward "\\(`*[.]el'\\)" nil t)
      (message 
        (propertize
          (car (cdr (car (nthcdr 1 (text-properties-at (point))))))
            'face 'font-lock-warning-face) )
      (goto-char (point-min))) ))

If you use lispy minor mode: 如果您使用lispy minor模式:

  1. You can open the definition of current function by positioning the point on the open paren of that function and pressing F . 您可以通过将该点放在该功能的打开位置并按下F来打开当前功能的定义。
  2. You can open the definition of current variable by marking it and pressing F . 您可以通过标记并按F来打开当前变量的定义。
  3. You can find all definitions in current directory with g . 您可以使用g查找当前目录中的所有定义。 You get a helm completion interface for all tags in all Elisp files. 您将获得所有Elisp文件中所有标记的helm完成界面。 Each line will have the tag in the first column and the file in the second. 每行将在第一列中包含标记,在第二列中包含文件。 My installation's base Elisp directory has 19838 tags, and the completion is fast enough. 我的安装基础Elisp目录有19838个标签,完成速度足够快。

  4. You can find all definitions in current directory and its sub-directories with lispy-goto-recursive . 您可以使用lispy-goto-recursive在当前目录及其子目录中找到所有定义。 It takes minutes to parse and seconds to bring up the completion interface. 解析完成界面需要几分钟才能解析。 But it allows to interactively search through all the files in the Emacs source - that's 89675 tags. 但它允许以交互方式搜索Emacs源中的所有文件 - 即89675个标签。 A sample search: there are 55 top-level tags that contain insert-file spread around about 20 files. 示例搜索:有55个顶级标记包含大约20个文件的insert-file文件。 Most of them are functions, but the top-level tag (define-key ctl-x-map "i" 'insert-file) is also matched and can be viewed without opening the file. 它们中的大多数都是函数,但顶级标记(define-key ctl-x-map "i" 'insert-file)也是匹配的,无需打开文件即可查看。

You can grab the source of Emacs (if you installed Emacs you probably have .elc files - which are compiled elisp files), and search for the function, if you're on Unix like system you can use ack or find/grep all lisp files are in lisp directory 您可以获取Emacs的源代码 (如果您安装了Emacs,您可能有.elc文件 - 这是编译的elisp文件),并搜索该函数,如果您使用的是Unix系统,则可以使用ackfind/grep all lisp文件位于lisp目录中

cd Emacs-24.4/lisp
ack 'defun some-function'
find . -name '*.el' | xargs grep 'defun some-function'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM