2012-06-13 11 views
9

È possibile riutilizzare l'intervallo di comandi ex in VIM?Riutilizzo dell'intervallo precedente in ex comandi in VIM

Per fare un esempio, posso scrivere (copia) linee 4 a 10 dal mio file corrente in un nuovo file utilizzando il seguente comando:

:4,10w foo/bar.txt 

Ma quello che voglio veramente fare è spostare le linee di un nuovo file. Posso farlo in questo modo:

:4,10w foo/bar.txt 
:4,10d 

Ma è un po 'fastidioso dover digitare 4,10 entrambe le volte.

Così ho due domande:

  1. Generalmente, C'è un modo per fare riferimento alla gamma precedentemente utilizzato in comandi ex?
  2. In particolare, se non c'è un modo per fare (1), esiste un modo più semplice per tagliare e incollare un numero di righe da un file a uno nuovo.

risposta

1

In genere, ciò che faccio è eliminare le righe da un file, passare all'altro file e incollare.

Inoltre, generalmente uso i marchi. Invece di digitare i numeri effettivi, ho colpito mb per contrassegnare la riga iniziale, quindi andare alla fine e premere d'b per eliminare nuovamente la riga contrassegnata come b. Ma è possibile utilizzare mb per segnare una linea di iniziare, e me per segnare una linea di fine, quindi eseguire un ex comando:

:'b,'e w somefile.txt<Enter> 

Naturalmente è possibile utilizzare tutte le lettere da a attraverso z per i vostri marchi; Di solito uso b e e ma puoi usare quello che ti piace.

Come faccio a spostare le linee:

m'b 
<navigate to end line> 
d'b 
:n somefile.txt<Enter> 
p 
Ctrl+^ 

Ctrl +^passa dal file aperto corrente al file aperto precedente. (Si potrebbe anche solo aprire un riquadro e passare ai riquadri, se preferisci. I riquadri non funzionano in chiaro vi, ma funzionano in vim.)

Quanto sopra presuppone che sia stata impostata l'opzione autowrite. Con autowrite, il comando :n e Ctrl +^scrivono entrambi il file corrente e quindi cambiano file, invece di lamentarsi che il file è stato modificato senza che lo si salvi. Puoi anche fare quanto sopra e solo scrivere esplicitamente il file prima di usare :n o Ctrl + ^.

A proposito, io uso Ctrl +^così tanto che l'ho mappato su K. Più facile da digitare, ma mi sono abituato a quell'abitudine molto tempo fa, quando a volte dovevo usare un terminale stupido che non poteva digitare Ctrl + ^.

A proposito, quando si eliminano le righe, vanno nel "buffer senza nome". In vim, il buffer senza nome viene conservato quando si cambiano i file. Nel vi originale, il buffer senza nome viene cancellato. Quindi quanto sopra non funzionerà con il vecchio vi. Puoi farlo funzionare cancellando in un buffer denominato, quindi incollando dal buffer specificato; che funziona in qualsiasi versione di vi.

m'b 
<navigate to end line> 
"ad'b 
:n somefile.txt<Enter> 
"ap 
Ctrl+^ 

È possibile che questo cancella nel buffer di nome a, poi paste dal a nell'altro file. Questo naturalmente funziona naturalmente; è solo che non ne hai bisogno.

4

Non sono a conoscenza di una risposta a (1), ma per rispondere a (2), ci sono diversi modi per farlo che non richiedono la riselezione manuale delle linee. In modalità visiva questo funzionerà:

4GV10G 
:w foo/bar.txt 
gvd 

perché gv riseleziona la selezione precedente, che è quasi quello che si vuole, senza l'utilizzo di una gamma ex.

Ma si può solo accendere il problema sulla sua testa, e provare:

:4,10d 
:sp foo/bar.txt 
pZZ 

per tagliare, poi incollare in un nuovo file, quindi chiuderlo.

0

È possibile eseguire prima la cancellazione, quindi aprire una nuova scheda e incollare il contenuto, quindi :4,10d, quindi :tabe foo/bar.txt, seguito da p ... suona meglio?

3

Altro che usare la storia Vim (:cursore su, q:) e rimuovendo il comando precedente in modo che solo la gamma è tenuto, non c'è modo di riutilizzare l'ultimo intervallo, nessuna variabile magia.

Se ho usato questa combinazione linee spostare più spesso, vorrei scrivere un comando personalizzato per esso:

command! -bang -range -nargs=1 -complete=file MoveWrite <line1>,<line2>write<bang> <args> | <line1>,<line2>delete _ 

è necessario specificare l'intervallo di una sola volta e risparmiare digitazione.

È possibile scrivere qualcosa come questo anche per altre combinazioni. La sfida principale è specificare tutti gli attributi del comando (bang, range, completamento) e, più tardi, ricordare il nome del comando personalizzato.

2

Ecco una mappatura della riga di comando che consente di raggiungere questo obiettivo. L'ho associato a CTRL-G CTRL-U, poiché esegue un'azione simile a CTRL-U. (Ma si può cambiare la situazione, naturalmente!)

" c_CTRL-G_CTRL-U Remove all characters between the cursor position and 
"   the closest previous |:range| given to a command. When 
"   directly after a range, remove it. 
"   Useful to repeat a recalled command line with the same 
"   range, but a different command. 
let s:singleRangeExpr = '\%(\d\+\|[.$%]\|''\S\|\\[/?&]\|/[^/]*/\|?[^?]*?\)\%([+-]\d*\)\?' 
let s:rangeExpr = s:singleRangeExpr.'\%([,;]'.s:singleRangeExpr.'\)\?' 
let s:upToRangeExpr = '^\%(.*\\\@<!|\)\?\s*' . s:rangeExpr . '\ze\s*\h' 
" Note: I didn't take over the handling of command prefixes (:verbose, :silent, 
" etc.) to avoid making this overly complex. 
function! s:RemoveAllButRange() 
    let l:cmdlineBeforeCursor = strpart(getcmdline(), 0, getcmdpos() - 1) 
    let l:cmdlineAfterCursor = strpart(getcmdline(), getcmdpos() - 1) 

    let l:upToRange = matchstr(l:cmdlineBeforeCursor, s:upToRangeExpr) 
    if empty(l:upToRange) 
     return getcmdline() 
    else 
     call setcmdpos(strlen(l:upToRange) + 1) 
     return l:upToRange . l:cmdlineAfterCursor 
    endif 
endfunction 
cnoremap <C-g><C-u> <C-\>e(<SID>RemoveAllButRange())<CR> 
1

Si può anche fare qualcosa di simile per scrivere il contenuto del registro anonimo file2.txt

:4,10d | :call writefile(split(@@, "\n", 1), 'file2.txt') 
5

io di solito uso gatto a fare questo:

:4,10!cat > foo/bar.txt 

questo funziona perché si sta convogliando le linee attraverso il gatto e la loro sostituzione con l'output risultante, che non è niente. E ovviamente puoi aggiungere alla fine di un file esistente facendo >> invece di>.

+0

Questo è un modo interessante per gestirlo! Tipo di elegante. – steveha