Глобальное переопределение привязки ключей в Emacs
как я могу установить привязку ключа, которая глобально переопределяет и имеет приоритет над всеми другими привязками для этого ключа? Я хочу переопределить все карты основных / второстепенных режимов и убедиться, что моя привязка всегда действует.
это конечно не работает:
(global-set-key "C-i" 'some-function)
он работает в text-mode, но когда я использую lisp-mode,C-i отскок к lisp-indent-line.
Я могу пройти и переопределить привязку в lisp-mode и в каждом другом режиме индивидуально, но должен быть более легкий путь. Каждый раз, когда я устанавливаю новый режим для нового типа файла, мне нужно будет вернуться и проверить, чтобы убедиться, что все мои привязки ключей не переопределяются новым режимом.
Я хочу сделать это, потому что я хочу эмулировать привязки, которые я уже изучил и укоренился от других редакторов.
8 ответов:
Я использую второстепенный режим для всех моих Привязок клавиш "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)это имеет дополнительное преимущество в том, чтобы отключить все мои модификации одним махом (просто отключить второстепенный режим) в случае, если кто-то другой управляет клавиатурой или если мне нужно увидеть, что делает привязка клавиш по умолчанию.
обратите внимание, что вам может потребоваться отключить это в минибуфере:
(defun my-minibuffer-setup-hook () (my-keys-minor-mode 0)) (add-hook 'minibuffer-setup-hook 'my-minibuffer-setup-hook)
как дополнение к scottfrazer это, Я написал следующее, чтобы мои привязки клавиш сохраняли приоритет, даже если впоследствии загруженные библиотеки приносят новые карты ключей.
потому что keymaps могут быть сгенерированы во время компиляции,
loadказалось, что лучшее место для этого.(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))))
установить
use-package, eval и вы сделали:(require 'bind-key) (bind-key* "C-i" 'some-function)
Я нашел этот вопрос при поиске "emacs undefine org mode keybindings", потому что я хотел развязать существующее поведение C-c C-b, чтобы позволить моей глобальной карте похоронить буфер для работы в буфере организации.
это оказалось самым простым решением для меня:
(add-hook 'org-mode-hook (lambda () (local-unset-key (kbd "C-c C-b"))))
хотя ответ скоттфразера-это именно то, что вы просили, я упомяну для потомков другое решение.
" не определяйте букву C-c как ключ в программах Lisp. Последовательности, состоящие из C-c и буквы (верхнего или нижнего регистра), зарезервированы для пользователей; они являются единственными последовательностями, зарезервированными для пользователей, поэтому не блокируйте их."
Если вы привязываете свои личные глобальные привязки к C-c плюс письмо, тогда вы "должны" быть в безопасности. Однако это всего лишь соглашение, и любой режим по-прежнему может переопределить ваши привязки.
Если вы хотите "всегда использовать привязки клавиш на карте, если я явно не переопределяю их для конкретной карты режима", и предполагая, что вы используете scottfrazier это вы хотите:
(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))Так
(locally-override "\C-i" nil)следует удалить привязку "\C-i " из второстепенного режима только в текущем буфере. Предупреждение: это полностью непроверено, но кажется правильным подходом. Точка установки родителя, а не просто справиться с глобальным значением my-keys-minor-mode-map-это то, что любые последующие изменения глобального значения автоматически отражаются в локальном значении.
Я не думаю, что вы можете. Это примерно равносильно тому, что вы хотите определить глобальную переменную, которая не может быть скрытой локальной переменной в функции. Сфера просто не работает таким образом.
тем не менее, может быть способ написать функцию elisp, чтобы пройти через список режимов и переназначить его в каждом из них для вас.
Если вы действительно хотите сделать это самостоятельно, вы должны проверить вокруг и увидеть, если кто-то уже сделал это.
существует пакет для Emacs, который дает ваши windows-подобные привязки клавиш. Вы должны быть в состоянии найти его через Google.
Comments