Предположим, что я скачал основной режим под названием 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)
Второй метод на самом деле кажется мне чище. Есть ли какие-либо преимущества в том, чтобы делать это так, как это нужно?
elisp
key-bindings
major-mode
nispio
источник
источник
C-n
иC-p
. Пример - просто фиктивный код. Я хотел придумать несколько очень простых примеров режимов и примеров привязок, именно так, чтобы сами привязки не отвлекали от реальной цели вопроса.Ответы:
Второй подход предпочтительнее, так как он модифицирует раскладку режима только один раз.
Если вы сделаете это с помощью ловушки режима, то она будет вызываться каждый раз, когда этот режим включен в каком-либо буфере. Повторное выполнение обычно не будет иметь никакого эффекта, потому что ключи просто снова связаны с тем, с чем они уже связаны. Таблицы ключей основного режима являются «локальными» для основного режима, а не для отдельных буферов, которые используют этот режим, поэтому, если вы измените привязку в одном из этих буферов, используя
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
.источник
(eval-after-load 'magical '(progn (define-key magical-mode-map ...) ...))
.Использование
(define-key my-magical-mode-map …)
это нормальный способ.Когда вы используете ловушку и
local-set-key
, ключи добавляются каждый раз, когда вы входите в режим My Magical в некотором буфере. Это странно, потому чтоlocal-set-key
влияет на все буферы, которые находятся в одном и том же режиме (в более общем случае, на все буферы, использующие одну и ту же таблицу ключей). Так что, если вы внесли какие-либо изменения в таблицу ключей, они будут переопределяться каждый раз, когда вы входите в режим My Magical в буфере.Второй способ также может сбивать с толку, если вы настраиваете раскладку клавиатуры в разных местах. Хуки выполняются в порядке, обратном порядку, в котором они были добавлены, и до тех пор, пока они не будут выполнены в первый раз, вы не увидите никаких следов ваших настроек.
источник
Вы, очевидно, не задаете вопрос об определении таблицы ключей основного режима, а о том, чтобы пользовательский код добавил или изменил несколько комбинаций клавиш в существующей таблице ключей основного режима. Вы говорите «обычай», что говорит об этом, но мы могли бы прояснить это.
Чтобы быть уверенным, то, что вы говорите, вы видите чаще всего для этого, это не то, что обычно используется для определения таблицы ключей основного режима. Например, это не то, что вы найдете в исходном коде Emacs. И это не то, что рекомендуется в руководстве Elisp (узел
Major Mode Conventions
).Просто хотел убрать это с дороги, чтобы было понятно другим: вы, как правило, не хотите использовать ловушку режима для определения карты основного режима.
На ваш вопрос о настройке ключей пользователя -
В любом случае это не
local-set-key
то, что вы должны использовать в режиме ловушки. Просто используйтеdefine-key
с мажорной картой основного режима, точно так же, как в первом примере. @tarsius уже объяснил это хорошо.Кроме этого, ответ таков: в общем , не имеет большого значения, будете ли вы связывать клавиши (используя
define-key
карту режимов) раз и навсегда или используете хук для их привязки каждый раз при входе в режим.Но это может иметь значение, если привязки на карте меняются - например, загружая какой-то другой код, который их меняет. В этом случае размещение привязок на хуке основного режима гарантирует, что при входе в режим привязки будут установлены. То есть он гарантирует, что они будут выполнены, но не гарантирует, что ничто другое не изменит их впоследствии (например, другая функция на том же хуке, вызванная позже). Помните, что у вас мало контроля над тем, что запускается на крючке и когда - если, конечно, вы не уверены, что только ваш собственный код мешает с этим.
Это единственная разница в действии, о которой я могу думать. Вам решать, когда вы считаете эту разницу преимуществом того или иного подхода. FWIW, глядя на мой собственный код, я не думаю, что когда-либо связывал ключи на ловушке режима.
источник
Ваше наименование немного сбивает с толку (я думаю, вы должны удалить
my
в вашей второй части вопроса).Во всяком случае, если предположить
my-magical-keys
, что пользователь настраивает функциюmagical-mode
, я вижу одно очевидное преимущество. Это легко удалить (заremove-hook
) крюк за один раз.Второе преимущество - для чего предназначены функции. Я имею в виду, что они многоразовые. Вы можете подключить их к другим режимам.
Редактировать:
Как указал @tarsius, удаление хука не восстановит первоначальное поведение, и может быть лучше перевести функцию в второстепенный режим.
источник
my-magical-mode
. Однако, если использованиеmy-
префикса сбивает с толку, я, безусловно, могу отредактировать вопрос.my-
добавляется для пользовательских функций.my-
так, чтобы никто не подумал, что я спрашиваю, как настроить реальный режим с названиемmagical-mode
(если он существует).