2011-09-23 10 views
10

Utilizzo di Vim Sono davvero un fan della modalità visiva che consente di inserire del testo prima di una colonna.Inserimento del rientro per le colonne in Vim

Inserire alcuni spaziatura dopo le frecce,

> one 
> two 
> three 

può essere realizzata tramite <Ctrl-V>jjI <Esc>:

> one 
> two 
> three 
  • vai alla modalità visiva <Ctrl-V>,
  • estendono selezione visuale jj,
  • inserire alcuni spazi I__,
  • propagare la modifica a tutte le linee di selezione visuale a blocchi <Esc>

Ora ho un file di testo che ha bisogno di qualche formattazione. Questo è ciò che sembra:

start() -- xxx 
initialize() -- xxx 
go() -- xxx 

Ora voglio allineare parte di questo testo per organizzare in colonne in questo modo:

start()  -- xxx 
initialize() -- xxx 
go()   -- xxx 

Il problema che ho è che non riesco a inserire un importo diverso di indentazione in ogni riga e il solo rientro di una quantità fissa di spazi/tabulazioni è insufficiente. Come si può fare una rientranza in cui tutti i testi rientrati dovranno essere allineati nella stessa colonna?


EDIT: Ho pensato solo un metodo piuttosto prolisso e poco maneggevole:

  • trovare la posizione stringa trattino da: \--,
  • inserto n (diciamo 20) spazi prima che: 20i <Esc>,
  • eliminare una parte di quegli spazi torna a una determinata colonna (diciamo 15): d|15,
  • salvare tali passi come una macro e ripetere la macro tutte le volte necessarie,

... molto brutto, però!

+0

possibile duplicato di [Come inserire spazi fino alla colonna X per allineare elementi in colonne?] (Http://stackoverflow.com/questions/6154306/how-to-insert-spaces-up-to-column- x-to-line-up-things-in-columns) – DocMax

risposta

14

Sto molto meglio senza plug-in Vim. Ecco la mia soluzione:

<Shift-V>jj:!column -ts --

Poi inserire -- in più righe proprio come hai scritto nella domanda.


È inoltre possibile aggiungere un numero di commenti al momento dell'inserimento.

:set virtualedit=all

<Ctrl-V>jjA-- xxx<Esc>

+2

Questo è ovviamente il modo in cui dovresti farlo al momento dell'inserimento. +1. – Benoit

+0

non funzionerà nel mio caso ... le parti '--- xxx' di ogni riga iniziano su colonne diverse. Quindi non è possibile allineare le parti di modifica della selezione visiva. (il file che ho bisogno di modificare ha già questa struttura e ho bisogno di riformattarlo di conseguenza) – oliver

+1

Lavori su * nix? Se è così, puoi provare il comando 'column' in Vim. ' jj:! Column -ts --', quindi inserisci' --' su più righe che vuoi. – ernix

4

È necessario utilizzare un plug-in specifico, in questo caso è possibile utilizzare il plug-in Tabular o Align.

Entrambi consentono di allineare il testo su caratteri specifici, ad esempio -- nell'esempio. La loro sintassi è un po 'diversa però. Scegli quello più adatto a te.

+0

ha appena installato Tabular e funziona correttamente. Bello ... anche se speravo che questo compito piuttosto piccolo non implicasse l'installazione di un plugin. grazie per il suggerimento! – oliver

+0

@oliver: è possibile risolvere questa attività senza la necessità di installare un plug-in. La soluzione non è così compatta come quando si usa uno di questi plugin, però. –

3

senza plug-in e se avete già inserito i vostri commenti senza soluzione di emix:

:,+2 s/--/         & 

Ciò garantirà tutti i commenti devono essere spostate leftwise al fine di allinearli propriamente.

Poi blocco per blocco selezionare la colonna alla quale si vuole allineare il testo, e: 100<

+0

Bello e semplice. Mi piace! – oliver

+0

Inoltre, si consideri ':, 2s/\ ze -/\ = repeat ('', 32)'. –

+0

@ib .: anche questo è buono, ma a seconda delle impostazioni della tastiera, può essere più lento da digitare! – Benoit

3

Un modo semplice per allineare il testo in colonne è quello di utilizzare Tabular o Align plugin. Se nessuno di questi è a portata di mano, è possibile utilizzare il seguente comando un po 'complicato (e un po' ingombrante) ma perfettamente funzionante (per il caso il caso in questione). 1,2

:let m=0|g/\ze -- /let m=max([m,searchpos(@/,'c')[1]]) 
:%s//\=repeat(' ',m-col('.')) 

