Il punto centrale è che esiste una differenza tra una funzione e un comando .
In Emacs lisp, le funzioni non sono richiamabili in modo interattivo per impostazione predefinita. Ciò significa che non è possibile accedervi tramite M-x
o legarli a un tasto o un clic del mouse. Se vuoi farlo, devi dichiarare esplicitamente la funzione interactive
, cosa che fai aggiungendo un (interactive)
modulo come prima riga nel corpo (seguendo la stringa di documentazione). Una funzione interattiva si chiama comando Questo è spiegato nel manuale: (info "(elisp) Using Interactive")
(versione online) .
Il messaggio di errore visualizzato Wrong type argument: commandp, my-function
indica che stai tentando di chiamare una funzione in modo interattivo, ma tale funzione non è un comando .
Per spiegare l'errore reale, la lettera p
viene spesso utilizzata in lisp per indicare un predicato o un test. In questo caso, Emacs sta testando my-function
per vedere se si tratta di un comando che utilizza il test commandp
. Non lo è, il che porta all'errore. Errori simili compaiono ogni volta che usi un oggetto del tipo sbagliato: se Emacs prevede una stringa e passi un simbolo, potresti vedere un riferimento stringp
, ad esempio.
Per rispondere alla domanda come richiesto, è necessario aggiungere la (interactive)
linea alla definizione:
(defun my-function ()
(interactive)
(message "This is a great function"))
Esistono molte opzioni per il interactive
modulo, che supporta tutti i tipi di modi per trasmettere informazioni alla tua funzione. Controlla il manuale per tutti i dettagli.
Le macro della tastiera sono un caso speciale in questo contesto. Una macro di tastiera è una sequenza di eventi di input, rappresentata come una stringa. Le macro della tastiera si comportano come comandi, quindi puoi associarle ai tasti senza preoccuparti di aggiungere una interactive
dichiarazione. Ad esempio, di seguito:
(global-set-key (kbd "C-c l") "λ")
"λ"
è una macro di tastiera, quindi possiamo collegarla C-c l
senza problemi. Se proviamo a fare la stessa cosa con una funzione, dobbiamo essere sicuri di definire la funzione come 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 λ