Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

Там 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))))

Ответ 3

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

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

Ответ 4

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

Ответ 5

В дополнение к предложению @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 = = = =...)

Подробнее см. этот пост..