Глобальное переопределение привязки ключей в Emacs - PullRequest
94 голосов
/ 25 марта 2009

Как я могу установить привязку ключа, которая глобально переопределяет и имеет приоритет над всеми другими привязками для этого ключа? Я хочу переопределить все карты основных / второстепенных режимов и убедиться, что моя привязка действует всегда.

Это, конечно, не работает:

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

Это работает в text-mode, но когда я использую lisp-mode, C-i восстанавливается до lisp-indent-line.

Я могу пройти и переопределить эту привязку в lisp-mode и в любом другом режиме индивидуально, но должен быть более простой способ. Каждый раз, когда я устанавливаю новый режим для нового типа файла, мне приходится возвращаться назад и проверять, чтобы все мои привязки клавиш не переопределялись новым режимом.

Я хочу сделать это, потому что я хочу подражать привязкам, которые я уже изучил и укоренил в других редакторах.

Ответы [ 8 ]

140 голосов
/ 26 марта 2009

Я использую второстепенный режим для всех моих «переопределенных» привязок клавиш:

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

Это дает дополнительное преимущество, заключающееся в том, что я могу отключить все мои модификации одним махом (просто отключить второстепенный режим) в случае, если кто-то другой управляет клавиатурой или если мне нужно посмотреть, как работает связывание клавиш по умолчанию. 1004 *

Обратите внимание, что вам может потребоваться отключить это в минибуфере:

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

(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup-hook)
30 голосов
/ 17 марта 2011

В качестве дополнения к ответу scottfrazer я написал следующее, чтобы мои сочетания клавиш сохраняли приоритет, даже если впоследствии загруженные библиотеки вводят новые собственные сопоставления клавиш.

Поскольку сопоставления клавиш могут быть сгенерированы во время компиляции, 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))))
16 голосов
/ 12 декабря 2014

Установка use-package, eval и все готово:

(require 'bind-key)
(bind-key* "C-i" 'some-function)
14 голосов
/ 06 мая 2014

Я нашел этот вопрос при поиске «emacs undefine key orbindings режима org», потому что я хотел отсоединить существующее поведение C-c C-b, чтобы позволить моей глобальной карте скрыть буфер для работы в буфере org.

Это оказалось самым простым решением для меня:

(add-hook 'org-mode-hook
      (lambda ()
        (local-unset-key (kbd "C-c C-b"))))
12 голосов
/ 18 ноября 2009

Хотя ответ Скоттфразера именно то, что вы просили, я упомяну для потомков другое решение.

С Руководство по Emacs :

"Не определяйте букву Cc как ключ в программах на Лиспе. Последовательности, состоящие из Cc и буквы (в верхнем или нижнем регистре), зарезервированы для пользователей; они являются единственными последовательностями, зарезервированными для пользователей, поэтому не блокируйте их . "

Если вы связываете свои личные глобальные привязки с C-c плюс буквой, то вы «должны» быть в безопасности. Тем не менее, это всего лишь соглашение, и любой режим все еще может переопределять ваши привязки.

3 голосов
/ 18 апреля 2013

Если вы хотите «всегда использовать привязки клавиш на карте, если я не переопределю их явно для конкретной карты режимов», и при условии, что вы используете подход 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, заключается в том, что любые последующие изменения глобального значения автоматически отражаются в локальном значении.

2 голосов
/ 26 марта 2009

Если вы действительно не хотите делать это самостоятельно, вам следует проверить и проверить, сделал ли это кто-нибудь еще.

Существует пакет для Emacs, который дает ваши привязки клавиш в стиле Windows. Вы должны быть в состоянии найти его через Google.

2 голосов
/ 26 марта 2009

Не думаю, что ты можешь. Это примерно эквивалентно тому, что вы хотите определить глобальную переменную, которая не может быть скрыта объявлениями локальных переменных в функциях. Сфера просто так не работает.

Однако может быть способ написать функцию elisp, чтобы просмотреть список режимов и переназначить ее для каждого из вас.

...