Как создать комбинацию клавиш для пользовательского второстепенного режима в Emacs
Вопрос:
Как создать пользовательские сочетания клавиш для второстепенных режимов? Как то так
Вот что у меня так далеко. Я пытаюсь заставить работать только одну пользовательскую привязку клавиш:
(define-minor-mode num-mode
"Toggle the Num pad keys.
With no argument, this command toggles the mode.
Non-null prefix argument turns on the mode.
Null prefix argument turns off the mode.
When Num mode is enabled, the num pad inserts the
keys you see on the pad. This may over ried existing
definitions, and is probably only usefule if you aref
running Emacs through a terminal."
;; The initial value.
nil
;; The indicator for the mode line.
" NumPad"
;; The minor mode bindings.
;; This doesn't work right now!!!!
'(((kbd "<kp-1>") . "a"))
:global 1
)
Когда я нажимаю "1" на цифровой клавиатуре после вызова моего пользовательского второстепенного режима "num-mode" и проверки его включения в мини-буфере, я получаю сообщение об ошибке <kp-1> is undefined
, То, что я хочу, это a
распечатывается, где указатель, когда я нажимаю <kp-1>
, (просто тест)
Контекст:
Поэтому я обычно использую свою цифровую клавиатуру для перемещения между буферами (клавиши со стрелками перемещают меня в нужном направлении). Это установлено глобально. Я хочу создать второстепенный режим, который я могу вызывать, когда я хочу использовать свою цифровую клавиатуру для простого ввода чисел.
По умолчанию клавиши на моей цифровой клавиатуре не определены. я использую <kp-0>
в <kp-9>
определить сочетания клавиш для цифровых клавиш.
Я могу создать второстепенный режим, который я могу вызвать, но я не могу прикрепить какие-либо сочетания клавиш. Это верно для всех сочетаний клавиш, в том числе ни для одного другого.
Спасибо за любую помощь!
3 ответа
Короткий ответ
Проблемная линия:
'(((kbd "<kp-1>") . "a"))
Решение (форсировать оценку макроса):
;; Single quote changed to back-quote and added a comma
`((,(kbd "<kp-1>") . "a"))
Длинный ответ
Макрос define-minor-mode позволяет относительно легко создавать второстепенные режимы (насколько это возможно в Emacs).
Сначала я покажу, как это делается, а затем объясню, как это работает:
В общем виде:
(define-minor-mode NAME-mode
"DOCUMENTATION"
INIT-VALUE
"LIGHTER"
;; keymap
'(
(KEY-SEQUENCE . DEFINITION)
(KEY-SEQUENCE . DEFINITION)
... ETC ...
)
;; other options
:KEYWORD-ARG VALUE
:KEYWORD-ARG VALUE
... ETC ...
)
Конкретный пример с принудительной оценкой макросов в alist:
;; Custom Minor Mode
(define-minor-mode custom-mode
"Doc description, yada yada yada."
;; The initial value - Set to 1 to enable by default
nil
;; The indicator for the mode line.
" CustomMode"
;; The minor mode keymap
`(
(,(kbd "C-c C-a") . some-command)
(,(kbd "C-c C-b") . other-command)
("\C-c\C-c" . "This works too")
)
;; Make mode global rather than buffer local
:global 1
)
Альтернативный способ, если вы хотите использовать переменную для раскладки ключей, это определить переменную раскладки и раскладку раскладки до объявления второстепенного режима примерно так:
(defvar custom-mode-keymap (make-keymap) "num-mode keymap.")
(define-key custom-mode-keymap (kbd "C-c C-a") 'some-command)
А затем, в вашем второстепенном определении режима, просто перечислите имя переменной для вашей раскладки клавиш, а не список
(define-key custom-mode-keymap (kbd "C-c C-b") 'other-command)
;; Num pad enable
(define-minor-mode custom-mode
...
;; The minor mode bindings.
custom-mode-keymap
Как все это работает
Сверху вниз, сразу после define-minor-mode, мы определяем имя команды для переключения второстепенного режима. custom-mode
в этом случае (M-x custom-mode
переключить режим). Это также определяет переменную с тем же именем.
Сразу после имени команды мы перечисляем строку документации для второстепенного режима в кавычках. Это может быть в значительной степени так долго, как вы хотите.
Далее у нас есть несколько вариантов. Самый простой выбор - просто перечислить три вещи, а затем любые дополнительные опции. Три вещи должны быть перечислены в порядке ниже. Эти три вещи:
Значение инициализации для вспомогательной переменной режима.
nil
будет выключен режим по умолчанию. Что-то кромеnil
будет включен по умолчанию.Зажигалка Светлее - это просто то, что отображается в строке режима внизу, когда ваш второстепенный режим включен. Это должно быть коротким, и это часто помогает, с точки зрения форматирования, начинать его с пробела.
Карта ключей. Карта ключей может быть определена как переменная или как список (список ассоциаций). Поскольку использование alist проще и короче, это то, что я использовал в примере. Alist должен быть в форме
(key-sequence . definition)
,
Если вы определяете раскладку ключей как список, есть несколько моментов, на которые следует обратить внимание, особенно если вы привыкли определять глобальные привязки клавиш. Во-первых, имена команд не заключаются в кавычки. Во-вторых, если вы хотите использовать макрос, вы должны заставить его оценить ( и на SO). Это делается с помощью комбинации обратной кавычки (не одиночной кавычки) и запятой. Вы можете увидеть, как это делается в примере с макросом kbd. Я также включил определение нажатия клавиш, если вы не используете макрос kbd. Если вы просто заключите в кавычки строку в вашей таблице ключей, она будет распечатана при нажатии определенной комбинации клавиш (точно так же, как для определения глобальных привязок клавиш).
Карта ключей не будет работать с макросами kbd, если вы не форсируете оценку макросов kbd комбинацией обратной кавычки и запятой. Как это:
`((,(kbd "C-c C-a") . some-command))
Наконец, вы можете добавить дополнительные параметры, используя ключевые слова в форме :blah
, В примере, который я использовал :global
, Мы могли бы определить весь режим с помощью ключевых слов-аргументов, но короче просто перечислить значение init, lighter и keymap в правильном порядке.
Вам нужно иметь такой код в определении второстепенного режима:
(defvar your-mode-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map parent-mode-shared-map)
(define-key map "\C-c\C-a" 'some-defun)
(define-key map "\C-c\C-b" 'some-other-sexp)
map)
(use-local-map your-mode-map)
Вы можете взглянуть на многие режимы, доступные в EmacsWiki для справки.
Посмотрите на это (только для информации о сочетаниях клавиш):
http://www.gnu.org/software/emacs/manual/html_node/emacs/Key-Bindings.html
http://www.gnu.org/software/emacs/manual/html_node/emacs/Local-Keymaps.html
С http://xahlee.org/emacs/reclaim_keybindings.html:
Хорошо написанные основные режимы будут работать в конце. Таким образом, вы можете использовать ловушку для определения привязки клавиш. Незначительные режимы обычно не имеют хуков. В этом случае вы можете сначала позвонить "(требуется‹ символ функции второстепенного режима ›)", а затем определить связывание клавиш.
Также вы можете взглянуть на: http://www.cs.utah.edu/dept/old/texinfo/emacs19/emacs_35.html
Возможно, принятый здесь ответ также поможет вам.