Cómo obtener una lista de todas las funciones proporcionadas exclusivamente por cierto modo principal

8

Esta pregunta está inspirada en https://stackoverflow.com/q/605785/ . Por M-x describe-function <TAB>puedo obtener una lista de todas las funciones interactivas o no atractivas disponibles en el estado actual de emacs. Si se activa un modo específico (por ejemplo, modo látex) obtenemos una lista más larga, ya que también se enumeran las funciones disponibles en el modo látex.

Mi pregunta es cómo obtener una lista de todas las funciones disponibles exclusivamente en un modo específico (por ejemplo, modo látex). En otras palabras, excluyendo todas las demás funciones no proporcionadas por ese modo. Al igual que en el enlace anterior, también sería útil proporcionar una breve descripción de las funciones.

Nombre
fuente
1
smex intenta esto y proporciona una lista de comandos para el modo principal actual cuando se usa smex-major-mode-commands.
wasamasa
@wasamasa gracias por presentar smex. Para los comandos (funciones interactivas) esto parece hacer el trabajo. Sigue siendo las funciones no interactivas.
Nombre
1
Vaya, olvidé mi punto real. Estudie sus fuentes para tener algo que comparar con el código de las otras respuestas.
wasamasa

Respuestas:

2

¿Qué significa que un modo proporcione una función? Usted dice " una lista de todas las funciones disponibles exclusivamente en un modo específico " y " excluyendo todas las demás funciones no proporcionadas por ese modo ".

Parece que estás confundiendo un modo con la biblioteca que lo define . Una biblioteca proporciona / define funciones. Un modo generalmente no lo hace.

Si desea obtener una lista de todas las funciones definidas en una biblioteca determinada , consulte la respuesta de @ wvxvw, para comenzar. También puede intentar hacer coincidir el prefijo de la biblioteca con los nombres de las funciones, que a menudo es pertinente, pero de ninguna manera es definitivo.

Sin embargo, si desea obtener una lista de todas las funciones que podrían ser relevantes para un modo dado , por ejemplo, funciones que solo se pueden usar, o que son más útiles, cuando ese modo está activado, entonces me temo Deberá examinar la biblioteca donde se define el modo. E incluso podría necesitar examinar algunas otras bibliotecas.

Una biblioteca dada generalmente define más que solo algunas cosas que son pertinentes a un modo dado. Y un modo dado puede hacer uso de cosas que están definidas en diferentes bibliotecas, y en algunos casos cosas que tienen sentido solo para ese modo dado o un conjunto de modos que lo incluye.

En resumen, como se plantea actualmente, su pregunta no es muy clara. Puede ayudarse a sí mismo a obtener mejores respuestas al aclararlo.

Dibujó
fuente
Tienes razón, la pregunta debería ser más precisa. Por ejemplo, para látex, me refiero a todas las funciones definidas en los .elarchivos contenidos en la carpeta site-lisp>auctex. Para el modo org, me refiero a todas las funciones definidas en los .elarchivos contenidos en la carpeta site-lisp>org. Para muchos modos, la situación es más sencilla, ya que para ellos solo hay un .elarchivo. Espero que estas explicaciones aclaren ahora el motivo de mi pregunta.
Nombre
2

Quizás, este código tendrá algún efecto educativo:

(defun remove-all-extensions (file-name)
  (let ((go-on t) next)
    (while go-on
      (setq next (file-name-sans-extension file-name))
      (setq go-on (not (string= next file-name))
            file-name next))
    next))

(defun function-symbols-of (library)
  (let ((origin (remove-all-extensions
                 (find-library-name
                  (if (stringp library) library
                    (symbol-name library)))))
        (result))
    (mapatoms (lambda (sym)
                (when (and (symbol-function sym)
                           (symbol-file sym)
                           (string= (remove-all-extensions (symbol-file sym))
                                    origin))
                  (push sym result))))
    result))

El problema

Debido a la naturaleza no determinista del análisis y la carga del código, se deben abordar varios problemas:

  1. ¿Cuándo se define la función en un archivo? Las funciones se pueden definir condicionalmente, y predecir si una condición favorecerá la definición de la función o no es equivalente a resolver el problema de detención. Para ilustrar esto, suponga que este código:

    (if (> (random 100) 50)
       (defun foo ())
       (defun bar ()))
    
  2. En general, no es posible saber si un formulario lisp definió una función antes (con éxito) de evaluar el formulario. Esto es, de nuevo, equivalente al problema de detención, por lo tanto, no se puede resolver en general.
  3. Hay algunos casos especiales comunes, como el alias y el asesoramiento, que (a) crean duplicados, (b) pueden confundirlo con el archivo fuente que declaró la función.
  4. Se declara una gran fracción de funciones en el código C (no necesariamente accesible), que en realidad no se divide en bibliotecas en el mismo sentido que el código Emacs Lisp.

