Я написал функцию и хочу вызвать ее через Mx и связать ее с ключом. Это моя функция:
(defun my-function ()
(message "This is a great function"))
Если я пытаюсь вызвать его M-x my-function
, я получаю ошибку: [no match]
в мини-буфере.
Если я пытаюсь связать его с клавишей (или щелчком мыши):
(global-set-key (kbd "C-c a") 'my-function)
Кажется, это работает, но когда я пытаюсь вызвать его с C-c a
, я получаю ошибку
Неверный аргумент типа: commandp, my-function
Почему я не могу использовать свою функцию?
functions
commands
interactive
Тайлер
источник
источник
interactive
- например, иногда команда исчезает из новой версии библиотеки. Ошибка может возникнуть в любом контексте, где Emacs ожидает команду.commandp
чтобы попытаться найти другие Q, которые можно закрыть как дубликаты этого. Будьте внимательны при чтении вопросов и ответов, так как некоторые отличаются. В некоторых случаях ответ (и контекст Q), возможно, стоит повторить здесь. В других случаях вопрос не связан и должен быть оставлен как есть (не закрыт).Ответы:
Суть в том, что есть разница между функцией и командой .
В 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)
строку в определение:Существует множество вариантов
interactive
формы, поддерживающих все виды передачи информации в вашу функцию. Проверьте руководство для всех деталей.Клавиатурные макросы являются особым случаем в этом контексте. Макрос клавиатуры - это последовательность событий ввода, представленная в виде строки. Макросы клавиатуры ведут себя как команды, поэтому вы можете связать их с клавишами, не беспокоясь о добавлении
interactive
объявления. Например, в следующем:"λ"
это макрос клавиатуры, поэтому мы можем связать егоC-c l
без проблем. Если мы пытаемся сделать то же самое с функцией, мы должны быть уверены, что определим функцию какinteractive
:источник
M-x my-function
в вашем примере. Кроме того, как новичок в Emacs, я на самом деле еще не на 100% уверен в том, что именноC-x C-e
делает или когда вам нужно его запустить, но кажется, что ... когда вы запускаете его, он анализирует буфер и перезаписываетmy-function
в памяти, потому что если я не запускать -C-x C-e
M-x
запускает функцию с момента последнегоC-x C-e
C-x C-e
оценивает буфер , кажется, что результатом оценки буфера, содержащего a,defun
является регистрация функции, хотя эта статья, кажется, заставляет меня думать, что она должна просто запустить функцию, и все же единственное, что показано в минибуфере, этоmy-function
(подразумевая, что возвращает функцию?), а неThis is a great function
. Я должен что-то здесь упустить.