Como recuperar documentos de funções e variáveis?

11

Estou tentando escrever uma função que irá recuperar os docstrings de qualquer sexps em um arquivo que corresponda (def.*).

Eu gostaria de poder recuperar quaisquer funções / macros, bem como quaisquer variáveis ​​definidas. Para variáveis, eu desejaria a sequência de caracteres, enquanto para todas as funções, também desejaria as listas de argumentos.

Jonathan Leech-Pepin
fonte
11
Para esclarecer: você tem um arquivo de origem Elisp (minha interpretação) ou possui várias variáveis ​​e funções no ambiente atual do Emacs (interpretação de Constantine)? E se a primeira interpretação, você realmente quer todos os (def…)sexps, não apenas especificações de nível superior? Ou a interpretação intermediária das funções e variáveis ​​que seriam definidas se o arquivo for carregado? Ou uma definição mais relaxada que inclua formulários de nível superior como (when nil (defun …)))?
Gilles 'SO- stop be evil'
Inicialmente, eu queria o primeiro, mas com base na interpretação de Constantine, consegui uma implementação funcional que me deu o que precisava. O objetivo é converter a fonte elisp em documentação (escrita em Org) com base em Docstrings.
Jonathan Sanguessuga-Pepin
Com a segunda interpretação, os integrados describe-functione os amigos fazem uma boa parte do que você deseja (lista de doutrinas e argumentos).
17114 T. Verron

Respostas:

10

Se o objetivo é obter informações sobre funções e variáveis já existentes no ambiente :

  • Para documentos de funções e macros, consulte a documentationfunção

  • Para documentos variáveis, use documentation-property; por exemplo:

    (documentation-property
     'user-init-file 'variable-documentation)
    
  • Para arity da função e a lista de argumentos, consulte esta pergunta do Emacs.SE , a resposta e comentários à pergunta.

(Encontrei isso pressionando C-h k C-h fe percorrendo o código fonte de describe-function(o mesmo para documentos de variáveis, mas estudando describe-variable).)

Para analisar um arquivo de código-fonte do Emacs Lisp, assumindo que o objetivo é obter informações sobre os def.*formulários de nível superior , é possível fazer algo semelhante ao seguinte.

(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)))))

Isto pode ser facilmente estendido para defvar, defconst, etc.

Para lidar com a defunaparência dentro de formulários de nível superior, seria necessário descer para esses formulários, possivelmente usando recursão.

Constantine
fonte
2
+1 por dizer aos leitores como encontrar essas informações. Essa é a lição mais importante das duas que você ensinou.
Tirou
@Drew Parece que estamos em uma situação estranha: o objetivo deste site é tornar-se obsoleto ... Isso tornaria uma discussão interessante no chat :)
Sean Allred
4
@SeanAllred Ensinar as pessoas a aprender não interrompe as perguntas, apenas as melhora.
Malabarba
3
+1 a Malabarba. O objetivo deste site deve (IMHO) ser responder ao que o Emacs em si não pode responder ou não responde bem ou facilmente . Analogia: para o idioma e uso em inglês do site, um motivo para encerrar as perguntas é que "As perguntas que podem ser respondidas usando referências comumente disponíveis estão fora do tópico *". (StackOverflow é semelhante.) Não precisamos ser tão extremos, dizendo que as perguntas que o Emacs pode responder são fora de tópico , mas a mesma idéia deve ser aplicada: faça com que os usuários tentem encontrar a resposta primeiro . No nosso caso, isso significa perguntar ao Emacs .
Drew
@Drew Fair points :) #
Sean Allred