Dicho todo esto, probablemente desee buscar find-func.elinspiración, para tener una idea general del diseño y los problemas relacionados con la ubicación del código fuente para las funciones de Emacs Lisp.

wvxvw
fuente
Permítanme informar esto: cuando ejecuto este código me sale el error Symbol's function definition is void: find-library-name. El también es un pequeño error tipográfico -> símbolos.
Nombre
@Name hm ... pero esta función es muy antigua (me parece mencionada en el código fuente en 2002). ¿Podría intentarlo (require 'find-func)antes de ejecutar este código? Gracias por el error tipográfico encontrado. Lo corregiré.
wvxvw
Gracias, sería genial si el nombre de la biblioteca se puede dar con expresiones regulares.
Nombre
1

Acabo de agregar esta funcionalidad a lispy . El nuevo comando lispy-goto-elisp-commands, está obligado a oge.

El genérico g( lispy-goto) proporciona una lista de todas las etiquetas, resaltando los comandos con una cara diferente, mientras que lispy-goto-elisp-commandssolo proporciona las etiquetas de comando.

Listado de código

(defun lispy-goto-elisp-commands (&optional arg)
  "Jump to Elisp commands within current file.
When ARG is non-nil, force a reparse."
  (interactive "P")
  (deactivate-mark)
  (let ((lispy-force-reparse arg))
    (lispy--fetch-tags (list (buffer-file-name)))
    (let ((struct (gethash (buffer-file-name) lispy-db)))
      (lispy--select-candidate
       (mapcar #'lispy--format-tag-line
               (delq nil
                     (cl-mapcar
                      (lambda (tag pretty-tag)
                        (when (semantic-tag-get-attribute tag :user-visible-flag)
                          pretty-tag))
                      (lispy-dbfile-plain-tags struct)
                      (lispy-dbfile-tags struct))))
       #'lispy--action-jump))))

Esto es solo para mostrar que la semántica de CEDET se utiliza para obtener la lista de etiquetas; (semantic-tag-get-attribute tag :user-visible-flag)se usa para determinar si la etiqueta es un comando o no.

Cómo utilizar

  1. Navegue hasta el archivo que contiene el código. Esto se puede hacer con f1 f. Me gusta usar el consejo-describir-función en su lugar, ya que presionar C-.allí omite tener que pasar por el *Help*búfer.

  2. Haga que el punto sea especial (muévalo antes de abrir el par, o active la región) y presione oge. También es posible simplemente usar M-x lispy-goto-elisp-commands.

abo-abo
fuente
Estoy un poco confundido, si me gusta obtener todas las funciones proporcionadas por el modo látex, ¿qué debo hacer con su código?
Nombre
Abra tex-mode.el. Presione "oge" para obtener una lista de 23 etiquetas de comando que contiene este archivo. Al seleccionar una de las etiquetas, se navegará allí.
abo-abo
Ejecutar M-x lispy-goto-elisp-commandsen el búfer tex-mode.elda el errorlispy--fetch-tags: Wrong type argument: stringp, ("c:/Program Files/GNU Emacs/share/emacs/24.5/lisp/textmodes/tex-mode.el")
Nombre
No tengo experiencia ejecutando CEDET en Windows. Sin embargo, el comando debería funcionar bien en GNU / Linux para 24.5.2 y 25.
abo-abo
Su respuesta habla de " comandos ", pero la pregunta de OP es sobre funciones , no solo comandos . Si realmente te refieres a las funciones, entonces es posible que quieras corregir el texto. Si te refieres solo a comandos, esta publicación aún no responde realmente la pregunta, en cuyo caso es posible que desees corregirlo (por ejemplo, cambiar el código o lo que sea).
Dibujó
1

El paquete smex tiene un código para enumerar todos los comandos de un paquete. Puede adaptar este código para obtener todas las funciones.

rumember
fuente
Oh sí, lo siento, me perdí eso.
rumember