2009-10-02 15 views
40

Stavo leggendo questo articolo su come creare macro vi: vi sequence macro e ho visto una macro utile per creare una sequenza nel buffer.Emacs macro per generare una sequenza?

1.
2.
...
100.

Nel VI, il trucco è che si può premere Ctrl-a al di sopra di un numero e si aggiungerà uno ad esso, quindi questo ha reso facile la macro. Voglio essere in grado di fare la stessa cosa in emacs.

risposta

56

Se si utilizza Emacs 23 (e forse 22?), Utilizzare kmacro-insert-counter che è associato a C-x C-k TAB per impostazione predefinita. Così, per il tuo esempio, faresti:

C-x (C-x C-k TAB . RET C-x)

in modo da iniziare macro, inserire contatore seguito da, a capo, macro fine ''. Quindi C-x e e e e e e e ecc. Oppure M-1 0 0 C-x e per ottenerne 100.

EDIT:

dimenticato di dire è possibile impostare il contatore ad un valore iniziale anche. Ad esempio, per iniziare a 1 invece di 0, fare M-1 C-x C-k C-c.

E se non si desidera incrementare il contatore in un punto particolare, è necessario aggiungerlo a C-u. Ovviamente a questo punto le sequenze di tasti diventano un po 'ridicole, quindi di solito lego una chiave per inserire, ma non aumentare.

+1

ancora di attualità: 'kmacro-set-counter Cx Ck cc' ' kmacro-aggiunge -contro Cx Ck Ca' 'kmacro-insert-counter Cx Ck TAB' Quindi l'idea è, impostare il contatore. Quindi definire la macro e all'interno della macro inserire e incrementare il contatore. Quindi eseguire ripetutamente la macro. Questo potrebbe essere stato ovvio per altri lettori, ma inizialmente non l'ho capito. – Cheeso

17

Emacs 23 supporta frammenti di elisp nel testo di sostituzione di replace-regexp.

