Der Kernpunkt ist, dass es einen Unterschied zwischen einer Funktion und einem Befehl gibt .
In Emacs lisp können Funktionen standardmäßig nicht interaktiv aufgerufen werden. Das bedeutet, dass Sie nicht über M-x
einen Schlüssel oder Mausklick darauf zugreifen oder sie daran binden können. Wenn Sie das tun möchten, müssen Sie die Funktion explizit deklarieren interactive
, indem Sie ein (interactive)
Formular als erste Zeile im Hauptteil hinzufügen (nach der Dokumentationszeichenfolge). Eine interaktive Funktion wird als Befehl bezeichnet. Dies wird im Handbuch erklärt: (info "(elisp) Using Interactive")
(Online-Version) .
Die angezeigte Fehlermeldung Wrong type argument: commandp, my-function
zeigt an, dass Sie versuchen, eine Funktion interaktiv aufzurufen, diese Funktion jedoch kein Befehl ist .
Um den tatsächlichen Fehler zu erklären, wird der Buchstabe p
häufig in Lispeln verwendet, um ein Prädikat oder einen Test anzugeben. In diesem Fall testet Emacs mit dem Test my-function
, ob es sich um einen Befehl handelt commandp
. Es ist nicht, was zu dem Fehler führt. Ähnliche Fehler treten auf, wenn Sie ein Objekt des falschen Typs verwenden: Wenn Emacs einen String erwartet und Sie ein Symbol übergeben, wird möglicherweise ein Verweis auf stringp
angezeigt.
Um die gestellte Frage zu beantworten, müssen Sie die (interactive)
Zeile zur Definition hinzufügen :
(defun my-function ()
(interactive)
(message "This is a great function"))
Es gibt viele Optionen für das interactive
Formular, die alle Arten der Weitergabe von Informationen an Ihre Funktion unterstützen. Überprüfen Sie das Handbuch für alle Details.
Ein Sonderfall sind in diesem Zusammenhang Tastaturmakros. Ein Tastaturmakro ist eine Folge von Eingabeereignissen, die als Zeichenfolge dargestellt werden. Tastaturmakros verhalten sich wie Befehle, sodass Sie sie an Tasten binden können, ohne sich Gedanken über das Hinzufügen einer interactive
Deklaration machen zu müssen. Zum Beispiel im Folgenden:
(global-set-key (kbd "C-c l") "λ")
"λ"
ist ein Tastaturmakro, an das wir es C-c l
problemlos binden können . Wenn wir versuchen, dasselbe mit einer Funktion zu tun, müssen wir die Funktion folgendermaßen definieren interactive
:
(global-set-key (kbd "C-c k")
(lambda () (insert "λ"))
;; C-c k is undefined! We tried to bind it to a function
(global-set-key (kbd "C-c m")
(lambda () (interactive) (insert "λ"))
;; C-c m is bound to a command that inserts λ