So erhalten Sie eine Liste aller Funktionen, die ausschließlich von einem bestimmten Hauptmodus bereitgestellt werden

8

Diese Frage wurde von https://stackoverflow.com/q/605785/ inspiriert . Durch M-x describe-function <TAB>kann ich eine Liste aller interaktiven oder nicht intuitiven Funktionen erhalten, die im aktuellen Status von Emacs verfügbar sind. Wenn ein bestimmter Modus aktiviert ist (z. B. Latex-Modus), erhalten wir eine längere Liste, da auch die im Latex-Modus verfügbaren Funktionen aufgelistet sind.

Meine Frage ist, wie man eine Liste aller Funktionen erhält, die ausschließlich in einem bestimmten Modus (z. B. Latex-Modus) verfügbar sind. Mit anderen Worten, ohne alle anderen Funktionen, die von diesem Modus nicht bereitgestellt werden. Wie im obigen Link wäre auch eine kurze Beschreibung der Funktionen nützlich.

Name
quelle
1
smex versucht dies und stellt bei Verwendung eine Liste von Befehlen für den aktuellen Hauptmodus bereit smex-major-mode-commands.
Wasamasa
@wasamasa danke für die Einführung von smex. Für die Befehle (interaktive Funktionen) scheint dies die Aufgabe zu erfüllen. Es bleiben die nicht interaktiven Funktionen.
Name
1
Hoppla, ich habe meinen eigentlichen Punkt vergessen. Studieren Sie die Quellen, um etwas mit dem Code aus den anderen Antworten zu vergleichen.
Wasamasa

Antworten:

2

Was bedeutet es für einen Modus, eine Funktion bereitzustellen? Sie sagen " eine Liste aller Funktionen, die ausschließlich in einem bestimmten Modus verfügbar sind " und " alle anderen Funktionen ausschließen, die von diesem Modus nicht bereitgestellt werden ".

Es hört sich so an, als würden Sie einen Modus mit der Bibliothek verwechseln, die ihn definiert . Eine Bibliothek bietet / definiert Funktionen. Ein Modus tut dies im Allgemeinen nicht.

Wenn Sie eine Liste aller in einer bestimmten Bibliothek definierten Funktionen erhalten möchten, lesen Sie zunächst die Antwort von @ wvxvw. Sie können auch versuchen, das Bibliothekspräfix mit Funktionsnamen abzugleichen - das ist häufig relevant, aber keineswegs endgültig.

Wenn Sie jedoch eine Liste aller Funktionen erhalten möchten, die für einen bestimmten Modus relevant sein könnten , z. B. Funktionen, die nur verwendet werden können oder am nützlichsten sind, wenn dieser Modus aktiviert ist, dann fürchte ich Sie müssen die Bibliothek untersuchen, in der der Modus definiert ist. Möglicherweise müssen Sie sogar einige andere Bibliotheken untersuchen.

Eine bestimmte Bibliothek definiert normalerweise mehr als nur einige Dinge, die für einen bestimmten Modus relevant sind. Und ein bestimmter Modus kann sehr gut Dinge verwenden, die in verschiedenen Bibliotheken definiert sind, und in einigen Fällen Dinge, die nur für diesen bestimmten Modus oder eine Reihe von Modi, die ihn enthalten, sinnvoll sind.

Insgesamt ist Ihre Frage, wie derzeit gestellt, nicht sehr klar. Sie können sich selbst helfen, bessere Antworten zu erhalten, indem Sie dies klären.

Drew
quelle
Sie haben Recht, die Frage sollte präziser sein. Zum Beispiel für Latex meine ich alle Funktionen, die in den .elim Ordner enthaltenen Dateien definiert sind site-lisp>auctex. Für den Organisationsmodus meine ich alle Funktionen, die in den .elim Ordner enthaltenen Dateien definiert sind site-lisp>org. Für viele Modi ist die Situation einfacher, da für sie nur eine .elDatei vorhanden ist. Ich hoffe, diese Erklärungen machen das Motiv meiner Frage jetzt klar.
Name
2

Vielleicht hat dieser Code eine pädagogische Wirkung:

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

Das Problem

