Come puoi rimuovere automaticamente gli spazi bianchi finali in vim


197

Ricevo errori "trailing whitespace" nel tentativo di eseguire il commit di alcuni file in git.

Voglio rimuovere automaticamente questi caratteri finali vuoti prima di salvare i file Python.

Puoi configurare vim per fare questo? Se é cosi, come?


3
questo non riguarda solo Python

2
Usa il mio plugin DeleteTrailingWhitespace .
Ingo Karkat,

Risposte:


208

Ho trovato la risposta qui .

L'aggiunta di quanto segue al mio file .vimrc ha funzionato.

autocmd BufWritePre *.py :%s/\s\+$//e

1
Interessante! Trascinare lo spazio bianco è una battaglia al lavoro. Lo detesto, gli altri non capiscono perché. Usiamo tanto vi quanto vim (io uso vim; loro non lo fanno perché dovrebbero installarlo). Ho un programma che chiamo stb per Strip Trailing Blanks e lo uso come filtro; funziona anche in vi. Questo è meglio.
Jonathan Leffler,

16
Questo cambia la posizione del cursore ad ogni salvataggio. È possibile evitarlo?
stepancheg,

3
Poiché questa è la risposta di fatto a questa domanda, forse dovrebbe essere aggiornata per mantenere la posizione del cursore.
Edu Felipe,

2
Ciò eliminerà anche gli spazi finali nelle stringhe multilinea, che in alcuni casi potrebbe non essere desiderato. Ma immagino non ci sia un modo semplice per evitarlo?
Luator,

3
Forse potresti esplicitare che ealla fine significa che, se non abbiamo trovato il modello, vi non considera il comando sostitutivo come fallito
LLenain,

169

Compilazione sopra e salvataggio della posizione del cursore:

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

autocmd FileType c,cpp,java,php,ruby,python autocmd BufWritePre <buffer> :call <SID>StripTrailingWhitespaces()

Se si desidera applicare questo al salvataggio su qualsiasi file, tralasciare il secondo autocmde utilizzare un carattere jolly *:

autocmd BufWritePre * :call <SID>StripTrailingWhitespaces()

9
Puoi migliorare la tua funzione salvando anche l'ultima ricerca e ripristinandola. let _s = @ / let @ / = _ s
xApple

3
Ho rimosso la autocmd FileType c,cpp,java,php,ruby,python parte per farla applicare a tutti i file.
swt83,

8
@xApple: non è necessario salvare le funzioni interne, salvare e ripristinare l'ultima ricerca - se ne occuperà il contesto delle funzioni.
Tobias,

3
@ swt83 devi anche sostituirlo <buffer>con *se vuoi che funzioni su tutti i file
cadlac

3
Se si antepone il comando sostitutivo w / keepp, non modificherà la cronologia delle ricerche, ovverokeepp %s/\s\+$//e
jeberle

68

Di solito ho anche un:

match Todo /\s\+$/

nel mio .vimrcfile, in modo che gli spazi bianchi di fine riga siano oscurati.

Todo è un nome di gruppo di hilighting di sintassi che viene utilizzato per parole chiave di hilighting come TODO, FIXMEo XXX. Ha un colore di sfondo giallastro fastidiosamente brutto e trovo che sia il migliore per le cose di hilight che non vuoi nel tuo codice :-)


7
Oppure puoi impostare la lista e impostare listchars + = trail :.
Oli,

Eccellente: è la via di mezzo perfetta tra la rimozione automatica degli spazi vuoti finali (anche quando potrei non esserne consapevole, o quando è il codice di qualcun altro con cui sto semplicemente lavorando nello stesso file), a non fare nulla al riguardo . Grazie.
Daniel Hershcovich,

2
sfortunatamente, la mia combinazione di colori preferita zenburn non mette in evidenza
Peter Long,

@PeterLong, non funziona neanche nel tema dei railscast. Controllalo con :hi Todo. Quindi ho esaminato :hi <Tab>e :help hi. Ho considerato Cursore Error, ma penso che ci proverò match VisualNOS /\s\+$/ . Potrei combinare questo con alcune delle autocmdaltre risposte qui.
Brady Trainor,

51

Evidenzi entrambi gli spazi vuoti finali esistenti e spoglio anche gli spazi bianchi finali.

Configuro il mio editor (vim) per mostrare uno spazio bianco alla fine, ad es

inserisci qui la descrizione dell'immagine

con questo in fondo al mio .vimrc:

highlight ExtraWhitespace ctermbg=red guibg=red
match ExtraWhitespace /\s\+$/
autocmd BufWinEnter * match ExtraWhitespace /\s\+$/
autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/
autocmd InsertLeave * match ExtraWhitespace /\s\+$/
autocmd BufWinLeave * call clearmatches()

e lo "spoglio automaticamente" dai file quando li salvo, nel mio caso * .rb per i file ruby, sempre nel mio ~ / .vimrc

function! TrimWhiteSpace()
    %s/\s\+$//e
endfunction
autocmd BufWritePre     *.rb :call TrimWhiteSpace()

13

Ecco un modo per filtrare per più di un FileType.

autocmd FileType c,cpp,python,ruby,java autocmd BufWritePre <buffer> :%s/\s\+$//e

Ogni file: autocmd FileType * autocmd BufWritePre <buffer>:% s / \ s \ + $ // e
JREAM

7

Copiato e incollato da http://blog.kamil.dworakowski.name/2009/09/unobtrusive-highlighting-of-trailing.html (il link non funziona più, ma il bit che ti serve è sotto)

"Questo ha il vantaggio di non evidenziare ogni spazio digitato alla fine della riga, solo quando si apre un file o si esce dalla modalità di inserimento. Molto pulito."

