2011-11-29 10 views
12

avevo aggiunto la seguente funzione nel mio Vimrc per rimuovere gli spazi finali bianchi poco prima del salvataggioRimozione trailing spazio bianco solo per le linee modificate

fun! <SID>StripTrailingWhitespaces()            
    let l = line(".")               
    let c = col(".")                
    %s/\s\+$//e                 
    call cursor(l, c)               
endfun                   

autocmd BufWritePre *.h :call <SID>StripTrailingWhitespaces() 
autocmd BufWritePre *.cpp :call <SID>StripTrailingWhitespaces() 
autocmd BufWritePre *.c :call <SID>StripTrailingWhitespaces() 

Funziona davvero bene. Tuttavia, in alcuni casi vorrei rimuovere gli spazi bianchi finali solo dalle righe che ho modificato. Questo per garantire che il mio output diff abbia un aspetto sano come per alcuni file di codice legacy, quasi tutte le linee hanno degli spazi posteriori finali e non voglio sovraccaricare il mio revisore del codice con differenze non necessarie.

diff -b non è una soluzione in questo momento in quanto ignora anche gli spazi bianchi da qualsiasi luogo in una linea e, talvolta, che il cambiamento è abbastanza importante da essere includere nel diff uscita.

Quindi la mia domanda è: è possibile rimuovere gli spazi bianchi finali solo dalle righe che sono state modificate in questa sessione in un file in vim?

+1

Ho una regola di evidenziazione che evidenzia (in modo molto fastidioso) lo spazio vuoto finale, quindi è molto facile per me vedere quale spazio deve essere rimosso; ma +1 perché sarebbe bello automatizzare la maggior parte di questo. – SingleNegationElimination

+1

Perché no, come attività una tantum, spoglia tutti gli spazi bianchi finali di tutti i tuoi file legacy? –

+1

@MatthewStrawbridge Fare ciò oscura chi ha scritto (o ha modificato per ultimo) le righe quando si esegue qualcosa come git annotate. (Può ancora essere trovato, ma richiede ulteriori passaggi.) –

risposta

2

mMontu's answer ha l'idea giusta, ma non gestisce un caso limite. Vale a dire, se sposto il cursore verso il basso, quindi il backup, tutto in modalità di modifica, non raccoglie le modifiche a tali linee. Se vorremmo gestire questo, allora abbiamo bisogno di memorizzare le prime e le ultime linee visitate dall'utente. Ecco il codice più robusto, con tutto ciò che raggruppate in funzioni:

fun! <SID>SetupTrailingWhitespaces() 
    let curline = line('.') 
    let b:insert_top = curline 
    let b:insert_bottom = curline 
endfun 

fun! <SID>UpdateTrailingWhitespace() 
    let curline = line('.') 
    if b:insert_top > curline 
     let b:insert_top = curline 
    elseif b:insert_bottom < curline 
     let b:insert_bottom = curline 
    endif 
endfun 

fun! <SID>StripTrailingWhitespaces() 
    let original_cursor = getpos('.') 
    exe b:insert_top ',' b:insert_bottom 's/\s\+$//e' 
    call setpos('.', original_cursor) 
endfun 

Ora non ci resta invochiamo queste funzioni al momento giusto:

autocmd InsertEnter * :call <SID>SetupTrailingWhitespaces() 
autocmd InsertLeave * :call <SID>StripTrailingWhitespaces() 
autocmd CursorMovedI * :call <SID>UpdateTrailingWhitespace() 

In alternativa, ho scritto a plugin che fornisce questa funzionalità aggiornate , con diverse funzionalità aggiuntive come la rimozione in modalità normale.

4

Una possibilità sarebbe quella di utilizzare autocmd InsertLeave per togliere gli spazi bianchi da riga corrente ogni volta che si lascia la modalità di inserimento:

autocmd InsertLeave *.[ch] :call <SID>StripTrailingWhitespaces() 

, e cambiare comando substitute di StripTrailingWhitespaces() funzione cambiato in

s/\s\+$//e 

E ' funzionerà se tutte le linee che includi non finiscono in spazi bianchi , solo l'ultimo. Sarà possibile modificare le righe non modificate , se si accede e si esce dalla modalità di inserimento (i seguito da ESC).

Questa soluzione può essere modificata per lavorare se si includono le linee che si esaurisce nello spazio bianco (linee incollato da codice legacy, per esempio):

autocmd InsertEnter *.[ch] :let b:insert_start = line('.') 
autocmd InsertLeave *.[ch] :call <SID>StripTrailingWhitespaces() 

fun! StripTrailingWhitespaces() 
    let original_cursor = getpos('.') 
    exe b:insert_start . ',.s/\s\+$//e' 
    call setpos('.', original_cursor) 
endfun  

Se la sostituzione sulle linee a causa di entrare e inserto uscita modalità (i seguita da ESC) è un problema quindi la soluzione potrebbe salvare b:changedtick-variable quando si accede alla modalità di inserimento e controllarla quando si lascia la modalità di inserimento per rilevare le modifiche.

0

Scrivo un plug-in con il nome "vim-scavenger" per pulire più righe vuote e spazi finali.

Basta aggiungere la seguente configurazione nel file.vimrc:

let g:scavenger_auto_clean_up_on_write = 1 

Per maggiori dettagli, si può venire a che Github repo per saperne di più. Sentiti libero di darmi consigli per migliorare il plugin.

+0

Questo plug-in è già stato rinominato in "vim-janitor". Per favore vai [qui] (https://github.com/KuoE0/vim-janitor). – KuoE0

Problemi correlati