2013-06-19 9 views
11

Diciamo che mi legano la chiave per una certa funzione come segue:Come scrivere un binding di tasti in emacs per una facile ripetizione?

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

Ora, voglio la chiave di rilegatura a lavorare come:
Dopo premo C-c = per la prima volta, se voglio ripetere la funzione-foo, non è necessario premere nuovamente C-c, ma semplicemente ripetere premendo =. Quindi, dopo aver chiamato la funzione-foo per un numero di volte sufficiente, posso semplicemente premere i tasti diversi da = (o premere esplicitamente C-g) per uscire.

Come fare questo?

+1

Hai familiarità con il comando 'repeat'? È legato a 'C-x z' e può essere usato per ripetere il comando precedente. Ripete quel comando ogni volta che premi 'z'. – mk1

+1

@ mk1 conosco C-x z, mi chiedo solo se posso creare i miei binding di tasti che funzionano in questo modo ... comunque, grazie per i tuoi commenti – shelper

+0

'C-x e' per l'esecuzione di macro di tastiera ha il comportamento desiderato. Se l'implementazione di quell'associazione si trova nell'elite da qualche parte, ciò potrebbe essere un inizio nello scrivere il proprio binding. – pcurry

risposta

12

Questa potrebbe essere la cosa che stai cercando:

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

Si desidera il function-foo per utilizzare set-temporary-overlay-map.

7

C'è un pacchetto smartrep.el che fa esattamente quello che ti serve. La documentazione è un po 'scarsa, ma puoi capire come dovrebbe essere utilizzata esaminando numerose configurazioni di emacs trovate su github. Per esempio (tratto da here):

(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)))) 
+0

Non sembra essere stato specificato da nessuna parte in modo esplicito, ma ho scoperto che 'C-g 'esce dalla modalità di ripetizione. –

4

Questo è quello che uso. Mi piace perché non devi specificare la chiave di ripetizione.

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

Mi piace molto, ma nota che CMD * deve * essere già caricato (l'autoloading è insufficiente), altrimenti gli interrogatori arglist e in forma interattiva falliranno. (In realtà il secondo * dovrebbe * innescare il caricamento automatico, ma l'arglist che lo precede sarà errato). – phils

0

In aggiunta a quanto suggerito @juanleon, che utilizza set-temporary-overlay-map, qui è un'alternativa che io uso un po '. Utilizza la libreria standard 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))) 

Da utilizzare per definire diversi comandi ripetibili. Per esempio,

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

quindi associare un tale comando a un tasto con un suffisso ripetibile, per esempio, C-c = (per C-c = = = = ...)

Vedi this SO post per ulteriori informazioni.

Problemi correlati