highlight ExtraWhitespace ctermbg=red guibg=red
au ColorScheme * highlight ExtraWhitespace guibg=red
au BufEnter * match ExtraWhitespace /\s\+$/
au InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/
au InsertLeave * match ExtraWhiteSpace /\s\+$/

1
Il link al blog sembra essere morto.
Tobias,

La stessa soluzione si trova a questo link in "Utilizzo del comando match".
Ryanjillon

6

Ho visto questa soluzione in un commento su VIM Wikia - Rimuovere gli spazi indesiderati

Mi è veramente piaciuto. Aggiunge .a agli spazi bianchi indesiderati.

inserisci qui la descrizione dell'immagine

Metti questo nel tuo .vimrc

" Removes trailing spaces
function TrimWhiteSpace()
  %s/\s*$//
  ''
endfunction

set list listchars=trail:.,extends:>
autocmd FileWritePre * call TrimWhiteSpace()
autocmd FileAppendPre * call TrimWhiteSpace()
autocmd FilterWritePre * call TrimWhiteSpace()
autocmd BufWritePre * call TrimWhiteSpace()

5

Ecco come lo sto facendo. Non ricordo dove l'ho rubato da TB.

autocmd BufWritePre * :call <SID>StripWhite()
fun! <SID>StripWhite()
    %s/[ \t]\+$//ge
    %s!^\( \+\)\t!\=StrRepeat("\t", 1 + strlen(submatch(1)) / 8)!ge
endfun

2
Hum, è piuttosto pericoloso farlo su "*" se alla fine si aprono file binari, potrebbero finire in una forma piuttosto scadente.
mat

Sì, probabilmente non è il più intelligente, quindi non uso neanche vim per un editor esadecimale. Ciò non verrà eseguito se non si salva.
Greg

Penso che questo superi l'alternativa di elencare ogni singolo tipo di file su cui potresti lavorare, no? Lavoro su rb, php, cs, html, sass, css, js, coffee, xml, xslt, pl, etc, etc, etc ... C'è un mezzo felice?
Derek prima del

4
A meno che tu non stia scrivendo su file binari in vim, questo probabilmente non sarà mai un problema.
Greg

Sembra che la prima %sbandiera globale (g) sia inutile come uno spazio all'EOL :-)
Jens

3

Una soluzione che rimuove semplicemente gli spazi bianchi finali dal file non è accettabile in tutte le circostanze. Funzionerà in un progetto che ha avuto questa politica sin dall'inizio, e quindi non ci sono spazi bianchi tali da non aggiungerti al tuo prossimo impegno.

Supponiamo di voler semplicemente non aggiungere nuove istanze di spazi bianchi finali, senza influire sugli spazi bianchi esistenti in righe che non sono state modificate, al fine di mantenere il commit libero da modifiche irrilevanti per il tuo lavoro.

In tal caso, con git, puoi usare uno script come questo:

#!/bin/sh

set -e # bail on errors

git stash save commit-cleanup
git stash show -p | sed '/^\+/s/ *$//' | git apply
git stash drop

Vale a dire, nascondiamo le modifiche e quindi filtriamo tutte le +linee nel diff per rimuovere il loro spazio bianco finale mentre applichiamo nuovamente la modifica alla directory di lavoro. Se questa pipe di comando ha esito positivo, eliminiamo la scorta.


1

Gli altri approcci qui in qualche modo non hanno funzionato per me in MacVim quando usato nel .vimrcfile. Quindi eccone uno che fa ed evidenzia gli spazi finali:

set encoding=utf-8
set listchars=trail:·
set list

Esecuzione set listchars=trail:·dicendo: E474: Invalid argument: listchars=trail:·. Puoi validare il tuo esempio?
Kenorb,


0

autocmd BufWritePre * :%s/\s\+$//<CR>:let @/=''<CR>


0

Per le persone che vogliono eseguirlo per tipi di file specifici (FileTypes non sono sempre affidabili):

autocmd BufWritePre *.c,*.cpp,*.cc,*.h,*.hpp,*.py,*.m,*.mm :%s/\s\+$//e

O con vim7:

autocmd BufWritePre *.{c,cpp,cc,h,hpp,py,m,mm} :%s/\s\+$//e

0

Se tagli gli spazi bianchi, dovresti farlo solo su file che sono già puliti. "Quando a Roma...". Questa è una buona etichetta quando si lavora su basi di codice in cui i cambiamenti spuri sono sgraditi.

Questa funzione rileva gli spazi bianchi finali e attiva il taglio solo se era già pulito.

Il merito di questa idea va alla gemma di un commento qui: https://github.com/atom/whitespace/issues/10 (il più lungo flusso di commenti sui ticket dei bug di sempre)

autocmd BufNewFile,BufRead *.test call KarlDetectWhitespace()

fun! KarlDetectWhitespace()
python << endpython
import vim
nr_unclean = 0
for line in vim.current.buffer:
    if line.rstrip() != line:
        nr_unclean += 1

print "Unclean Lines: %d" % nr_unclean
print "Name: %s" % vim.current.buffer.name
cmd = "autocmd BufWritePre <buffer> call KarlStripTrailingWhitespace()"
if nr_unclean == 0:
    print "Enabling Whitespace Trimming on Save"
    vim.command(cmd)
else:
    print "Whitespace Trimming Disabled"
endpython
endfun

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

Potresti anche mantenere il registro di ricerca let _s=@/e ripristinarlo alla fine `let @ / = _ s`. In questo caso stiamo usando il registro del buco nero
SergioAraujo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.