Use dois mapas de modo principal no mesmo buffer

11

Já deparei com algumas situações em que seria altamente conveniente que o mapa de teclas de um modo principal atue como um mapa de teclas de fallback para outro modo principal. Por exemplo:

  • Eu escrevo muito LaTeX em alguns dos meus documentos organizacionais, por isso seria ótimo ter latex-modecomandos disponíveis facilmente durante a edição org-mode.
  • Eu frequento uma sala de irc com suporte ao Markdown, por isso também seria bom markdown-modeadicionar teclas de atalho erc-mode.

Nos dois casos, este mapa de teclas extra deve funcionar como um substituto (é por isso que não posso usar apenas um modo secundário para isso). Não quero que os comandos de látex substituam nenhuma org-modechave. O que eu quero é:
Se uma chave estiver definida em latex-mode-mapAND, não estiver definida org-mode-map, use a latex-mode-mapligação .

P: Como posso definir um mapa de teclas como um mapa de teclas de fallback para um modo principal?
OU
P: Como copiar chaves de um mapa de modo principal para outro, sem substituir nada?


Só para ficar claro. Eu sei que poderia definir essas chaves uma por uma, mas seria infinitamente mais conveniente ter uma solução automatizada.

Malabarba
fonte
6
Use uma mesclagem de mapa de teclas. Veja make-composed-keymap.
Drew

Respostas:

12

Isso acabou sendo mais simples do que o esperado. Como sugerido nos comentários aqui e na pergunta:

(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)))

Isso criará um mapa de chaves que é uma cópia, erc-mode-mapmas que também herda markdown-mode-map. Portanto, todas as markdownchaves serão sombreadas sempre que colidirem com elas erc.

Se você não quer algumas chaves do keymap fallback para ofuscar o kemap principal, apenas desativá-los em um principal.

(define-key erc-mode-map "\C-c\C-a" nil)
Malabarba
fonte
2
Percebi que o uso define-keydo valor de retorno de make-composed-keymappode ter efeitos colaterais inesperados nos mapas de teclas originais, e suspeito que o mesmo possa se aplicar a esse appendedmapa manualmente . Se você deseja usar define-key, parece mais seguro criar um novo mapa de teclas cujo mapa de teclas pai é um mapa de teclas composto.
Jon O.
@JonO. Na verdade, fiquei muito surpreso ao descobrir que isso não acontece aqui. Se sim (define-key erc-mode-map "\C-c\C-s" nil), a markdown-modechave correspondente ainda estará disponível, mesmo nos buffers erc.
Malabarba
Malabarba: Acredito que seu último comentário não se aplica mais após a alteração do código. A make-composed-keymapdocumentação diz que "uma ligação nula no MAPS substitui qualquer ligação correspondente no PARENT, mas não substitui as ligações correspondentes em outros mapas principais do MAPS". Como markdown-mode-mapPARENT no seu exemplo, eu esperaria que essa nilligação inibisse a ligação de remarcação?
php phils
2
Minha interpretação é que (make-composed-keymap (list erc-mode-map markdown-mode-map)) teria o efeito que você descreveu, no entanto?
php phils
1
cl-copy-listrealmente não fará o que você quiser. Se você deseja copiar o mapa de teclas, deveria ter usado copy-keymap.
27516 Stefan
3

Como mencionado por @Malabarba, você pode usar make-composed-keymappara isso. Mas se você realmente deseja que o novo mapa de chaves seja herdado dos dois mapas de teclas, a modificação do novo mapa de teclas não afeta nenhum dos outros dois mapas de teclas, mas é necessário fazê-lo em duas etapas:

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

Isso ocorre porque define-keyàs vezes pode modificar os mapas passados ​​como primeiro argumento, make-composed-keymapmas não aqueles passados ​​como segundo. Eu acho que você deve M-x report-emacs-buge solicita que make-composed-keymapaceite uma lista de keymaps como segundo argumento, para que você possa fazer

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