Как получить строки документации из функций и переменных?

11

Я пытаюсь написать функцию, которая будет извлекать строки документов из любого пола в файле, который соответствует (def.*).

Я хотел бы иметь возможность извлекать любые функции / макросы, а также любые переменные, которые определены. Для переменных мне нужна строка документации, а для любых функций - списки аргументов.

Джонатан Лич-Пепин
источник
1
Чтобы уточнить: у вас есть исходный файл Elisp (моя интерпретация), или у вас есть набор переменных и функций в текущей среде Emacs (интерпретация Константина)? И если первое толкование, вы действительно хотите все (def…)полы, а не только спецификации высшего уровня? Или промежуточная интерпретация функций и переменных, которые будут определены, если файл загружен? Или более смягченное определение, которое включает такие формы высшего уровня как (when nil (defun …)))?
Жиль "ТАК - перестань быть злым"
Сначала я хотел получить первое, однако, основываясь на интерпретации Константина, я смог получить функциональную реализацию, которая дала мне то, что мне было нужно. Цель состоит в том, чтобы преобразовать исходный код elisp в документацию (написанную на Org) на основе строк документации.
Джонатан Лич-Пепин
Со вторым толкованием встроенные describe-functionи друзья делают довольно большую часть того, что вы хотите (строка документации и список аргументов).
Т. Веррон

Ответы:

10

Если целью является получение информации о функциях и переменных уже в среде :

  • Строки документации по функциям и макросам см. В documentationфункции.

  • Для переменных строк документации используйте documentation-property; например:

    (documentation-property
     'user-init-file 'variable-documentation)
    
  • О функции функции и списке аргументов см. Этот вопрос Emacs.SE , ответ и комментарии к вопросу.

(Я нашел это, нажав C-h k C-h fи просматривая исходный код describe-function(то же самое для переменных строк документации, но изучая describe-variable).)

Чтобы проанализировать файл исходного кода Emacs Lisp, предполагая, что целью является получение информации о def.*формах верхнего уровня , можно сделать что-то похожее на следующее.

(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
    (save-excursion
      (save-restriction
        (widen)
        (goto-char (point-min))
        (let (result)
          ;; keep going while reading succeeds
          (while (condition-case nil
                     (progn
                       (read (current-buffer))
                       (forward-sexp -1)
                       t)
                   (error nil))
            (let ((form (read (current-buffer))))
              (cond
               ((not (listp form))      ; if it's not a list, skip it
                nil)
               ((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))))))
          result)))))

Это может быть легко расширена до defvar, defconstи т.д.

Чтобы обработать defunпоявление в формах верхнего уровня, нужно спуститься в эти формы, возможно, используя рекурсию.

Константин
источник
2
+1 для того, чтобы рассказать читателям, как найти эту информацию самостоятельно. Это самый важный урок из двух, которые вы преподали.
Дрю
@Drew Похоже, мы находимся в странной ситуации: цель этого сайта состоит в том, чтобы сделать себя устаревшим ... Это сделало бы интересную дискуссию в чате :)
Шон Оллред
4
@SeanAllred Обучение людей не останавливает вопросы, оно только делает их лучше.
Малабарба
3
+1 к Малабарбе. Цель этого сайта (ИМХО) - ответить на то, что сам Emacs не может ответить или не отвечает хорошо или легко . Аналогия: Для сайта « Английский язык и использование» причина закрытия вопроса заключается в том, что « Вопросы, на которые можно ответить, используя общедоступные ссылки , не по теме *». (StackOverflow аналогичен.) Мы не должны быть такими крайними, говоря, что вопросы, на которые может ответить сам Emacs, являются не относящимися к теме , но должна применяться та же идея: сначала попросите пользователей попытаться найти ответ . В нашем случае это означает, спрашивая Emacs .
Дрю
@Drew Fair points :)
Шон Оллред