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?
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.
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.
#'... 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.
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.
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.
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")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With