I'm trying to write a function that will retrieve the docstrings from any sexps in a file that match (def.*).

I'd want to both be able to retrieve any functions/macros, as well as any variables that are defined. For variables I would want the docstring, while for any functions I would also want the argument lists.

  • 1
    To clarify: do you have an Elisp source file (my interpretation), or do you have a bunch of variables and functions in the current Emacs environment (Constantine's interpretation)? And if the first interpretation, do you really want all (def…) sexps, not just top-level specs? Or the intermediate interpretation of the functions and variables that would be defined if the file is loaded? Or a more relaxed definition that includes such top-level forms as (when nil (defun …)))? Commented Nov 17, 2014 at 6:22
  • I had initially wanted the first, however based on Constantine's interpretation I was able to get a functional implementation that got me what I needed. Goal is to convert elisp source into documentation (written in Org) based on Docstrings. Commented Nov 17, 2014 at 14:51
  • With the second interpretation, the built-in describe-function and friends do quite a good part of what you want (docstring and arguments list).
    – T. Verron
    Commented Nov 17, 2014 at 15:05

1 Answer 1


If the goal is to get information about functions and variables already in the environment:

  • For docstrings of functions and macros, see the documentation function.

  • For variable docstrings, use documentation-property; for example:

     'user-init-file 'variable-documentation)
  • For function arity and the argument list, see this Emacs.SE question, the answer, and comments to the question.

(I found this by pressing C-h k C-h f and skimming the source code of describe-function (same for variable docstrings, but studying describe-variable).)

To analyze an Emacs Lisp source code file, assuming that the goal is to get information about top-level def.* forms, one can do something similar to the following.

(defun get-defun-info (buffer)
  "Get information about all `defun' top-level sexps in a buffer
BUFFER. Returns a list with elements of the form (symbol args docstring)."
  (with-current-buffer buffer
        (goto-char (point-min))
        (let (result)
          ;; keep going while reading succeeds
          (while (condition-case nil
                       (read (current-buffer))
                       (forward-sexp -1)
                   (error nil))
            (let ((form (read (current-buffer))))
               ((not (listp form))      ; if it's not a list, skip it
               ((eq (nth 0 form) 'defun) ; if it's a defun, collect info
                (let ((sym (nth 1 form))
                      (args (nth 2 form))
                      (doc (when (stringp (nth 3 form)) (nth 3 form))))
                  (push (list sym args doc) result))))))

This can be easily extended to defvar, defconst, etc.

To handle defun appearing inside top-level forms one would have to descend into these forms, possibly using recursion.

  • 2
    +1 for telling readers how to find this info themselves. That's the more important lesson of the two that you taught.
    – Drew
    Commented Nov 17, 2014 at 2:23
  • @Drew It appears we are in a strange situation: the goal of this site is to make itself obsolete… This would make an interesting discussion in chat :) Commented Nov 17, 2014 at 4:57
  • 4
    @SeanAllred Teaching people to learn doesn't stop the questions, it only makes them better.
    – Malabarba
    Commented Nov 17, 2014 at 9:20
  • 3
    +1 to Malabarba. The purpose of this site should (IMHO) be to answer what Emacs itself cannot answer or does not answer well or easily. Analogy: For site English Language & Usage a reason for closing questions is that "Questions that can be answered using commonly available references are off-topic*". (StackOverflow is similar.) We need not be as extreme, saying that questions that Emacs itself can answer are off-topic, but the same idea should apply: get users to try to find the answer first. In our case, that means by asking Emacs.
    – Drew
    Commented Nov 17, 2014 at 17:49
  • @Drew Fair points :) Commented Nov 17, 2014 at 18:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.