Użyj dwóch map trybu głównego w tym samym buforze

11

Zetknąłem się z kilkoma sytuacjami, w których bardzo wygodnie byłoby mieć mapę kluczową jednego trybu głównego działającą jako mapa zapasowa dla innego trybu głównego. Na przykład:

  • Piszę dużo LaTeX-a w niektórych moich dokumentach organizacyjnych, więc świetnie byłoby mieć latex-modełatwo dostępne polecenia podczas edycji org-mode.
  • Często odwiedzam IRC z obsługą Markdown, więc fajnie byłoby też markdown-modedodać skróty klawiszowe erc-mode.

W obu przypadkach ta dodatkowa mapa klawiszy powinna działać jako rezerwowa (dlatego nie mogę po prostu użyć do tego trybu mniejszego). Nie chcę, aby polecenia lateksu zastępowały jakiekolwiek org-modeklawisze. Chcę, aby:
Jeśli klucz jest zdefiniowany w latex-mode-mapAND i nie jest zdefiniowany w, org-mode-mapużyj latex-mode-mappowiązania .

P: Jak ustawić mapę klawiszy jako mapę zastępczą dla trybu głównego?
LUB
P: W jaki sposób można skopiować klucze z jednej mapy trybu głównego na inny, nie zastępując niczego?


Żeby było jasne. Wiem, że mógłbym zdefiniować te klucze jeden po drugim, ale nieskończenie wygodniej byłoby mieć zautomatyzowane rozwiązanie.

Malabarba
źródło
6
Użyj scalania mapy klawiszy. Zobaczyć make-composed-keymap.
Drew

Odpowiedzi:

12

Okazało się to prostsze niż się spodziewano. Jak sugerowano w komentarzach tutaj i na pytaniu:

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

Spowoduje to utworzenie mapy klawiszy, która jest kopią, erc-mode-mapale z której również dziedziczy markdown-mode-map. Dlatego wszystkie markdownklucze będą zasłaniane za każdym razem, gdy zderzą się z erckluczami.

Jeśli chcesz , aby niektóre klucze mapy zastępczej przyćmiały główny kemap, po prostu wyłącz je w głównym.

(define-key erc-mode-map "\C-c\C-a" nil)
Malabarba
źródło
2
Zauważyłem, że użycie define-keyzwracanej wartości make-composed-keymapmoże mieć nieoczekiwane skutki uboczne w oryginalnych mapach klawiszy i podejrzewam, że to samo może dotyczyć tej appendedmapy ręcznie . Jeśli chcesz użyć define-key, wydaje się, że najbezpieczniej jest utworzyć nową mapę klawiszy, której mapa nadrzędna jest klawiaturą złożoną.
Jon O.
@JonO. Byłem bardzo zaskoczony, gdy dowiedziałem się, że tak się nie dzieje. Jeśli to zrobię (define-key erc-mode-map "\C-c\C-s" nil), odpowiedni markdown-modeklucz będzie nadal dostępny, nawet w buforach erc.
Malabarba,
Malabarba: Uważam, że twój ostatni komentarz nie ma już zastosowania po tej zmianie kodu. make-composed-keymapDokumentacja mówi „a nil wiąże w MAPS zastępuje dowolny odpowiadający wiąże w rodzicem, ale nie zastępują odpowiadające wiązania w innych keymaps map.” Podobnie jak markdown-mode-mapw twoim przykładzie PARENT, oczekiwałbym, że to nilwiązanie powstrzyma wiązanie przeceny?
phils
2
Jednak moja interpretacja (make-composed-keymap (list erc-mode-map markdown-mode-map)) byłaby taka, jak byście opisali efekt?
phils
1
cl-copy-listtak naprawdę nie zrobi tego, co chcesz. Jeśli chcesz skopiować mapę klawiszy, powinieneś był użyć copy-keymap.
Stefan
3

Jak wspomniano @Malabarba, możesz make-composed-keymapdo tego użyć . Ale jeśli naprawdę chcesz, aby nowa mapa klawiszy odziedziczyła po obu mapach klawiszy, takie modyfikowanie nowej mapy klawiszy nie wpływa na żadną z pozostałych dwóch map klawiszy, musisz to zrobić w dwóch krokach:

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

Wynika to z faktu, że define-keyczasami można modyfikować mapy przekazane jako pierwszy argument, make-composed-keymapale nie te przekazane jako drugi. Myślę, że powinieneś M-x report-emacs-bugi poprosić o make-composed-keymapzaakceptowanie listy map klawiszy jako drugiego argumentu, więc możesz to zrobić

(make-composed-keymap nil (list erc-mode-map markdown-mode-map))
Stefan
źródło