Aufgrund des nicht deterministischen Charakters des Code-Parsing und -Ladens müssen verschiedene Probleme behoben werden:

  1. Wann ist die Funktion in einer Datei definiert? Funktionen können bedingt definiert werden, und die Vorhersage, ob eine Bedingung die Funktionsdefinition begünstigt oder nicht, entspricht der Lösung des Halteproblems. Nehmen wir zur Veranschaulichung diesen Code an:

    (if (> (random 100) 50)
       (defun foo ())
       (defun bar ()))
    
  2. Es ist im Allgemeinen nicht möglich zu sagen, ob ein Lisp-Formular eine Funktion definiert hat, bevor das Formular (erfolgreich) ausgewertet wird. Dies ist wiederum gleichbedeutend mit dem Anhalten des Problems und daher im Allgemeinen nicht lösbar.
  3. Es gibt einige häufige Sonderfälle wie Aliasing und Beratung, bei denen (a) Duplikate erstellt werden und (b) Sie möglicherweise in Bezug auf die Quelldatei, die die Funktion deklariert hat, irreführen.
  4. Ein großer Teil der Funktionen wird in C-Code deklariert (nicht unbedingt zugänglich), der nicht wirklich in Bibliotheken unterteilt ist, wie Emacs Lisp-Code.

Vor diesem Hintergrund möchten Sie wahrscheinlich nach find-func.elInspiration suchen , um sich einen Überblick über das Layout und die Probleme beim Auffinden des Quellcodes für Emacs Lisp-Funktionen zu verschaffen.

wvxvw
quelle
Lassen Sie mich dies melden: Wenn ich diesen Code ausführe, erhalte ich den Fehler Symbol's function definition is void: find-library-name. Das ist auch ein kleines Tippfehler-Symbol -> Symbole.
Name
@Name hm ... aber diese Funktion ist sehr alt (ich finde sie im Quellcode von 2002 erwähnt). Könnten Sie es versuchen, (require 'find-func)bevor Sie diesen Code ausführen. Danke für den Tippfehler gefunden. Ich werde das korrigieren.
wvxvw
Danke, es wäre toll, wenn der Name der Bibliothek durch reguläre Ausdrücke angegeben werden könnte.
Name
1

Ich habe diese Funktionalität gerade zu lispy hinzugefügt . Der neue Befehl lispy-goto-elisp-commandsist gebunden an oge.

Das generic g( lispy-goto) gibt eine Liste aller Tags an, wobei Befehle mit einem anderen Gesicht hervorgehoben werden, während lispy-goto-elisp-commandsnur die Befehls-Tags angegeben werden.

Codeliste

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

Dies soll nur zeigen, dass die Semantik von CEDET verwendet wird, um die Liste der Tags zu erhalten. (semantic-tag-get-attribute tag :user-visible-flag)wird verwendet, um zu bestimmen, ob das Tag ein Befehl ist oder nicht.

Wie benutzt man

  1. Navigieren Sie zu der Datei, die den Code enthält. Dies kann mit erfolgen f1 f. Ich verwende stattdessen gerne die Counsel-Description-Funktion , da das Drücken C-.dort nicht durch den *Help*Puffer gehen muss .

  2. Machen Sie den Punkt zu etwas Besonderem (bewegen Sie ihn vor dem Öffnen des Parens oder aktivieren Sie die Region) und drücken Sie oge. Es ist auch möglich, nur zu verwenden M-x lispy-goto-elisp-commands.

abo-abo
quelle
Ich bin ein wenig verwirrt, wenn ich alle Funktionen des Latex-Modus erhalten möchte, was muss ich mit Ihrem Code tun?
Name
Öffnen Sie tex-mode.el. Drücken Sie "oge", um eine Liste von 23 Befehls-Tags zu erhalten, die diese Datei enthält. Wenn Sie eines der Tags auswählen, navigieren Sie dorthin.
abo-abo
Das Ausführen M-x lispy-goto-elisp-commandsauf dem Puffer tex-mode.elgibt den Fehlerlispy--fetch-tags: Wrong type argument: stringp, ("c:/Program Files/GNU Emacs/share/emacs/24.5/lisp/textmodes/tex-mode.el")
Name
Ich habe keine Erfahrung mit CEDET unter Windows. Der Befehl sollte jedoch unter GNU / Linux für 24.5.2 und 25 einwandfrei funktionieren.
abo-abo
Ihre Antwort spricht von " Befehlen ", aber die OP-Frage betrifft Funktionen , nicht nur Befehle . Wenn Sie wirklich Funktionen meinen, möchten Sie möglicherweise den Text korrigieren. Wenn Sie nur Befehle meinen, beantwortet dieser Beitrag die Frage noch nicht wirklich. In diesem Fall möchten Sie sie möglicherweise korrigieren (z. B. den Code ändern oder was auch immer).
Drew
1

Das smex- Paket enthält Code zum Auflisten aller Befehle eines Pakets. Sie können diesen Code anpassen, um alle Funktionen zu erhalten.

rumember
quelle
Oh ja, tut mir leid, dass ich das verpasst habe.
November