Как написать привязки клавиш в Emacs для легкого повторения?

Позволять'скажем, я привязываю ключ к определенной функции следующим образом:

(global-set-key (kbd "C-c =") 'function-foo)

Теперь я хочу, чтобы привязка клавиш работала как:

После того, как я нажимаюC-c = в первый раз, если я хочу повторить функцию-foo, я нене нужно нажиматьC-c снова, но просто повторите нажатие=, Затем, после того, как я вызову функцию-foo в течение достаточного времени, я могу просто нажать клавиши, кроме= (или явно нажмитеC-g) чтобы выйти.

Как это сделать?

 pcurry26 июн. 2013 г., 05:25
C-x e для выполнения клавиатурных макросов имеет желаемое поведение. Если реализация этой привязки находится где-то в elisp, это может стать началом написания вашей собственной привязки.
 shelper20 июн. 2013 г., 01:36
@ mk1 я знаю C-x z, мне просто интересно, смогу ли я сделать свои собственные привязки клавиш, которые работают таким образом ... в любом случае, спасибо за ваши комментарии
 mk119 июн. 2013 г., 23:41
Вы знакомы сrepeat команда? Это связано сC-x z и вы можете использовать его, чтобы повторить предыдущую команду. Эта команда повторяется при каждом нажатии.z

Ответы на вопрос(5)

Это то, что я использую. Мне это нравится, потому что ты ненужно указать повторяющийся ключ.

(require 'repeat)
(defun make-repeatable-command (cmd)
  "Returns a new command that is a repeatable version of CMD.
The new command is named CMD-repeat.  CMD should be a quoted
command.

This allows you to bind the command to a compound keystroke and
repeat it with just the final key.  For example:

  (global-set-key (kbd \"C-c a\") (make-repeatable-command 'foo))

will create a new command called foo-repeat.  Typing C-c a will
just invoke foo.  Typing C-c a a a will invoke foo three times,
and so on."
  (fset (intern (concat (symbol-name cmd) "-repeat"))
        `(lambda ,(help-function-arglist cmd) ;; arg list
           ,(format "A repeatable version of `%s'." (symbol-name cmd)) ;; doc string
           ,(interactive-form cmd) ;; interactive form
           ;; see also repeat-message-function
           (setq last-repeatable-command ',cmd)
           (repeat nil)))
  (intern (concat (symbol-name cmd) "-repeat")))
 phils30 дек. 2013 г., 08:05
Мне это очень нравится, но учтите, что CMDдолжен уже загружен (автозагрузка недостаточна), иначе запросы arglist и интерактивной формы завершатся неудачно. (На самом деле последнийбыло бы вызвать автозагрузку, но предшествующий ей арглист будет неверным).

В дополнение к тому, что предложил @juanleon, который используетset-temporary-overlay-mapВот альтернатива, которую я использую совсем немного. Он использует стандартную библиотеку.repeat.el

;; This function builds a repeatable version of its argument COMMAND.
(defun repeat-command (command)
  "Repeat COMMAND."
 (interactive)
 (let ((repeat-previous-repeated-command  command)
       (last-repeatable-command           'repeat))
   (repeat nil)))

Используйте это, чтобы определить различные повторяемые команды. Например.,

(defun backward-char-repeat ()
  "Like `backward-char', but repeatable even on a prefix key."
  (interactive)
  (repeat-command 'backward-char))

Затем свяжите такую команду с ключом с повторяющимся суффиксом, например,C-c = (заC-c = = = =...)

Увидетьэтот ТАК пост для дополнительной информации.

Там'сsmartrep.el пакет, который делает именно то, что вам нужно. Документация немного скудная, но вы можете понять, какПредполагается использовать его, просматривая многочисленные конфиги emacs, найденные на github. Например (взято изВот):

(require 'smartrep)
(smartrep-define-key
    global-map "C-q" '(("n" . (scroll-other-window 1))
                       ("p" . (scroll-other-window -1))
                       ("N" . 'scroll-other-window)
                       ("P" . (scroll-other-window '-))
                       ("a" . (beginning-of-buffer-other-window 0))
                       ("e" . (end-of-buffer-other-window 0))))
 Adam Spiers29 янв. 2014 г., 17:11
Это неКажется, это нигде не указано явно, но я обнаружил, что `C-g ' выходит из режима повтора.
Решение Вопроса

Это может быть то, что вы ищете:

(defun function-foo ()
  (interactive)
  (do-your-thing)
  (set-temporary-overlay-map
    (let ((map (make-sparse-keymap)))
      (define-key map (kbd "=") 'function-foo)
      map)))

Вы хотите, чтобы вашfunction-foo использовать .set-temporary-overlay-map

Ваш ответ на вопрос