Как вызвать интерактивную функцию Emacs Lisp с аргументом префикса, из другой функции Emacs Lisp?
Я хочу написать функцию Emacs Lisp, которая включит flyspell-mode
независимо от текущего состояния режима. Функция flyspell-mode-on
устарела. Документация предполагает, что положительный аргумент префикса превратится в flyspell-mode
, но, к сожалению, работает
(flyspell-mode 1)
выводится сообщение об ошибке:
Wrong number of arguments: (lambda (flyspell-mode 1)), 0
Если бы я мог понять, как вызвать flyspell-mode
с аргументом префикса, я считаю, что смогу решить эту проблему.
Наиболее подходящий раздел, который я могу найти в руководстве Emacs Lisp, - это раздел "Интерактивный вызов", который описывает такие команды, как call-interactively
. Это решительно не то, что я хочу.
(Конечная проблема, которую я пытаюсь решить, - создать крючок режима, который включает режим независимо от его текущего состояния.)
N.B. Название вопроса emacs Lisp функция вызова с аргументом префикса программно делает его похожим, но этот вопрос спрашивал о том, как создать интерактивную команду, и проблема была в конечном итоге решена с помощью call-interactively
.
EDIT: этот вопрос спорный; Я нашел альтернативное решение моей исходной проблемы:
(add-hook 'text-mode-hook
(function (lambda ()
(require 'flyspell)
(if flyspell-mode nil (flyspell-mode)))))
Но мне все же хотелось бы знать, как вызвать функцию Emacs Lisp с аргументом префикса, из другой функции Emacs Lisp, без чего-либо интерактивного.
UPDATE. Возможно, мне следовало спросить, почему я получил сообщение об ошибке...
Ответы
Ответ 1
Похоже, что ваша версия режима Flyspell не соответствует соглашениям о второстепенном режиме, которые требуют, чтобы вы могли включить вспомогательный режим с помощью (name-of-mode t)
или любой положительный аргумент префикса, отключите его с помощью (name-of-mode 0)
любого отрицательного префиксного аргумента и переключите его с помощью (name-of-mode nil)
.
Если у вас установлена последняя версия Flyspell, отчет об ошибке может быть в порядке. У меня есть версия, поставляемая с GNU Emacs 23.2 на моей машине, и она соблюдает соглашение. Моя версия также определяет две функции turn-on-flyspell
и turn-off-flyspell
, как тривиальные обертки вокруг flyspell-mode
; функции с такими именами являются общими, но не официальными соглашениями. Функции flyspell-mode-on
и flyspell-mode-off
, по-видимому, предназначены для внутреннего использования.
Как правило, команды считывают текущий префиксный аргумент из переменной current-prefix-arg
. Не путайте это с prefix-arg
, что является значением для следующей команды (только несколько команд, например universal-argument
, коснитесь этой переменной). Таким образом, если вам нужно передать префиксный аргумент при вызове функции, свяжите или установите current-prefix-arg
.
(let ((current-prefix-arg t))
(flyspell-mode))
Ответ 2
Если вы не вызываете функцию в интерактивном режиме, объявление (interactive)
не используется для получения аргументов.
В подавляющем большинстве случаев вам не нужно беспокоиться о том, может ли аргумент быть "аргументом префикса" для неинтерактивных вызовов; просто проверьте документацию по функциям и передайте нужное значение для того, что вы хотите сделать.
Если по какой-то причине вам необходимо реплицировать отправку префиксного аргумента в неинтерактивный контекст, вам нужно будет проверить объявление функции (interactive)
и точно определить, как он использует этот аргумент, и убедиться, что вы реплицируете этот поведение для аргумента, который вы передаете.
Подробнее см. в разделе
- C-h f
interactive
RET
- M-:
(info "(elisp) Prefix Command Arguments")
RET
В более сложных случаях, когда функция меняет свое поведение на основе переменной current-prefix-arg
, вы можете напрямую установить эту переменную.
(let ((current-prefix-arg '(4)))
(foo current-prefix-arg))
Ответ 3
Я могу думать об этом. Должно быть лучше
(call-interactively '(lambda ()
(interactive)
(flyspell-mode '(4))))
UPDATE:
Я могу запустить это прямо. Что мне не хватает в этом вопросе.?
(flyspell-mode '(4))
Ответ 4
FWIW, функция "flyspell-mode" приняла аргумент (как в "(flyspell-mode 1)" ) по крайней мере с Emacs-21, поэтому я не знаю, как вы получили эту ошибку.
Но пока я здесь, я мог бы также отметить, что (flyspell-mode) в режиме "add-hook" изменил значение в Emacs-24: вместо значения "переключить режим flyspell в тексте" режимы "теперь это означает" включить режим flyspell в текстовых режимах ". Это отстало-несовместимое изменение, но я считаю, что он исправит более скрытые ошибки, чем он представит.
Ответ 5
Я не Emacs и Elisp master (пока;)), но я думаю, что в этом случае вы можете использовать Ctrl - u 1
Alt - x flyspell-mode
.