Подтвердить что ты не робот

Специальные привязки к конкретным параметрам emacs: local-set-key vs define-key

Через несколько лет, настроив мой файл .emacs, я обнаружил, что использовал два разных типы конструкций для установки привязок ключевых привязок к основному режиму:

1. с помощью крючка и local-set-key. Например:

(defun my/bindkey-recompile ()
  "Bind <F5> to `recompile'."
  (local-set-key (kbd "<f5>") 'recompile))
(add-hook 'c-mode-common-hook 'my/bindkey-recompile)

Я бы сказал, что эта конструкция упрощает использование тех же ключевых привязок для различные основные режимы, добавив одну и ту же функцию ко всем соответствующим основным режимам крючки (другими словами, "какие ключевые привязки я хочу" четко разделены из "для каких режимов я их хочу" ). Однако мне не нравится тот факт, что такие настройки выполняются на уровне буфера, тогда как я бы думаю, что они принадлежат к основному режиму.

2., используя define-key (часто в сочетании с eval-after-load для задержки до тех пор, пока не будет загружена соответствующая карта клавиатуры). Например:

(eval-after-load "cc-mode"
  '(progn
     (define-key c-mode-map   (kbd "C-c o") 'ff-find-other-file)
     (define-key c++-mode-map (kbd "C-c o") 'ff-find-other-file)))

В отличие от этого, эта конструкция настраивает сам основной режим, но меньше гибкий: если я хочу использовать те же привязки клавиш для другого режима, у меня будет найти правильные имена файлов и клавиатур для этого режима и почти дублировать выражение eval-after-load (хотя это, вероятно, можно было бы автоматизировать с помощью функция/макрос).

Вопрос:, хотя оба типа конструкций работают хорошо и дают результат I хотят, они технически очень разные, настраивая ключевые привязки в различные раскладки клавиатуры в разное время. Поэтому мой вопрос: среди этих двух конструкций, есть ли "предпочтительный/лучший" способ сделать что-то? (Или, может быть, "лучший" конструкция является третьей, о которой я не знаю?)

Под "предпочтительным/лучшим" я имею в виду такие вещи, как:

  • менее подвержен перерыву с новыми версиями emacs
  • менее подвержен нарушению/нарушению активными второстепенными режимами
  • более идиоматический/читаемый/доступный с другими
4b9b3361

Ответ 1

Я считаю, что два подхода, которые вы описываете, менее разные, чем вы думаете.

Обратите внимание, что local-set-key действительно оценивает (define-key map key command), где map - это значение (current-local-map), которое обычно задается основным режимом.

Итак, хотя они могут делать разные вещи; большую часть времени единственное реальное различие будет в том, что функция hook с вызовом local-set-key будет устанавливать эту же клавишу повторно/избыточно, тогда как другой подход устанавливает ее только один раз.

Вы можете продемонстрировать это себе, используя local-set-key в режиме hook, удалив эту функцию hook после ее использования, а затем создав новый буфер в том же самом основном режиме и проверив привязку.

менее подвержен перерыву с новыми версиями emacs

Я думаю, вы могли бы утверждать, что имя ключевой карты может измениться в будущем, и поэтому не нужно знать имя, это преимущество, но вы можете сказать, что имя крючка режима может измениться. Я не думаю, что для этого достаточно заботы.

Следует отметить, что local-set-key будет работать, даже если основной режим не установил current-local-map, что, по моему мнению, делает его немного более надежным по сравнению с обобщенными подходами.

менее подвержен нарушению/нарушению активными второстепенными режимами

Нет никакой разницы. Все мажоранты с малым режимом имеют приоритет над всеми основными ключевыми картами режима, и ни один из подходов не будет иметь никакого эффекта на порядок minor-mode-map-alist (который определяет приоритет клавиш мажорного режима).

более идиоматический/читаемый/доступный с другими

Они оба полностью читаемы мне, поэтому я не могу их отличить в этом аспекте.

Я говорю, просто используйте любой подход, который лучше всего подходит вам в каждом контексте. Я считаю, что хорошо иметь стандартный подход для большинства вещей ради согласованности вашего кода, но я сомневаюсь, что это важно, какой из них вы выберете. Очевидно, что экономия нескольких циклов ЦП должна выполняться без необходимости повторного вычисления одного и того же кода, но это должно иметь очень мало значения, чтобы не беспокоиться.

Я думаю, что наиболее очевидным случаем для одного над другим является тот, который вы уже упоминали, - если вы хотите применить одну и ту же привязку к нескольким режимам, используя общий крюк (но не ко всем режимам - для этого я настоятельно рекомендую создание настраиваемого второстепенного режима), тогда local-set-key внутри этого крючка определенно подходит.

Ответ 2

У меня есть множество пользовательских команд клавиатуры, и я не мог потрудиться по-разному, чтобы установить их в Emacs, и все эти keymaps переопределяют друг друга, поэтому я просто установил John Wiegley bind-key в соответствии с моим соответствующим ответом.

(require 'bind-key)
(bind-key "C-l" 'goto-line)