Najważniejsze jest to, że istnieje różnica między funkcją a poleceniem .
W Emacs lisp funkcje nie są domyślnie wywoływane interaktywnie. Oznacza to, że nie można uzyskać do nich dostępu za M-x
pomocą klawisza lub kliknięcia myszy ani przypisać ich. Jeśli chcesz to zrobić, musisz jawnie zadeklarować funkcję interactive
, którą wykonujesz, dodając (interactive)
formularz jako pierwszy wiersz w treści (po ciągu dokumentacji). Funkcja interaktywna nazywana jest poleceniem. Wyjaśniono to w instrukcji: (info "(elisp) Using Interactive")
(wersja online) .
Wyświetlany komunikat o błędzie Wrong type argument: commandp, my-function
wskazuje, że próbujesz wywołać funkcję interaktywnie, ale ta funkcja nie jest poleceniem .
Aby wyjaśnić rzeczywisty błąd, litera p
jest często używana w lisp do wskazania predykatu lub testu. W tym przypadku Emacs sprawdza, my-function
czy jest to polecenie korzystające z testu commandp
. Nie jest, co prowadzi do błędu. Podobne błędy pojawiają się przy każdym użyciu przedmiot niewłaściwego typu: jeśli Emacs oczekuje ciąg i przekazać symbol, może pojawić się odniesienie do stringp
, na przykład.
Aby odpowiedzieć na zadane pytanie, musisz dodać (interactive)
wiersz do definicji:
(defun my-function ()
(interactive)
(message "This is a great function"))
Istnieje wiele opcji interactive
formularza, obsługujących wszelkiego rodzaju sposoby przekazywania informacji do funkcji. Sprawdź w instrukcji wszystkie szczegóły.
Makra klawiaturowe są szczególnym przypadkiem w tym kontekście. Makro klawiatury to sekwencja zdarzeń wejściowych, reprezentowana jako ciąg znaków. Makra klawiaturowe zachowują się jak polecenia, dzięki czemu można je przypisywać do klawiszy, nie martwiąc się o dodanie interactive
deklaracji. Na przykład w następujący sposób:
(global-set-key (kbd "C-c l") "λ")
"λ"
to makro klawiatury, dzięki czemu możemy go C-c l
bez problemu powiązać . Jeśli staramy się zrobić to samo z funkcją musimy mieć pewność, aby zdefiniować funkcję jako 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 λ