Відмінності між встановленням основних клавіш режиму гачком та додаванням їх до карти режимів


13

Припустимо, що я завантажив основний режим, який називається magical-mode, і він має свою магічну клавішну назву magical-mode-map. Цей режим також забезпечує гак, magical-mode-hookякий запускається кожного разу, коли він magical-modeстає основним режимом буфера. Тепер я хочу змінити мій файл init, щоб додати кілька спеціальних прив’язок клавіш для використання в цьому режимі.

Здається, що існує (принаймні) два способи встановити прив'язки до спеціальних ключів 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 Справді бойовий бій. Я пішов цим шляхом раніше, але тепер я повернувся до старих добрих 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.


Мені подобається ця відповідь, але що робити, якщо режим завантажується автоматично?
ремвай

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

4

Використання (define-key my-magical-mode-map …)- це звичайний спосіб.

Коли ви використовуєте гачок і local-set-key, клавіші додаються щоразу, коли ви входите в режим "Мій магічний" у якомусь буфері. Це дивно, оскільки local-set-keyвпливає на всі буфери, що знаходяться в одному режимі (загалом, всі буфери, що використовують однакову клавішу). Отже, якщо ви внесли якісь зміни в карту клавіш, вони будуть переопрацьовані кожного разу, коли ви вводите "Мій магічний режим" у буфер.

Другий метод також може бути заплутаним, якщо ви налаштовуєте клавіатурну карту в різних місцях. Гачки виконуються в зворотному порядку від того, до якого вони додані, і до першого їх виконання ви не побачите жодних слідів ваших налаштувань.


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-префікса заплутано, я, безумовно, можу відредагувати питання.
nispio

Так, це було б краще, зазвичай (як мінімум, як я бачу в дикій природі) my-додається для функцій користувача.
kindahero

1
Домовились. Я просто застосував my-так, щоб ніхто не подумав, що я питаю, як налаштувати реальний режим, який називається magical-mode(якщо він існує).
nispio

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

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