Как создать комбинацию клавиш для пользовательского второстепенного режима в Emacs - PullRequest
11 голосов
/ 25 июня 2010

Вопрос:

Как создать пользовательские сочетания клавиш для второстепенных режимов? Примерно так .

Вот что у меня есть. Я пытаюсь заставить работать только одну пользовательскую привязку клавиш:

(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 ]

20 голосов
/ 25 июня 2010

Короткий ответ

Строка проблемы:

'(((kbd "<kp-1>") . "a"))

Решение (форсировать оценку макроса):

;; Single quote changed to back-quote and added a comma
`((,(kbd "<kp-1>") . "a"))

Длинный ответ

Макрос define-minor-mode позволяет вам создавать второстепенные режимы относительно легко (насколько это возможно в Emacs).

First I 'покажу, как это делается, потом объясню, как это работает:

В общем виде:

(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)

А затем, в вашем второстепенном определении режима, просто перечислите имя переменной для вашей раскладки клавиш вместо alist

(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 для переключения режима).Это также определяет переменную с тем же именем.

Сразу после имени команды мы перечисляем строку документации для второстепенного режима в кавычках.Это может быть сколько угодно.

Далее у нас есть несколько вариантов.Самый простой выбор - просто перечислить три вещи, а затем любые дополнительные опции.Три вещи должны быть перечислены в порядке ниже.Эти три вещи:

  1. Значение инициализации для вспомогательной переменной режима.nil отключит режим по умолчанию.Что-то кроме nil будет по умолчанию включено.

  2. Зажигалка.Светлее - это просто то, что отображается в строке режима внизу, когда ваш второстепенный режим включен.Это должно быть коротким, и это часто помогает, с точки зрения форматирования, начинать его с пробела.

  3. Карта клавиш.Карта ключей может быть определена как переменная или как список (список ассоциаций).Поскольку использование alist проще и короче, это то, что я использовал в примере.Список alist должен быть в форме (key-sequence . definition).

Если вы определите раскладку клавиатуры как список, есть несколько вещей, на которые следует обратить внимание, особенно если вы привыкли определять глобальныесочетания клавиш.Во-первых, имена команд не заключаются в кавычки.Во-вторых, если вы хотите использовать макрос, вы должны заставить его вычислить ( и SO ) .Это делается с помощью комбинации обратной кавычки (не одиночной кавычки) и запятой.Вы можете увидеть, как это делается в примере с макросом kbd.Я также включил определение нажатия клавиш, если вы не используете макрос kbd.Если вы просто заключите в кавычку строку в вашей клавиатуре, она будет распечатана при нажатии определенной комбинации клавиш (как и для определения глобальных привязок клавиш).

Карта клавиш не будет работать с макросами kbd, еслиВы не форсируете оценку макросов kbd комбинацией обратной кавычки и запятой. Например:

`((,(kbd "C-c C-a") . some-command))

Наконец, вы можете добавить дополнительные опции, используя ключевые слова-аргументы вида :blah.В примере я использовал :global.Мы могли бы определить весь режим с помощью ключевых слов-аргументов, но короче просто перечислить значения init, lighter и keymap в правильном порядке.

3 голосов
/ 25 июня 2010

Вам нужно иметь такой код в определении второстепенного режима:

(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 .

2 голосов
/ 25 июня 2010

Посмотрите на это (только для информации о сочетаниях клавиш):

http://www.gnu.org/software/emacs/manual/html_node/emacs/Key-Bindings.html#Key-Bindings

http://www.gnu.org/software/emacs/manual/html_node/emacs/Local-Keymaps.html#Local-Keymaps

С http://xahlee.org/emacs/reclaim_keybindings.html:

Хорошо написанные основные режимы будут работать в конце.Таким образом, вы можете использовать ловушку для определения привязки клавиш.Незначительные режимы обычно не имеют хуков.В этом случае вы можете сначала вызвать «(требуется‹ символ второстепенного режима ›)», а затем определить связывание клавиш.

Также вы можете взглянуть на: http://www.cs.utah.edu/dept/old/texinfo/emacs19/emacs_35.html#SEC347

Может быть,принятый ответ здесь также поможет вам.

...