У меня есть незначительный режим. Если тот режим активен, и пользователь поражает DEL, я хочу сделать некоторое действие, но только если некоторое условие содержит. Если условие содержит, и действие выполняется, я хочу ничего не сделать больше после этого. Но если условие перестало работать, я не хочу делать что-либо и позволять действию DEL по умолчанию выполниться.
Не уверенный, как я мог решить это. Но я предполагаю, что мог сделать это двумя способами:
1) Я мог снова переплести клавишу DEL к функции в незначительном режиме и затем проверить, содержат ли условия ot нет. Но затем как я знаю, какова команда по умолчанию к DEL?
2) Я мог добавить пред рычаг команды как это. Выполните команду и затем повредите цепочку. Но как я повреждаю цепочку?
(add-hook 'pre-command-hook
(lambda()
(when (equal last-input-event 'backspace)
;; Do something and then stop (do not execute the
;; command that backspace is bound to)
)))
Каким образом Вы решили бы его?Спасибо!
Чтобы сделать это, временно отключите второстепенный режим, а затем найдите привязку клавиш.
Представьте, что вы связали служебное задание
с DEL . Тогда это поможет (при условии, что условие, которое вы хотите активировать, это (backspace, равное последнему событию ввода))
:
(defun do-thingy ()
"Do something, unless last event was backspace."
(interactive)
(if (equal last-input-event 'backspace)
(let* ((my-minor-mode nil)
(original-func (key-binding (kbd "DEL"))))
;; original-func is whatever DEL would be if
;; my-minor-mode were disabled
(call-interactively original-func))
(message "Here's my minor mode behavior!")))
Примечание: это поведение предполагает, что вы настроили свой ключ bindings стандартным способом для второстепенного режима . В частности, вы должны добавить свою раскладку в переменную minor-mode-map-alist
, добавив элемент ( my-minor-mode. my-minor-mode-keymap)
. Вот как работает приведенный выше оператор let
, он ищет нужную привязку с временно отключенным режимом.
используйте define-minor-mode
, чтобы определить свой второстепенный режим, раскладка автоматически настраивается "правильным образом".
Похоже, нет надежного способа делать то, что вы хотите. Если ваша новая команда привязана к DEL, то все, что было привязано к DEL раньше в текущей раскладке, больше не существует. Другой предложенный вами подход не будет работать, потому что предварительные команды не препятствуют выполнению следующего действия. Вы также можете подумать о том, чтобы прервать дальнейшее выполнение с помощью ^ G (Keyboard-Quit), но это неконтролируемое прерывание, которое может остановить больше вещей, чем вы хотите.
Даже если вы сделаете процесс установки новой привязки немного более сложным, чем просто повторная привязка, и запомните, что было привязано там раньше, чтобы вы могли вызвать это позже, у вас действительно нет того, что вы ищете . Если кто-то хочет повторно привязать действие «по умолчанию», он должен сделать это, изменив вашу функцию, а не заменяя привязку клавиш.
То, что вы хотите сделать, не соответствует модели Emacs о том, как работает привязка клавиш.
Это то, что я использую в своем пакете smart-tab
, который делает именно это.
(defun smart-tab-default ()
"Indents region if mark is active, or current line otherwise."
(interactive)
(if mark-active
(indent-region (region-beginning)
(region-end))
(call-interactively
(or
;; Minor mode maps for tab (without smart-tab-mode)
(cdar (assq-delete-all 'smart-tab-mode (minor-mode-key-binding "\t")))
(cdar (assq-delete-all 'smart-tab-mode (minor-mode-key-binding [(tab)])))
(local-key-binding "\t")
(local-key-binding [(tab)])
(global-key-binding "\t")
(global-key-binding [(tab)])))))
А в команде smart-tab
(которая связана с табуляцией в второстепенном режиме
) она имеет следующее:
(if (smart-tab-must-expand prefix)
;; use smart tab
(smart-tab-default))
Сначала она проверяет, есть ли какие-либо привязки второстепенного режима для вкладки (не включая
smart-tab-mode
), затем локальные и, наконец, глобальные привязки клавиш.