web-dev-qa-db-fra.com

Ignorer globalement la liaison de touches dans Emacs

Comment puis-je définir une liaison de clé qui remplace globalement et a priorité sur toutes les autres liaisons pour cette clé? Je veux remplacer toutes les cartes en mode majeur/mineur et m'assurer que ma liaison est toujours en vigueur.

Bien sûr, cela ne fonctionne pas:

(global-set-key "\C-i" 'some-function)

Cela fonctionne dans text-mode, mais quand j'utilise LISP-mode, C-i est rebondi à LISP-indent-line.

Je peux parcourir et remplacer cette liaison dans LISP-mode et dans tous les autres modes individuellement, mais il doit y avoir un moyen plus simple. Chaque fois que j'installe un nouveau mode pour un nouveau type de fichier, je dois revenir en arrière et vérifier que toutes mes liaisons de touches ne sont pas remplacées par le nouveau mode.

Je veux le faire parce que je veux émuler des liaisons que j'ai déjà apprises et ancrées dans d'autres éditeurs.

98
Brian Carper

J'utilise un mode mineur pour toutes mes raccourcis clavier "override":

(defvar my-keys-minor-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "C-i") 'some-function)
    map)
  "my-keys-minor-mode keymap.")

(define-minor-mode my-keys-minor-mode
  "A minor mode so that my key settings override annoying major modes."
  :init-value t
  :lighter " my-keys")

(my-keys-minor-mode 1)

Cela a l'avantage supplémentaire de pouvoir désactiver toutes mes modifications d'un seul coup (désactivez simplement le mode mineur) au cas où quelqu'un d'autre conduirait le clavier ou si j'ai besoin de voir ce que fait une liaison de touches par défaut.

Notez que vous devrez peut-être désactiver cette fonction dans le mini-tampon:

(defun my-minibuffer-setup-hook ()
  (my-keys-minor-mode 0))

(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup-hook)
147
scottfrazer

En plus de réponse de scottfrazer , j'ai écrit ce qui suit afin que mes raccourcis clavier restent prioritaires, même si les bibliothèques chargées par la suite apportent leurs propres keymaps.

Étant donné que les images clés peuvent être générées au moment de la compilation, load semblait être le meilleur endroit pour le faire.

(add-hook 'after-load-functions 'my-keys-have-priority)

(defun my-keys-have-priority (_file)
  "Try to ensure that my keybindings retain priority over other minor modes.

Called via the `after-load-functions' special hook."
  (unless (eq (caar minor-mode-map-alist) 'my-keys-minor-mode)
    (let ((mykeys (assq 'my-keys-minor-mode minor-mode-map-alist)))
      (assq-delete-all 'my-keys-minor-mode minor-mode-map-alist)
      (add-to-list 'minor-mode-map-alist mykeys))))
30
phils

Installer use-package , évaluez et vous avez terminé:

(require 'bind-key)
(bind-key* "C-i" 'some-function)
18
Mirzhan Irkegulov

J'ai trouvé cette question en recherchant "emacs undefine org mode keybindings", car je voulais dissocier le comportement C-c C-b existant pour permettre à ma carte globale d'enterrer le tampon pour fonctionner dans un tampon d'organisation.

Cela a fini par être la solution la plus simple pour moi:

(add-hook 'org-mode-hook
      (lambda ()
        (local-unset-key (kbd "C-c C-b"))))
14
Jay Doane

Bien que la réponse de scottfrazer soit exactement ce que vous avez demandé, je mentionnerai pour la postérité une autre solution.

De Le manuel Emacs :

"Ne définissez pas la lettre C-c comme une clé dans les programmes LISP. Les séquences composées de C-c et d'une lettre (majuscule ou minuscule) sont réservées aux utilisateurs; ce sont les seules séquences réservées aux utilisateurs, ne les bloquez donc pas."

Si vous liez vos liaisons globales personnelles à C-c plus une lettre, alors vous "devriez" être en sécurité. Cependant, ce n'est qu'une convention, et n'importe quel mode est toujours en mesure de remplacer vos liaisons.

12
Kirkland

Si vous voulez "toujours utiliser les raccourcis clavier dans la carte, sauf si je les remplace explicitement pour une carte de mode spécifique", et en supposant que vous utilisez approche de scottfrazier , vous voulez:

(defun locally-override (key cmd)
  (unless (local-variable-p 'my-keys-minor-mode-map)
    (set (make-variable-buffer-local 'my-keys-minor-mode-map)
         (make-sparse-keymap))
    (set-keymap-parent my-keys-minor-mode-map 
                       (default-value 'my-keys-minor-mode-map)))
  (define-key my-keys-minor-mode-map key cmd))

Alors

(locally-override "\C-i" nil)

devrait supprimer la liaison "\ C-i" du mode mineur dans le tampon actuel uniquement. Attention: ce n'est pas encore testé, mais cela semble être la bonne approche. Le point de définir le parent plutôt que de simplement copier la valeur globale de my-keys-minor-mode-map est que toute modification ultérieure de la valeur globale est automatiquement reflétée dans la valeur locale.

3
gbrunick

À moins que vous ne vouliez vraiment le faire vous-même, vous devriez vérifier et voir si quelqu'un d'autre l'a déjà fait.

Il existe un package pour Emacs qui donne vos raccourcis clavier de type Windows. Vous devriez pouvoir le trouver via google.

2
JesperE

Je ne pense pas que vous puissiez. Cela équivaut à peu près à dire que vous souhaitez définir une variable globale qui ne peut pas être masquée par les déclarations de variables locales dans les fonctions. La portée ne fonctionne tout simplement pas de cette façon.

Cependant, il pourrait y avoir un moyen d'écrire une fonction elisp pour parcourir la liste des modes et la réaffecter dans chacun d'eux pour vous.

2
T.E.D.