Emacs резервная привязка ключей - PullRequest
10 голосов
/ 22 марта 2010

У меня есть второстепенный режим. Если этот режим активен и пользователь нажимает DEL, я хочу сделать какое-то действие, но только если выполняется какое-то условие. Если условие выполнено и действие выполнено. Я больше ничего не хочу делать после этого. Но если условие не выполняется, я не хочу ничего делать и позвольте выполнению действия DEL по умолчанию.

Не уверен, как я мог решить это. Но, думаю, я мог бы сделать это двумя способами:

1) Я мог бы привязать клавишу DEL к функции в вспомогательном режиме, а затем проверьте, если условия не выполняются. Но тогда откуда мне знать, что команда по умолчанию для DEL?? 1007 *

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

Как бы вы решили это? Спасибо!

Ответы [ 3 ]

12 голосов
/ 22 марта 2010

Способ сделать это - временно отключить ваш второстепенный режим, а затем найти привязку клавиш.

Представьте, что вы связали 'do-thingy с DEL . Тогда это сделает свое дело (при условии, что условие, которое вы хотите вызвать, является (equal last-input-event '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!")))

Примечание. В этом поведении предполагается, что вы настроили привязки клавиш стандартным способом, которым минорный режим будет . В частности, вы должны добавить свою таблицу ключей в переменную minor-mode-map-alist, добавив элемент (my-minor-mode . my-minor-mode-keymap). Вот как работает вышеприведенный оператор let, он ищет нужную привязку с временно отключенным режимом.

Если вы используете define-minor-mode для определения своего второстепенного режима, раскладка клавиатуры автоматически настраивается на «правильный путь».

2 голосов
/ 22 марта 2010

Это то, что я использую для моего пакета 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), затем для локальных и, наконец, глобальных привязок клавиш.

0 голосов
/ 22 марта 2010

Кажется, нет способа сделать то, что вы хотите, надежно. Если ваша новая команда привязана к DEL, то того, что ранее было привязано к DEL в текущей раскладке, больше не существует. Другой предложенный вами подход не сработает, потому что предварительные командные хуки не мешают выполнению следующих действий. Вы также можете подумать о том, чтобы прервать дальнейшее выполнение с помощью ^ G (Keyboard-Quit), но это неконтролируемое прерывание, которое может остановить больше вещей, чем вы хотите.

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

То, что вы хотите сделать, не соответствует модели Emacs о том, как работает привязка клавиш.

...