¿Cómo recuperar cadenas de documentos de funciones y variables?

11

Estoy tratando de escribir una función que recupere las cadenas de documentos de cualquier sexps en un archivo que coincida (def.*).

Me gustaría poder recuperar las funciones / macros, así como las variables definidas. Para las variables me gustaría la cadena de documentación, mientras que para cualquier función también me gustaría las listas de argumentos.

Jonathan Leech-Pepin
fuente
1
Para aclarar: ¿tiene un archivo fuente de Elisp (mi interpretación), o tiene un montón de variables y funciones en el entorno actual de Emacs (interpretación de Constantine)? Y si es la primera interpretación, ¿realmente quieres todos los (def…)sexps, no solo las especificaciones de nivel superior? ¿O la interpretación intermedia de las funciones y variables que se definirían si se carga el archivo? ¿O una definición más relajada que incluya formas de nivel superior como (when nil (defun …)))?
Gilles 'SO- deja de ser malvado'
Inicialmente quería el primero, sin embargo, gracias a la interpretación de Constantine, pude obtener una implementación funcional que me dio lo que necesitaba. El objetivo es convertir la fuente de elisp en documentación (escrita en Org) basada en Docstrings.
Jonathan Leech-Pepin
Con la segunda interpretación, el incorporado describe-functiony los amigos hacen una buena parte de lo que quieres (docstring y lista de argumentos).
T. Verron

Respuestas:

10

Si el objetivo es obtener información sobre funciones y variables que ya están en el entorno :

  • Para las cadenas de documentos de funciones y macros, vea la documentationfunción.

  • Para cadenas de documentos variables, use documentation-property; por ejemplo:

    (documentation-property
     'user-init-file 'variable-documentation)
    
  • Para la función arity y la lista de argumentos, vea esta pregunta de Emacs.SE , la respuesta y los comentarios a la pregunta.

(Encontré esto presionando C-h k C-h fy deslizando el código fuente de describe-function(lo mismo para cadenas de documentos variables, pero estudiando describe-variable)).

Para analizar un archivo de código fuente de Emacs Lisp, suponiendo que el objetivo es obtener información sobre def.*formularios de nivel superior , se puede hacer algo similar a lo siguiente.

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

Esto se puede extender fácilmente a defvar, defconst, etc.

Para manejar la defunaparición dentro de los formularios de nivel superior, uno tendría que descender a estos formularios, posiblemente utilizando la recursividad.

Constantina
fuente
2
+1 por decirle a los lectores cómo encontrar esta información ellos mismos. Esa es la lección más importante de las dos que enseñaste.
Dibujó el
@Drew Parece que estamos en una situación extraña: el objetivo de este sitio es volverse obsoleto ... Esto sería una discusión interesante en el chat :)
Sean Allred
44
@SeanAllred Enseñar a las personas a aprender no detiene las preguntas, solo las mejora.
Malabarba
3
+1 a Malabarba. El propósito de este sitio debería (en mi humilde opinión) ser responder a lo que Emacs no puede responder o no responde bien o fácilmente . Analogía: para el sitio English Language & Usage, una razón para cerrar las preguntas es que "Las preguntas que pueden responderse utilizando referencias comúnmente disponibles están fuera de tema *". (StackOverflow es similar.) No necesitamos ser tan extremos, diciendo que las preguntas que Emacs puede responder están fuera de tema , pero la misma idea debería aplicarse: hacer que los usuarios intenten encontrar la respuesta primero . En nuestro caso, eso significa preguntarle a Emacs .
Dibujó el
@Drew Fair points :)
Sean Allred