/ / Dlaczego nie mogę zmienić skrótów klawiszowych - emacs, skróty klawiaturowe, elisp, paredit

Dlaczego nie mogę zmienić skrótów klawiaturowych - emacs, skróty klawiaturowe, elisp, paredit

Próbuję użyć tylko kilku funkcji z paredit, bez ładowania wszystkich skrótów klawiszowych. Patrząc na paredit.el, jedyną mapą, którą znalazłem, była mapa trybu paredit, więc spróbowałem tego.

(setq paredit-mode-map (make-sparse-keymap))
(define-key paredit-mode-map (kbd "<C-M-left>") "paredit-backward)

Nie zmienił on przypisania klawiszy (jak sprawdzono za pomocą C-h k), ale zmieniono zmienną mapę trybu kredytu-mapy.

Próbowałem też

(eval-after-load "paredit"
"(progn
(setq paredit-mode-map (make-sparse-keymap))
(define-key paredit-mode-map (kbd "<C-M-left>") "paredit-backward)))

a następnie włączanie i wyłączanie paredit, z tym samym rezultatem.

Wcześniej wprowadzanie zmian w mapie klawiszy zawsze działało dla mnie. Co tu się dzieje?

Edytować:

Zmieniłem mapę klawiszy, wykonując następujące czynności:

; Remove old paredit bindings
(defun take-from-list (condp list)
"Returns elements in list satisfying condp"
(delq nil
(mapcar (lambda (x) (and (funcall condp x) x)) list)))
(setq minor-mode-map-alist
(take-from-list
(lambda (x) (not (eq (car x) "paredit-mode)))
minor-mode-map-alist))

; Create new paredit-mode-map
(setq paredit-mode-map (make-sparse-keymap))
(define-key paredit-mode-map (kbd "<C-kp-enter>") "paredit-backward)

; Add the new paredit-mode-map to minor-mode-map-alist
(setq minor-mode-map-alist (append
(list (append (list "paredit-mode) paredit-mode-map))
minor-mode-map-alist))

Wygląda więc na to, że minor-mode-map-alist jest zmienną używaną do wyszukiwania. Jestem pewien, że istnieją bardziej eleganckie sposoby zmiany skrótów klawiszowych, ale chciałem dowiedzieć się więcej o tym, jak działają skróty klawiszowe w emacs.

Odpowiedzi:

4 dla odpowiedzi № 1

Paredit używa innego sposobu definiowania mapy klawiszy. Podczas gdy większość mniejszych trybów definiuje mapę klawiszy w definicji zmiennej, wywołania Paredit paredit-define-keys na Najwyższy poziom, a zatem siłą inicjuje mapę klawiszy.

Innymi słowy, nie można uniemożliwić Paredit skonfigurowania powiązań. Musisz usunąć wszystkie skróty klawiszowe w mapie klawiszy za pomocą (define-key paredit-mode-map … nil) aby się ich pozbyć.

Edytować: Nie można „zresetować” map klawiszy, przypisując nową mapę klawiszy do zmiennej. (setq paredit-mode-map …) zmieni zmienną paredit-mode-map, to będzie nie zmień rzeczywistą mapę klawiszy używaną w trybie Paredit.

Wiązanie tej zmiennej jest tylko oceniane po raz w czas definicji, tj. podczas oceny define-minor-mode. To makro wywołuje wewnętrznie add-minor-modei przechodzi do tej funkcji Bieżąca wartość zmiennej mapy klawiszy. Wszelkie przyszłe użycie trybu odnosi się tylko do tej mapy klawiszy. Zmienna mapy klawiszy to nigdy więcej oceniane w trybie drugorzędnym, a zatem zmiana jego wiązania nie ma żadnego wpływu.

Jeśli chcesz zmienić mapę klawiszy, musisz ponownie powiązać zmienną przed define-minor-mode jest oceniane, tj. przed załadowaniem odpowiedniej biblioteki. Zmieniając to w eval-after-load forma jest więc całkowicie bezużyteczna.

Zwykle zmiana zmiennej mapy klawiszy przed załadowaniem biblioteki działa dobrze, ponieważ większość trybów definiuje mapę klawiszy w treści defvar. defvar nie zmieni jednak wartości zmiennej, jeśli ma ona już wartość. Zatem, jeśli zmienna ma już mapę klawiszy, nie zostanie dotknięta.

Jednak, jak powiedziałem, Paredit nie przestrzega tego wzorca i zamiast tego na siłę dodaje swoje powiązania do mapy klawiszy. W ten sposób zmiana jest bezcelowa, ponieważ Paredit i tak doda swoje powiązania.

Jak powiedziałem, musisz ręcznie wyczyścić istniejącą mapę klawiszy, odznaczając każdy jej klucz.

TL; DR: Używaj Smartparens, naprawdę! Obejmuje całość Paredit, jest elastyczny, jest mocny, jest rozszerzalny, krótko mówiąc, jest po prostu dobry. I pozwala wybrać dowolne skróty klawiszowe.


3 dla odpowiedzi № 2

Najpierw przeczytaj odpowiedź Księżyca. To tylko wyjaśnienie.

co dokładnie jest zepsute w twoim kodzie

(setq paredit-mode-map (make-sparse-keymap))

To nie będzie działać w żadnym trybie już załadowanym. paredit nie jest wyjątkowy.

Brak szacunku Paredta wobec defvar oznacza, że ​​bardzo trudno jest go rozwiązać wszystkie klucze, jak chcesz.


3 dla odpowiedzi nr 3

Dlaczego po prostu nie stworzysz własnego mniejszego trybu? Wszystko, co robi Tryb Paredit, zapewnia powiązania klawiszy, więc jeśli zablokujesz jego mapę klawiszy, nie zrobi to za Ciebie. Polecenia paredit są dostępne niezależnie od tego, czy używasz trybu Paredit, czy nie. (Nikt nie „wymusza” na tobie przypisywania klawiszy!)

(defvar snowape-mode-map (make-sparse-keymap))
(define-minor-mode snowape-mode
"Minor mode for snowape"s favorite pareditoid key bindings.
\<snowape-mode-map>"
:lighter " Snowape")
(define-key snowape-mode-map (kbd "C-M-<left>") "paredit-backward)
...

Alternatywnie możesz po prostu użyć local-set-key w trybach ulubionych:

(add-hook "lisp-mode-hook
(defun lisp-mode-snowape-setup ()
(local-set-key (kbd "C-M-<left>") "paredit-backward)))