Jak możesz automatycznie usunąć końcowe białe znaki w vimie

197

Podczas próby zatwierdzenia niektórych plików w git dostaję błędy „końcowe białe znaki”.

Chcę automatycznie usunąć końcowe znaki białych znaków przed zapisaniem plików Pythona.

Czy możesz skonfigurować vima, aby to robił? Jeśli tak to jak?

Paul D. Eden
źródło
3
nie dotyczy to samego pytona
2
Użyj mojej wtyczki DeleteTrailingWhitespace .
Ingo Karkat

Odpowiedzi:

208

Tutaj znalazłem odpowiedź .

Dodanie następującego do mojego pliku .vimrc załatwiło sprawę.

autocmd BufWritePre *.py :%s/\s\+$//e
Paul D. Eden
źródło
1
Ciekawy! Końcowa biała przestrzeń to bitwa w pracy. Nienawidzę tego, inni nie rozumieją dlaczego. Używamy tyle samo vi, co vima (ja używam vima; nie robią tego, ponieważ musieliby go zainstalować). Mam program, który nazywam stb do Strip Trailing Blanks i używam go jako filtra; działa również w vi. To jest lepsze.
Jonathan Leffler
16
Zmienia to pozycję kursora przy każdym zapisie. Czy można tego uniknąć?
stepancheg
3
Ponieważ jest to de facto odpowiedź na to pytanie, być może należy ją zaktualizować, aby utrzymać pozycję kursora.
Edu Felipe
2
Spowoduje to również usunięcie końcowych spacji w ciągach wieloliniowych, co w niektórych przypadkach może nie być pożądane. Ale chyba nie ma łatwego sposobu na uniknięcie tego?
luator
3
Być może mógłbyś wyraźnie powiedzieć, że ena końcu oznacza, że ​​jeśli nie znaleźliśmy wzorca, vi nie uważa polecenia zastępczego za nieudane
LLenain
169

Kompilacja powyższego plus zapisywanie pozycji kursora:

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()

Jeśli chcesz zastosować to do zapisu do dowolnego pliku, pomiń drugi autocmdi użyj symbolu wieloznacznego *:

autocmd BufWritePre * :call <SID>StripTrailingWhitespaces()
stepancheg
źródło
9
Możesz poprawić swoją funkcję, zapisując również ostatnie wyszukiwanie i przywracając je. let _s = @ / let @ / = _ s
xApple
3
Usunąłem autocmd FileType c,cpp,java,php,ruby,python część, aby dotyczyła wszystkich plików.
swt83
8
@xApple: Wewnątrz funkcji zapisywanie i przywracanie ostatniego wyszukiwania nie jest konieczne - wystarczy pozostawić kontekst funkcji.
Tobias
3
@ swt83 trzeba również wymienić <buffer>ze *jeśli chcesz go do pracy na wszystkich plików
cadlac
3
Jeśli użyjesz prefiksu polecenia zastępczego w / keepp, nie zmieni on historii wyszukiwania, tj.keepp %s/\s\+$//e
jeberle,
68

Zwykle mam również:

match Todo /\s\+$/

w moim .vimrcpliku, aby białe znaki końca linii były podświetlone.

Todo bycia składnia hilighting nazwa-grupy , która jest używana do hilighting słowa kluczowe jak TODO, FIXMElub XXX. Ma denerwująco brzydki żółtawy kolor tła i uważam, że najlepiej jest ukryć w kodzie to, czego nie chcesz :-)

mata
źródło
7
Lub możesz ustawić listę i ustawić listę kanałów + = ślad :.
Oli
Doskonale - jest to idealny środek między automatycznym usuwaniem spacji końcowych (nawet jeśli nie jestem tego świadomy lub gdy jest to kod kogoś innego, z którym po prostu pracuję w tym samym pliku), a nie robieniem nic z tym . Dzięki.
Daniel Hershcovich
2
niestety moja ulubiona kolorystyka zenburn nie wyróżnia się
Peter Long
@PeterLong, również nie działa w temacie Railscasts. Sprawdź to za pomocą :hi Todo. Więc przestudiowałem :hi <Tab>i :help hi. Zastanawiałem się Cursori Error, ale myślę, że spróbuję match VisualNOS /\s\+$/ . Mógłbym połączyć to z niektórymi autocmdz innych odpowiedzi tutaj.
Brady Trainor
51

Zarówno podkreślam istniejące końcowe białe znaki, jak i usuwam końcowe białe znaki.

Konfiguruję mój edytor (vim), aby wyświetlać białe znaki na końcu, np

wprowadź opis zdjęcia tutaj

z tym na dole mojego .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()

i „automatycznie usuwam” je z plików podczas ich zapisywania, w moim przypadku * .rb dla plików ruby, ponownie w moim ~ / .vimrc

function! TrimWhiteSpace()
    %s/\s\+$//e
endfunction
autocmd BufWritePre     *.rb :call TrimWhiteSpace()
Michael Durrant
źródło
13

Oto sposób na filtrowanie według więcej niż jednego FileType.