Mi capita spesso definisco macro della tastiera che seguono questo schema:

  • copia un blocco di testo
  • Passare a un numero che voglio incrementare nel blocco copiato del testo con isearch
  • Attivare il contrassegnare e spostare il punto per definire una regione che comprende il numero
  • Mx replace-regexp
  • Al prompt "Sostituire regexp", immettere \([0-9]+\) per acquisire un gruppo o f uno o più cifre
  • Al "regexp Sostituire ([0-9] +) con:" richiesta, inserire \,(1+ \#1), dove , indica che una forma elisp di sostituire segue, 1+ è una funzione di incremento, e \#1 è il primo testo della partita catturato, interpretato come un numero.

Dopo aver preso un minuto per definire la macro di tastiera, questo mi permette di avere quasi la comodità di taglia e incolla per generare un sacco di blocchi di codice quasi identico, come ad case dichiarazioni.

Si noti che questa tecnica può essere facilmente adattata ad es. numeri doppi (\,(* 2 \#1)) o qualsiasi altra cosa. Puoi anche usarlo per sostituire l'elemento successivo in una sequenza arbitraria usando una combinazione di 'position e 'nth, ma non entrerò in quello ora :).

+1

grazie per aver dimostrato come usare replace-regexp per sostituire un contatore per il testo –

+0

'\, (eval-expression)' è molto pulito in query replace regexps! Ho dovuto rinumerare una sequenza di numeri in apice a partire da 1. Erano tutti in tag SMF '[sup]', iniziando con 63. Così ho fatto questa query sostituire regexp per avviarli da 1: '(default \ [sup \] [0-9] + \ [\/sup \] '→' [sup] \, (kmacro-insert-counter 1) [/ sup] '. Tuttavia, li ha sostituiti con qualcosa come [sup] Nuovo contatore macro value: 1 (1) [/ sup] 00 ". Come potrei risolvere questo problema (oltre a regexare quel testo extra)? – Geremia

+1

@Geremia: Ecco cosa dovevo fare:' C'-':' '(setq kmacro- contatore 0) 'e quindi:' \ [sup \] [0-9] + \ [\/sup \] '→' [sup] \, (stampa (setq kmacro-counter (1+ kmacro-counter)))) ' – Geremia

1

C'è anche:

C-u M-! jot -s '.C-q C-j' 10

Non è pura elisp, ma ha lo stesso effetto. Potresti scrivere una macro nominata per eseguirla per te.

+1

dove posso trovare il comando jot? –

+0

'jot' e 'seq' fanno la stessa cosa per questi scopi.Se sei su Unix, quasi sicuramente ne hai almeno uno installato.q –

51

coloro che si sentono ci sono troppi trucchi per memorizzare potrebbe trovare l'acquisizione di alcuni elisp più redditizio:

 
M-: (dotimes (i 20) (insert (format "%2d.\n" (1+ i)))) 
+6

+1 per menzionando 'M-:' ('eval-expression'), non ne ho mai sentito parlare –

+0

@ TörökGábor' \, (eval-expression) 'è pulito in anche la query sostituisce regexps. – Geremia

3

Se si accende il modo minore CUA (cua-mode), è possibile selezionare una colonna di testo e poi riempirlo con una sequenza di numeri usando cua-sequence-rectangle (associato a M-n per impostazione predefinita).

Questa è la stessa cosa menzionata nel video di Török Gábor, ma ora è scritta qui in modo da non dover guardare l'intero video a meno che non lo si voglia. È un bel video

+4

Vale anche la pena notare che in questi giorni non è necessario 'cua-mode' * per numerare un rettangolo - dal 24.1 esiste una normale operazione di rettangolo' rettangolo-numero-linee' legata a 'C-x r N'. (* o 'cua-selection-mode', che è sicuramente l'opzione preferibile per coloro che non usano' cua-mode' come standard.) – phils

+2

Posso anche collegarmi a [emacs string-insert-rectangle vector di numeri ?] (http://stackoverflow.com/a/9932745/324105) pure. – phils

9

Dal rilascio 24,3 dell'Emacs (ritengo effettivamente dal rilascio 24,0), la sequenza di tasti è stata semplificata:

<F3> <F3> . <ENTER> <F4>

Poi ripetendo <F4> chiave ripeterà la macro.

Il trucco è che, dopo aver iniziato una macro con <F3>, un secondo <F3> premere il tasto inserirà il valore corrente del contatore della macro tastiera nel buffer, e incrementa il contatore di 1.

Altri trucchi:

  • <F3> C-u 2 <F3> . <ENTER> <F4> sarà incrementato con due (invece di +1)
  • C-u 100 <F3> <F3> . <ENTER> C-u 50 <F4> avrà inizio alle 100 e terminano alle 149
  • C-x C-k C-f %03d <ENTER> <F3> <F3> . <ENTER> <F4> si bloccherà con zero come "000"

fonte: sezione Keyboard Macro Counter nel manuale Emacs.

+2

Per preimpostare il contatore, è sufficiente un prefisso numerico arg. ad es .: 'C-u 100 . RET '. Un argomento prefisso a '' dice quante volte ripetere la macro (compresa la registrazione), quindi per contare da 100 a 149 immediatamente si potrebbe finire con 'C-u 50 ' invece di solo ''. – phils

+0

Grazie phils. Ho migliorato la mia risposta (e conoscenza) con i tuoi commenti. – thdox

+0

'F3 F3 X F4' è un ** enorme ** miglioramento rispetto a' Cx (Cx CK TAB X Cx) 'in termini di facilità d'uso per una macro throwaway - e ora non devo venire qui perché io ho dimenticato la combinazione di acrobazie principali. Spero che questa risposta salirà in alto, a cui appartiene. –

0

È possibile utilizzare shell-command-on-region altrimenti:

C-u M-! seq 1 100|xargs -I{} echo {}"." 
0

Ecco un semplice defun per questo:

(defun insert-range (START END &optional STEP FORMAT) 
    "Inserts a range of integers from START to END with STEP (default to 1) 
in a given format (default to \"\\n%d\")" 
    (interactive 
    (list (read-number "Start: " 1) 
     (read-number "End: " 10) 
     (read-number "Step: " 1) 
     (read-string "Format (default to \"\\n%d\"): " nil nil "\n%d"))) 
    (dotimes (i (1+ (/ (- END START) STEP))) 
    (insert (format FORMAT (+ START (* i STEP)))) 
) 
) 
Problemi correlati