Используйте две карты основного режима в одном буфере

11

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

  • Я пишу много LaTeX в некоторых моих документах org, поэтому было бы здорово иметь latex-modeкоманды, легко доступные во время редактирования org-mode.
  • Я часто посещаю IRC-комнату с поддержкой Markdown, так что было бы неплохо markdown-modeдобавить привязки клавиш erc-mode.

В обоих случаях эта дополнительная раскладка клавиш должна действовать как запасной вариант (поэтому я не могу просто использовать дополнительный режим для этого). Я не хочу, чтобы латексные команды переопределяли какие-либо org-modeключи. То, что я хочу:
если ключ определен в latex-mode-mapAND, он не определен, org-mode-mapтогда используйте latex-mode-mapпривязку .

Q: Как я могу установить раскладку клавиатуры как запасную раскладку для основного режима?
ИЛИ В
: Как можно копировать ключи из одной карты основного режима в другую, не переопределяя ничего?


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

Malabarba
источник
6
Используйте слияние клавиш. См make-composed-keymap.
Дрю

Ответы:

12

Это оказалось проще, чем ожидалось. Как предлагается в комментариях здесь и по вопросу:

(with-eval-after-load 'erc
  (require 'markdown-mode)
  (require 'cl-lib)
  (setq erc-mode-map
        (make-composed-keymap (cl-copy-list erc-mode-map)
                              markdown-mode-map)))

Это создаст карту ключей, которая является копией, erc-mode-mapно также наследуется от markdown-mode-map. Таким образом, все markdownключи будут затенены всякий раз, когда они сталкиваются с ercключами.

Если вы хотите, чтобы некоторые ключи резервной таблицы ключей затмили основную карту, просто отключите их в основной.

(define-key erc-mode-map "\C-c\C-a" nil)
Malabarba
источник
2
Я заметил, что использование define-keyвозвращаемого значения make-composed-keymapможет иметь неожиданные побочные эффекты для исходных таблиц ключей, и я подозреваю, что то же самое может относиться к этой appendedкарте вручную . Если вы хотите использовать define-key, кажется, безопаснее всего создать новую раскладку, родительская раскладка которой является составной раскладкой.
Джон О.
@JonO. На самом деле, я был очень удивлен, узнав, что этого не происходит здесь. Если я это сделаю (define-key erc-mode-map "\C-c\C-s" nil), соответствующий markdown-modeключ будет по-прежнему доступен даже в буферах erc.
Малабарба
Малабарба: Я считаю, что ваш последний комментарий больше не применяется после этого изменения кода. В make-composed-keymapдокументации говорится, что «нулевая привязка в MAPS переопределяет любую соответствующую привязку в PARENT, но она не переопределяет соответствующие привязки в других таблицах ключей MAPS». Как markdown-mode-mapи PARENT в вашем примере, я ожидал бы, что nilпривязка будет препятствовать привязке уценки?
Фил
2
Моя интерпретация заключается в том, (make-composed-keymap (list erc-mode-map markdown-mode-map)) что это будет иметь эффект, который вы описали, однако?
Филс
1
cl-copy-listна самом деле не будет делать то, что вы хотите. Если вы хотите скопировать карту ключей, то вам следовало бы использовать copy-keymap.
Стефан
3

Как уже упоминалось @Malabarba, вы можете использовать make-composed-keymapдля этого. Но если вы действительно хотите, чтобы новая раскладка ключей наследовала от обеих раскладок, то изменение этой раскладки не влияет ни на одну из двух других раскладок, вам нужно сделать это в два этапа:

(make-composed-keymap
 nil (make-composed-keymap (list erc-mode-map markdown-mode-map)))

Это потому, что define-keyиногда можно изменить карты, переданные в качестве первого аргумента, make-composed-keymapно не карты, переданные в качестве второго. Я думаю , вы должны M-x report-emacs-bugи просить make-composed-keymapпринять список из раскладок в качестве второго аргумента, так что вы можете просто сделать

(make-composed-keymap nil (list erc-mode-map markdown-mode-map))
Стефан
источник