autocmd FileType c,cpp,python,ruby,java autocmd BufWritePre <buffer> :%s/\s\+$//e
syvex
źródło
Każdy plik: autocmd FileType * autocmd BufWritePre <bufor>:% s / \ s \ + $ // e
JREAM
7

Skopiowano i wklejono z http://blog.kamil.dworakowski.name/2009/09/unobtrusive-highlighting-of-trailing.html (link już nie działa, ale potrzebna część jest poniżej)

„Ma to tę zaletę, że nie wyróżnia każdego wpisanego miejsca na końcu wiersza, tylko po otwarciu pliku lub wyjściu z trybu wstawiania. Bardzo porządnie”.

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\+$/
lazysoundsystem
źródło
1
Link do bloga prawdopodobnie umarł.
Tobias
To samo rozwiązanie można znaleźć pod tym linkiem w sekcji „Korzystanie z polecenia dopasowania”.
ryanjdillon
6

Widziałem to rozwiązanie w komentarzu na VIM Wikia - Usuń niechciane spacje

Naprawdę mi się podobało. Dodaje .niechciane białe spacje.

wprowadź opis zdjęcia tutaj

Umieść to w swoim .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()
Diego Juliao
źródło
5

Tak to robię. Nie pamiętam, skąd go ukradłem.

autocmd BufWritePre * :call <SID>StripWhite()
fun! <SID>StripWhite()
    %s/[ \t]\+$//ge
    %s!^\( \+\)\t!\=StrRepeat("\t", 1 + strlen(submatch(1)) / 8)!ge
endfun
gregf
źródło
2
Hum, to dość niebezpieczne, aby to zrobić na „*”, jeśli w końcu otworzysz pliki binarne, mogą skończyć się w całkiem złym stanie.
mat
Tak, chyba nie najmądrzejszy, ale znowu nie używam vima dla edytora szesnastkowego. To się nie uruchomi, dopóki nie zapiszesz.
gregf
Myślę, że jest to alternatywa dla listy każdego typu pliku, nad którym możesz pracować, nie? Pracuję na rb, php, cs, html, sass, css, js, coffee, xml, xslt, pl, itp. Itp. Itd. Czy istnieje szczęśliwy nośnik?
Derek Prior
4
O ile nie piszesz do plików binarnych w vimie, prawdopodobnie nie będzie to nigdy problemem.
gregf,
Pojawia się po raz pierwszy %sflaga globalna (g) jest tak bezużyteczna jak spacja na EOL :-)
Jens
3

Rozwiązanie, które po prostu usuwa końcowe spacje z pliku, nie jest akceptowane we wszystkich okolicznościach. Będzie działał w projekcie, który od początku obowiązywał tę zasadę, więc nie ma takich białych znaków, że nie dodałeś się tylko do nadchodzącego zatwierdzenia.

Załóżmy, że nie chcesz dodawać nowych instancji końcowych białych znaków bez wpływu na istniejące białe znaki w liniach, których nie edytowałeś, aby zachować zatwierdzenie bez zmian, które nie mają znaczenia dla twojej pracy.

W takim przypadku za pomocą git możesz użyć takiego skryptu:

#!/bin/sh

set -e # bail on errors

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

Innymi słowy, przechowujemy zmiany, a następnie filtrujemy wszystkie +linie w diff, aby usunąć końcowe białe znaki, gdy ponownie zastosujemy zmianę do katalogu roboczego. Jeśli ta komenda zakończy się powodzeniem, upuszczamy skrytkę.

Kaz
źródło
1

Inne podejścia tutaj jakoś nie działały dla mnie w MacVimie, gdy zostały użyte w .vimrcpliku. Oto jeden, który robi i wyróżnia końcowe spacje:

set encoding=utf-8
set listchars=trail:·
set list
mb21
źródło
Wykonywanie set listchars=trail:·mówiąc: E474: Invalid argument: listchars=trail:·. Czy możesz potwierdzić swój przykład?
kenorb
1
@kenorb zobaczyć stackoverflow.com/questions/18321538/...
mb21
0

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

aemonge
źródło
0

Dla osób, które chcą uruchomić go dla określonych typów plików (typy plików nie zawsze są niezawodne):

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

Lub z vim7:

autocmd BufWritePre *.{c,cpp,cc,h,hpp,py,m,mm} :%s/\s\+$//e
Mr_Pouet
źródło
0

Jeśli przycinasz białe znaki, powinieneś to robić tylko dla plików, które są już czyste. "Kiedy w Rzymie...". Jest to dobra etykieta podczas pracy z bazami kodowymi, w których niepożądane zmiany są niepożądane.

Ta funkcja wykrywa końcowe białe znaki i włącza przycinanie tylko wtedy, gdy było już czyste.

Zaletą tego pomysłu jest klejnot komentarza tutaj: https://github.com/atom/whitespace/issues/10 (najdłuższy strumień komentarzy do zgłoszeń błędów)

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
Karl Pickett
źródło
Możesz także zachować rejestr wyszukiwania let _s=@/i przywrócić go na końcu `let @ / = _ s`. W tym przypadku korzystamy z rejestru czarnej dziury
SergioAraujo