Come recuperare docstring da funzioni e variabili?


11

Sto provando a scrivere una funzione che recupererà i docstring da qualsiasi sexp in un file corrispondente (def.*).

Vorrei sia essere in grado di recuperare qualsiasi funzione / macro, sia qualsiasi variabile definita. Per le variabili vorrei il docstring, mentre per qualsiasi funzione vorrei anche gli elenchi di argomenti.


1
Per chiarire: hai un file sorgente Elisp (la mia interpretazione) o hai un sacco di variabili e funzioni nell'attuale ambiente Emacs (interpretazione di Costantino)? E se la prima interpretazione, vuoi davvero tutti i (def…)sexp, non solo le specifiche di alto livello? O l'interpretazione intermedia delle funzioni e delle variabili che verrebbero definite se il file fosse caricato? O una definizione più rilassata che include forme di alto livello come (when nil (defun …)))?
Gilles 'stop SO-essere malvagio'

Inizialmente avevo voluto il primo, tuttavia, basandomi sull'interpretazione di Costantino, ero in grado di ottenere un'implementazione funzionale che mi procurasse ciò di cui avevo bisogno. L'obiettivo è convertire la fonte elisp in documentazione (scritta in Org) basata su Docstrings.
Jonathan Leech-Pepin,

Con la seconda interpretazione, il built-in describe-functione gli amici fanno abbastanza buona parte di ciò che desideri (elenco di argomenti e argomenti).
T. Verron,

Risposte:


10

Se l'obiettivo è ottenere informazioni su funzioni e variabili già presenti nell'ambiente :

  • Per le istruzioni di funzioni e macro, vedere la documentationfunzione.

  • Per docstring variabili, utilizzare documentation-property; per esempio:

    (documentation-property
     'user-init-file 'variable-documentation)
    
  • Per la funzione arity e l'elenco degli argomenti, vedere questa domanda Emacs.SE , la risposta e i commenti alla domanda.

(L'ho trovato premendo C-h k C-h fe scremando il codice sorgente di describe-function(lo stesso per le variabili variabili, ma studiando describe-variable).)

Per analizzare un file di codice sorgente di Emacs Lisp, supponendo che l'obiettivo sia ottenere informazioni sui def.*moduli di livello superiore , si può fare qualcosa di simile al seguente.

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

Questo può essere facilmente esteso per defvar, defconstecc

Per gestire l' defunapparizione all'interno di moduli di livello superiore si dovrebbe scendere in queste forme, possibilmente usando la ricorsione.


2
+1 per dire ai lettori come trovare queste informazioni da soli. Questa è la lezione più importante delle due che hai insegnato.
Disegnato il

@Drew Sembra che ci troviamo in una strana situazione: l'obiettivo di questo sito è di diventare obsoleto ... Ciò renderebbe una discussione interessante in chat :)
Sean Allred,

4
@SeanAllred Insegnare alle persone ad imparare non ferma le domande, le rende solo migliori.
Malabarba,

3
+1 a Malabarba. Lo scopo di questo sito (IMHO) dovrebbe essere quello di rispondere a ciò che Emacs stesso non può rispondere o che non risponde bene o facilmente . Analogia: per la lingua e l'utilizzo del sito inglese, un motivo per chiudere le domande è che "Le domande a cui è possibile rispondere utilizzando riferimenti comunemente disponibili sono fuori tema *". (StackOverflow è simile.) Non abbiamo bisogno di essere così estremi, dicendo che le domande a cui Emacs stesso può rispondere sono fuori tema , ma la stessa idea dovrebbe applicarsi: convincere gli utenti a cercare prima di trovare la risposta . Nel nostro caso, ciò significa chiedere a Emacs .
Disegnato il

@Drew Fair points :)
Sean Allred,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.