Клавиши полуавтоматического редактирования/автоматического префикса
Большинство режимов emacs включают некоторый префикс для активации своих функций. Например, при использовании GUD "next" это "C-c C-n". Из этих режимов многие предоставляют специальные буферы, где можно использовать один ключ для активации некоторой функциональности (просто "n" или "p" для чтения следующей/предыдущей почты в GNUS, например).
Однако не все режимы предоставляют такой буфер, и многократное написание префикса может быть утомительным. Есть ли известный бит elisp, который позволит ad-hoc спецификации префиксных ключей быть перенесены на все входные данные в течение некоторого времени? (Например, до нажатия ESC или какого-либо другого санкционированного ключа)
Ответы
Ответ 1
Я согласен с Джо Касадонте в том, что путь - это определить свой собственный малый (или основной) режим.
Это, как говорится, ваш вопрос интересен.
Здесь предлагается решение, которое запрашивает последовательность клавиш и принимает префикс нажатия клавиш и продвигает эту раскладку на верхний уровень.
например. Предположим следующую раскладку:
M-g ESC Prefix Command
M-g g goto-line
M-g n next-error
M-g p previous-error
Когда вы запустите M-x semi-modal-minor-mode
, он предложит вам несколько нажатий клавиш. Если вы введете M-g n
, тогда будут установлены следующие привязки клавиш:
ESC Prefix Command (same as M-g ESC)
g goto-line
n next-error
p previous-error
Итак, теперь n
не вставляет самостоятельно, а переходит к следующей ошибке. См. Код ниже.
Примечание: если этот вспомогательный режим включен, <f12>
привязан к команде, которая отключает второстепенный режим. Это связано с тем, что привязки клавиш могут очень хорошо отключить ваш Emacs (например, что, если был новый keybinding для M-x
).
Отредактировано для добавления этих мыслей: переменная второстепенного режима была первоначально сделана буфером локальным, но это не работает, если вы также не создадите локальный переменный буфер minor-mode-alist (duh). Но вы также (возможно) не хотите эти привязки в минибуфере... Итак, я не собираюсь тестировать его b/c, это действительно зависит от того, что вы хотите, но я добавил комментарий к коду отражая эту мысль.
Без дальнейших церемоний:
(defvar semi-modal-minor-mode-keymap (make-sparse-keymap)
"keymap holding the prefix key keymapping, not really used")
(defvar semi-modal-minor-mode-disable-key (kbd "<f12>")
"key to disable the minor mode")
(defun semi-modal-minor-mode-disable ()
"disable the minor mode"
(interactive)
(semi-modal-minor-mode 0))
(define-minor-mode semi-modal-minor-mode
"local minor mode that prompts for a prefix key and promotes that keymap to the toplevel
e.g. If there are bindings like the following:
M-g ESC Prefix Command
M-g g goto-line
M-g n next-error
M-g p previous-error
And you enter 'M-g n' when prompted,
then the minor mode keymap has the bindings
g -> goto-line
n -> next-error
p -> previous-error
ESC -> Prefix Command (same as M-g ESC)
The variable semi-modal-minor-mode-disable-key is bound to disable the minor mode map.
This is provided because often the mappings make the keyboard unusable.
Use at your own risk."
nil " Semi" semi-modal-minor-mode-keymap
(make-local-variable 'semi-modal-minor-mode)
(make-local-variable 'minor-mode-map-alist)
(let ((pair-holding-keymap-to-modify (assq 'semi-modal-minor-mode minor-mode-map-alist)))
(setcdr pair-holding-keymap-to-modify (make-sparse-keymap))
(if semi-modal-minor-mode
(let (key
keymap)
;; all but last (b/c we want a prefix
(setq key (substring (read-key-sequence "Enter a full key combination, the prefix will be used: ") 0 -1))
(if (and (not (equal "" key))
(not (equal (kbd "C-g") key))
(let ((semi-modal-minor-mode nil))
(keymapp (setq keymap (key-binding key)))))
(progn
(setcdr pair-holding-keymap-to-modify (copy-keymap keymap))
(when semi-modal-minor-mode-disable-key
(define-key (cdr pair-holding-keymap-to-modify)
semi-modal-minor-mode-disable-key 'semi-modal-minor-mode-disable)))
(semi-modal-minor-mode 0))))))
Ответ 2
Определенная по модам (модальная?) часть привязок ключей в Emacs реализуется различными локальными картами, которые затмевают универсальную глобальную карту. Большинство основных и второстепенных режимов определяют собственные локальные карты; например, есть карта gud-mode. Связывание клавиш в локальной раскладке будет активироваться только тогда, когда текущий буфер находится в соответствующем режиме. Вы можете настроить специальную ключевую карту с помощью режима. Например, вы можете поместить этот фрагмент в свой файл ~/.emacs
(add-hook 'gud-mode-hook
(lambda ()
(local-set-key (kbd "C-n")
(lookup-key (current-local-map) (kbd "C-c C-n")))))
Подробнее о раскладках можно найти в справочном руководстве Elisp.
Ответ 3
Основная проблема здесь в том, что в настоящее время нет текущей раскладки клавиатуры. Там глобальная раскладка клавиатуры, которая переопределяется основной клавиатурой режима, которая, в свою очередь, переопределяется одним или несколькими малогабаритными ключевыми картами (и они могут наступать друг на друга определенным образом, я уверен). Определение нового основного режима по-прежнему оставит функциональные клавиши второстепенного режима, а определение нового второстепенного режима повлияет только на любые клавиши, которые вы определяете в макете с малым режимом.
Например, вы можете определить малый режим, который будет делать то, что вы хотите, до тех пор, пока активен второстепенный режим. Вы определяете новый второстепенный режим my-gud-mode
, который будет иметь свою собственную раскладку. Затем вам нужно будет определить все ваши сопоставления ключей для него (например, n, p и т.д.), И вам также необходимо будет определить все ключи, которые вы не хотите работать, для привязки к функции ignore
. Это настоящая боль этого, переназначая все остальные ключи. Однако малый режим легко включать и выключать; что преимущество.
Определение нового основного режима было бы проще при первом румянце, так как это позволит вам отменить более "текущую раскладку" за один снимок. Он должен отметить текущий основной режим в локальной-буферной переменной, чтобы его можно было восстановить позже, когда временный основной режим отключен. Но у вас все еще будут другие второстепенные режимы, вторгающиеся в вашу раскладку, поэтому он не будет "чистым".
То, что я делаю в этой ситуации, - это более простой префикс! Для вещей, которые я использую все время, весь день каждый день, я даю им функциональный ключ самостоятельно (например, у меня есть F1 в качестве ключа jabber-mode). Для менее сразу полезных вещей у меня есть две другие функциональные клавиши, отложенные F3 и F12 (я уверен, что была некоторая причина, по которой я выбрал их давно, но я больше не помню, почему). F3 определяет ключи, которые всегда доступны, независимо от основного режима. F12 определяет ключи, зависящие от основного режима. Некоторые примеры:
Я установил F3-m- в качестве префикса для переключения основных режимов (например, F3-mp переключается в режим cperl) и F3-M- в качестве префикса для второстепенных режимов (например, F3-Mv переключает режим просмотра), Они всегда доступны, поэтому вы можете сделать что-то вроде bind F3-g-, чтобы быть вашим префиксом gud, и ввести F3-g-p для предыдущего и т.д.
Моя клавиша F12 зависит от режима. Итак, в режиме DLC F12-e вызовет dired-nt-open-in-excel
в текущем файле, а в emacs- lisp -mode F12-e вызовет elint-current-buffer
. Почему-то я никогда не путаю их.
Если вам нужна помощь в определении таких ключевых карт, дайте мне знать.
Ответ 4
Режим Viper позволяет вам отображать команды на клавиши или последовательности клавиш, находясь в визуальном режиме (вводится с помощью клавиши "esc" ). Вернитесь в режим вставки с помощью "i".
Посмотрите viper-in-more-modes.el
Он использует viper-modify- основной режим.
Мне также нравится использовать файл viper-vi-global-user-map: из моего файла .emacs.