Основним моментом є те, що між функцією та командою є різниця .
У 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 λ