Scopo del primo comando è quello di determinare la larghezza della colonna sinistra del separatore (che presumo essere -- qui). La larghezza è calcolata come un massimo delle lunghezze del testo nella prima colonna tra tutte le righe. Il comando :global viene utilizzato per enumerare le righe contenenti il ​​separatore (le altre linee non richiedono l'allineamento). L'atomo \ze situato subito dopo l'inizio del modello, imposta la fine della corrispondenza nella stessa posizione in cui inizia (vedere :help \ze). Modifica delle confini della partita non influisce il comando modo :global opere, il modello è scritto in modo tale solo per soddisfare le esigenze del successivo comando sostituzione: Dal momento che questi due comandi potrebbero condividere lo stesso modello, si può essere omesso nel secondo.

Il comando eseguito sulle linee abbinate,

:let m=max([m,searchpos(@/,'c')[1]]) 

chiama la funzione searchpos() per cercare il modello utilizzato nel genitore :global di comando, e per ottenere la posizione della colonna della partita. Il modello è denominato @/ utilizzando l'ultimo registro del modello di ricerca (vedere :help "/). Ciò si avvantaggia del fatto che il comando :global aggiorna il registro / non appena inizia l'esecuzione. Il flag c passato come secondo argomento nella chiamata searchpos() consente la gara del primo carattere di una riga (:global posizioni del cursore proprio all'inizio del linea per eseguire un comando via), perché potrebbe essere che non è un testo a sinistra del separatore. La funzione searchpos() restituisce un elenco, il primo elemento di è il numero di riga della posizione corrispondente e il secondo è la posizione della colonna.Se il comando viene eseguito su una linea, la riga corrisponde allo schema del comando contenente :global. Siccome lo searchpos() è per cercare lo stesso motivo, c'è sicuramente una corrispondenza su quella linea. Pertanto, solo la colonna che inizia la corrispondenza è interessata, quindi ottiene estratto dall'elenco di ritorno mediante l'indice [1]. Questa stessa posizione è uguale alla larghezza del testo nella prima colonna della riga, più uno. Quindi, m è impostato al massimo del suo valore corrente e di quella posizione della colonna.

Il secondo comando,

:%s//\=repeat(' ',m-col('.')) 

pastiglie prima occorrenza del separatore su tutte le righe che contengono essa, con il numero di spazi che manca di rendere il testo prima del separatore prendere m caratteri, meno uno. Questo comando è un sostituzione globale sostituendo un intervallo vuoto proprio prima del separatore (vedere il commento sul comando :global sopra) con il risultato della valutazione della dell'espressione (vedi :help sub-replace-\=)

repeat(' ',m-col('.')) 

I repeat() ripetizioni funzionali il suo primo argomento (come stringa) il numero di volte indicato nel secondo argomento. Poiché su ogni sostituzione il cursore è spostato all'inizio della corrispondenza del modello, m-col('.') corrisponde esattamente al numero di spazi necessari per spostare il separatore verso destra per allineare le colonne (col('.') restituisce la posizione corrente della colonna del cursore).


seguito è una versione di una riga di questa coppia di comandi.

:let m=0|exe'g/\ze -- /let m=max([m,searchpos(@/,"c")[1]])'|%s//\=repeat(' ',m-col('.')) 

Nelle precedenti revisioni della risposta ai comandi utilizzati per essere segue.

:let p=[0]|%s/^\ze\(.*\) -- /\=map(p,'max([v:val,len(submatch(1))+1])')[1:0]/ 
:exe'%s/\ze\%<'.p[0].'c -- /\=repeat(" ",'.p[0].'-col("."))' 

Coloro che sono interessati a questi particolari comandi possono trovare dettagliate descrizione della storia di modifiche.

+1

wow ... sembra un po 'coinvolto! ti piacerebbe spiegare la tua soluzione? – oliver

+0

@oliver: sicuro. Ho aggiunto una spiegazione dettagliata alla risposta. –

+0

grazie per la spiegazione dettagliata! anche se non penso che userò questo (non potrei MAI ricordare :) in pratica mi è piaciuto molto leggere la tua risposta e di sicuro ho imparato alcune cose su Vim ... di nuovo! – oliver

0

Questa è una modifica alla risposta di Benoit che ha due passaggi.

Primo passo, seleziona il testo da cercare e sostituisci - con molti spazi.

'<,'>s/--/       --/ 

Ora tutti i commenti dovrebbero avere molti spazi, ma essere comunque irregolari.

Secondo passaggio, selezionare nuovamente il testo e utilizzare un'altra espressione regolare per abbinare tutti i caratteri che si desidera conservare (diciamo i primi 20 caratteri o così) più tutti gli spazi seguenti e per sostituirlo con una copia di quelli prima 20 caratteri:

'<,'>s/\(.\{20}\)\s*/\1/ 

non è così facile come Benoit, ma non riuscivo a capire come fare il suo secondo lavoro passo.

Problemi correlati