Основним моментом є те, що між функцією та командою є різниця .
У Emacs lisp функції за замовчуванням не інтерактивні. Це означає, що ви не можете отримати доступ до них через M-x
або прив’язати їх до клавіші або клацання миші. Якщо ви хочете це зробити, вам потрібно чітко оголосити функцію interactive
, яка є , що ви робите, додаючи (interactive)
форму в якості першого рядка в тілі (слідуючи рядку документації). Інтерактивна функція називається командою. Це пояснено в посібнику: (info "(elisp) Using Interactive")
(онлайн-версія) .
Повідомлення про помилку, яке ви бачите, Wrong type argument: commandp, my-function
означає, що ви намагаєтесь викликати функцію інтерактивно, але ця функція не є командою .
Щоб пояснити фактичну помилку, лист p
часто використовується в lisp для позначення предиката або тесту. У цьому випадку Emacs проводить тестування, my-function
щоб перевірити, чи це команда, що використовує тест commandp
. Це не так, що призводить до помилки. Подібні помилки виникають щоразу, коли ви використовуєте об'єкт неправильного типу: якщо Emacs очікує рядок і ви передасте символ, ви можете побачити посилання stringp
, наприклад.
Щоб відповісти на запитання, вам потрібно додати (interactive)
рядок до визначення:
(defun my-function ()
(interactive)
(message "This is a great function"))
Є цілі багато варіантів для interactive
форми, підтримуючи всі види способів передачі інформації в вашу функцію. Перевірте в посібнику всі деталі.
Клавіатури макросів є окремим випадком у цьому контексті. Макрос клавіатури - це послідовність вхідних подій, представлена у вигляді рядка. Макроси клавіатури поводяться як команди, тому ви можете прив’язати їх до клавіш, не турбуючись про додавання interactive
декларації. Наприклад, у наступному:
(global-set-key (kbd "C-c l") "λ")
"λ"
є макросом клавіатури, тому ми можемо C-c l
без проблем зв’язати його . Якщо ми намагаємось зробити те ж саме з функцією, ми повинні бути впевнені, щоб визначити функцію як 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 λ