Различия между установкой основных клавиш режима с помощью ловушки и добавлением их на карту режимов


13

Предположим, что я скачал основной режим под названием magical-mode, и у него есть своя магическая раскладка magical-mode-map. Этот режим также обеспечивает ловушку, magical-mode-hookкоторая запускается каждый раз, когда magical-modeстановится основным режимом буфера. Теперь я хочу изменить свой файл инициализации, добавив несколько пользовательских привязок клавиш для использования в этом режиме.

Кажется, что есть (по крайней мере) два способа настроить пользовательские привязки клавиш magical-mode. То, что я вижу чаще всего, это:

(defun my-magical-keys ()
  (local-set-key (kbd "C-i") 'previous-line)
  (local-set-key (kbd "C-k") 'next-line)
  (local-set-key (kbd "C-j") 'backward-char)
  (local-set-key (kbd "C-l") 'forward-char))
(add-hook 'magical-mode-hook 'my-magical-keys)

Но это также возможно сделать так:

(define-key magical-mode-map (kbd "C-i") 'previous-line)
(define-key magical-mode-map (kbd "C-k") 'next-line)
(define-key magical-mode-map (kbd "C-j") 'backward-char)
(define-key magical-mode-map (kbd "C-l") 'forward-char)

Второй метод на самом деле кажется мне чище. Есть ли какие-либо преимущества в том, чтобы делать это так, как это нужно?


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

@tarsius Действительно тяжелая битва. Я пошел по этому пути раньше, но теперь я вернулся к старым добрым C-nи C-p. Пример - просто фиктивный код. Я хотел придумать несколько очень простых примеров режимов и примеров привязок, именно так, чтобы сами привязки не отвлекали от реальной цели вопроса.
Nispio

Ответы:


15

Второй подход предпочтительнее, так как он модифицирует раскладку режима только один раз.

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

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

Если вы используете ловушку для изменения схемы ключей снова и снова, это может вступить в конфликт с предполагаемым использованием local-set-key. Скажем, вы использовали, M-x local-set-key RET C-i fancy-previous-line RETпотому что вы хотите попробовать этот вариант previous-line. Если вы теперь откроете новый буфер, который использует тот же основной режим, то ловушка будет запущена снова и переопределит вашу временную привязку во всех буферах, использующих этот основной режим, включая буфер, в котором вы ранее использовали local-set-key.


Мне нравится этот ответ, но что, если режим автоматически загружается?
remvee

2
Вы можете отложить загрузку кода до тех пор , после того, как был загружен какой - либо библиотеки: (eval-after-load 'magical '(progn (define-key magical-mode-map ...) ...)).
tarsius

4

Использование (define-key my-magical-mode-map …)это нормальный способ.

Когда вы используете ловушку и local-set-key, ключи добавляются каждый раз, когда вы входите в режим My Magical в некотором буфере. Это странно, потому что local-set-keyвлияет на все буферы, которые находятся в одном и том же режиме (в более общем случае, на все буферы, использующие одну и ту же таблицу ключей). Так что, если вы внесли какие-либо изменения в таблицу ключей, они будут переопределяться каждый раз, когда вы входите в режим My Magical в буфере.

Второй способ также может сбивать с толку, если вы настраиваете раскладку клавиатуры в разных местах. Хуки выполняются в порядке, обратном порядку, в котором они были добавлены, и до тех пор, пока они не будут выполнены в первый раз, вы не увидите никаких следов ваших настроек.


2

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

Чтобы быть уверенным, то, что вы говорите, вы видите чаще всего для этого, это не то, что обычно используется для определения таблицы ключей основного режима. Например, это не то, что вы найдете в исходном коде Emacs. И это не то, что рекомендуется в руководстве Elisp (узел Major Mode Conventions).

Просто хотел убрать это с дороги, чтобы было понятно другим: вы, как правило, не хотите использовать ловушку режима для определения карты основного режима.


На ваш вопрос о настройке ключей пользователя -

В любом случае это не local-set-keyто, что вы должны использовать в режиме ловушки. Просто используйте define-keyс мажорной картой основного режима, точно так же, как в первом примере. @tarsius уже объяснил это хорошо.

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

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

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


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

0

Ваше наименование немного сбивает с толку (я думаю, вы должны удалить myв вашей второй части вопроса).

Во всяком случае, если предположить my-magical-keys, что пользователь настраивает функцию magical-mode, я вижу одно очевидное преимущество. Это легко удалить (за remove-hook) крюк за один раз.

Второе преимущество - для чего предназначены функции. Я имею в виду, что они многоразовые. Вы можете подключить их к другим режимам.

Редактировать:

Как указал @tarsius, удаление хука не восстановит первоначальное поведение, и может быть лучше перевести функцию в второстепенный режим.


Я настраиваю гипотетический основной режим под названием my-magical-mode. Однако, если использование my-префикса сбивает с толку, я, безусловно, могу отредактировать вопрос.
Ниспио

Да, это было бы лучше, обычно (по крайней мере, как я вижу в дикой природе) my-добавляется для пользовательских функций.
любезно

1
Согласовано. Я просто применил my-так, чтобы никто не подумал, что я спрашиваю, как настроить реальный режим с названием magical-mode(если он существует).
Ниспио

1
Нет, удаление крючка не восстановит старые привязки. По крайней мере, до тех пор, пока Emacs не будет перезапущен, и тогда я не вижу необходимости комментировать только одну строку вместо четырех, как такое большое улучшение.
Tarsius

2
Что касается второго преимущества, которое вы упомянули: здесь было бы предпочтительнее создать вспомогательный режим, который затем можно было бы включить для различных основных режимов и / или только для некоторых буферов, использующих конкретный основной режим.
Tarsius
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.