¿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.


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.


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.