Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Emacs Lisp, how to find where the symbol is defined

Tags:

emacs

elisp

When I do C-h f or C-h v, Help tells me in which file the symbol is defined or where it will be autoloaded from. How can I find the same information programmatically?

like image 487
Jisang Yoo Avatar asked Aug 10 '13 22:08

Jisang Yoo


People also ask

What is a symbol in Emacs?

A symbol in GNU Emacs Lisp is an object with a name. The symbol name serves as the printed representation of the symbol. In ordinary Lisp use, with one single obarray (see Creating and Interning Symbols), a symbol's name is unique—no two symbols have the same name.

How do you evaluate a Lisp in emacs?

Typing C-x C-e in any buffer evaluates the Lisp form immediately before point and prints its value in the echo area. Typing M-: or M-x eval-expression allows you to type a Lisp form in the minibuffer which will be evaluated once you press RET.

What does #' mean in Emacs Lisp?

#'... is short-hand for (function ...) which is simply a variant of '... / (quote ...) that also hints to the byte-compiler that it can compile the quoted form as a function.

How do I Lisp in emacs?

In a fresh Emacs window, type ESC-x lisp-interaction-mode . That will turn your buffer into a LISP terminal; pressing Ctrl+j will feed the s-expression that your cursor (called "point" in Emacs manuals' jargon) stands right behind to LISP, and will print the result.


2 Answers

Some digging reveals that

(find-lisp-object-file-name object type)

Should do the trick. As an example:

(find-lisp-object-file-name 'goto-line 'function)
;; => "/usr/local/Cellar/emacs/24.3/share/emacs/24.3/lisp/simple.el"

EDIT: How I discovered this information:

First I did C-h k C-h f to figure out what C-h f is bound to. The result is describe-function, so let's do C-h f describe-function to see the source for that. I noticed that it was essentially an interactive wrapper around describe-function-1, so I jumped to the source for that. There's a lot of stuff in there, but the pertinent line is:

(file-name (find-lisp-object-file-name function def))

Revealing that find-lisp-object-file-name is the function used to do this work internally.

like image 165
James Porter Avatar answered Oct 31 '22 01:10

James Porter


To add to James Porter's answer

;;; run from: emacs -q

(require 'cl) ; for incf

(print (list
        ;; goto-line is a function defined in simple.el
        (find-lisp-object-file-name 'goto-line (symbol-function 'goto-line))
        ;; print is a function defined in C
        (find-lisp-object-file-name 'print (symbol-function 'print))
        ;; rx is an autoload from rx.el
        (find-lisp-object-file-name 'rx (symbol-function 'rx))
        ;; incf is an alias for cl-incf defined in cl.el
        (find-lisp-object-file-name 'incf (symbol-function 'incf))
        ;; cl-incf is defined in cl-lib.el
        (find-lisp-object-file-name 'cl-incf (symbol-function 'cl-incf))))
;; => ("c:/run/Emacs/lisp/simple.el" C-source 
;;  "c:/run/Emacs/lisp/emacs-lisp/rx.el" "c:/run/Emacs/lisp/emacs-lisp/cl.el"
;;  "c:/run/Emacs/lisp/emacs-lisp/cl-lib.el")

(print (list
        ;; print-circle is a variable defined in C
        (find-lisp-object-file-name 'print-circle 'defvar)
        ;; indent-line-function is a variable defined in indent.el
        (find-lisp-object-file-name 'indent-line-function 'defvar)))
;; => (C-source "c:/run/Emacs/lisp/indent.el")
like image 39
Jisang Yoo Avatar answered Oct 31 '22 00:10

Jisang Yoo