Wie können Sie nachgestellte Leerzeichen in vim automatisch entfernen?


197

Beim Versuch, einige Dateien in Git festzuschreiben, werden nachgestellte Whitespace-Fehler angezeigt.

Ich möchte diese nachgestellten Leerzeichen automatisch entfernen, bevor ich Python-Dateien speichere.

Können Sie vim dafür konfigurieren? Wenn das so ist, wie?


3
Dies betrifft nicht nur Python

2
Verwenden Sie mein DeleteTrailingWhitespace- Plugin.
Ingo Karkat

Antworten:


208

Ich habe die Antwort hier gefunden .

Das Hinzufügen von Folgendem zu meiner .vimrc-Datei hat den Trick getan.

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

1
Interessant! Schleppender weißer Raum ist ein Kampf bei der Arbeit. Ich hasse es, andere verstehen nicht warum. Wir verwenden so viel vi wie vim (ich benutze vim; sie tun es nicht, weil sie es installieren müssten). Ich habe ein Programm, das ich stb aufrufe, um nachgestellte Leerzeichen zu entfernen, und das ich als Filter verwende. funktioniert auch in vi. Das ist besser.
Jonathan Leffler

16
Dies ändert die Cursorposition bei jedem Speichern. Ist es möglich, dies zu vermeiden?
stepancheg

3
Da dies die tatsächliche Antwort auf diese Frage ist, sollte sie möglicherweise aktualisiert werden, um die Cursorposition beizubehalten.
Edu Felipe

2
Dadurch werden auch nachgestellte Leerzeichen in mehrzeiligen Zeichenfolgen gelöscht, was in einigen Fällen möglicherweise nicht erwünscht ist. Aber ich denke, es gibt keinen einfachen Weg, dies zu vermeiden?
Luator

3
Vielleicht könnten Sie explizit e
sagen,

169

Zusammenstellung von oben plus Speichern der Cursorposition:

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

Wenn Sie dies beim Speichern auf eine beliebige Datei anwenden möchten, lassen Sie die zweite weg autocmdund verwenden Sie einen Platzhalter *:

autocmd BufWritePre * :call <SID>StripTrailingWhitespaces()

9
Sie können Ihre Funktion verbessern, indem Sie auch die letzte Suche speichern und wiederherstellen. let _s = @ / let @ / = _ s
xApple

3
Ich habe das autocmd FileType c,cpp,java,php,ruby,python Teil entfernt, damit es auf alle Dateien angewendet wird.
swt83

8
@xApple: Innerhalb von Funktionen ist das Speichern und Wiederherstellen der letzten Suche nicht erforderlich. Wenn Sie den Funktionskontext verlassen, wird dies erledigt.
Tobias

3
@ SWT83 Sie müssen auch ersetzen <buffer>mit , *wenn Sie es Arbeit für alle Dateien wollen
cadlac

3
Wenn Sie dem Ersatzbefehl w / keeppkeepp %s/\s\+$//e
voranstellen,

68

Ich habe normalerweise auch eine:

match Todo /\s\+$/

in meiner .vimrcDatei, so dass Leerzeichen am Zeilenende hellig sind.

Todo ein Syntax hilighting wobei group-name , der wie Schlüsselwörter für hilighting verwendet wird TODO, FIXMEoder XXX. Es hat eine ärgerlich hässliche gelbliche Hintergrundfarbe und ich finde es am besten, Dinge zu hellen, die Sie nicht in Ihrem Code haben wollen :-)


7
Oder Sie können list und listchars + = trail: setzen.
Oli

Hervorragend - es ist der perfekte Mittelweg zwischen dem automatischen Entfernen von nachgestellten Leerzeichen (selbst wenn ich es nicht weiß oder wenn es sich um den Code eines anderen handelt, mit dem ich gerade in derselben Datei arbeite), um nichts dagegen zu unternehmen . Vielen Dank.
Daniel Hershcovich

2
Leider hebt mein Lieblingsfarbschema Zenburn nicht hervor
Peter Long

@PeterLong, funktioniert auch nicht im Railscasts-Thema. Überprüfen Sie es mit :hi Todo. Also habe ich durchgesehen :hi <Tab>und :help hi. Ich überlegte Cursorund Error, aber ich denke, ich werde es versuchen match VisualNOS /\s\+$/ . Ich könnte dies mit einigen der autocmds aus anderen Antworten hier kombinieren .
Brady Trainor

51

Ich hebe sowohl vorhandene nachgestellte Leerzeichen hervor als auch nachfolgende Leerzeichen.

Ich konfiguriere meinen Editor (vim) so, dass am Ende Leerzeichen angezeigt werden, z

Geben Sie hier die Bildbeschreibung ein

mit diesem am Ende meiner .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()

und ich 'entferne' es automatisch von Dateien, wenn ich sie speichere, in meinem Fall * .rb für Ruby-Dateien, wieder in meinem ~ / .vimrc

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

13

Hier ist eine Möglichkeit, nach mehr als einem Dateityp zu filtern.

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

Jede Datei: autocmd FileType * autocmd BufWritePre <Buffer>:% s / \ s \ + $ // e
JREAM

7

Kopiert und eingefügt von http://blog.kamil.dworakowski.name/2009/09/unobtrusive-highlighting-of-trailing.html (der Link funktioniert nicht mehr, aber das Bit, das Sie benötigen, ist unten)

"Dies hat den Vorteil, dass nicht jedes Leerzeichen am Ende der Zeile hervorgehoben wird, nur wenn Sie eine Datei öffnen oder den Einfügemodus verlassen. Sehr ordentlich."

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
Der Blog-Link scheint gestorben zu sein.
Tobias

Die gleiche Lösung finden Sie unter diesem Link unter "Verwenden des Befehls match".
Ryanjdillon

6

Ich habe diese Lösung in einem Kommentar bei gesehen VIM Wikia gesehen - Entfernen Sie unerwünschte Leerzeichen

Ich mochte es wirklich. Fügt ein .zu den unerwünschten Leerzeichen hinzu.

Geben Sie hier die Bildbeschreibung ein

Setzen Sie dies in Ihre .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

So mache ich es. Ich kann mich nicht erinnern, wo ich es von tbh gestohlen habe.

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

2
Hum, es ist ziemlich gefährlich, es auf "*" zu tun, wenn Sie schließlich Binärdateien öffnen, können sie in einem ziemlich schlechten Zustand enden.
Matte

Ja, wahrscheinlich nicht der klügste, aber ich benutze vim auch nicht für einen Hex-Editor. Das wird erst ausgeführt, wenn Sie speichern.
Gregf

Ich denke, dies ist besser als die Alternative, jeden einzelnen Dateityp aufzulisten, an dem Sie arbeiten könnten, nicht wahr? Ich arbeite an rb, php, cs, html, sass, css, js, kaffee, xml, xslt, pl usw. usw. usw. Gibt es ein fröhliches Medium?
Derek Prior

4
Wenn Sie nicht in vim in Binärdateien schreiben, wird dies wahrscheinlich nie ein Problem sein.
Gregf

Es scheint in der ersten %sdie globale (g) Flagge ist so nutzlos wie ein Leerzeichen bei EOL :-)
Jens

3

Eine Lösung, bei der nachfolgende Leerzeichen einfach aus der Datei entfernt werden, ist nicht unter allen Umständen akzeptabel. Es funktioniert in einem Projekt, in dem diese Richtlinie von Anfang an angewendet wurde. Daher gibt es keine solchen Leerzeichen, die Sie nicht einfach selbst in Ihr bevorstehendes Commit aufgenommen haben.

Angenommen, Sie möchten lediglich keine neuen Instanzen von nachgestellten Leerzeichen hinzufügen, ohne vorhandene Leerzeichen in Zeilen zu beeinflussen, die Sie nicht bearbeitet haben, um Ihr Commit frei von Änderungen zu halten, die für Ihre Arbeit irrelevant sind.

In diesem Fall können Sie mit git ein Skript wie das folgende verwenden:

#!/bin/sh

set -e # bail on errors

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

Das heißt, wir speichern die Änderungen und filtern dann alle +Zeilen im Diff, um deren nachfolgendes Leerzeichen zu entfernen, wenn wir die Änderung erneut auf das Arbeitsverzeichnis anwenden. Wenn diese Befehlspipe erfolgreich ist, löschen wir den Stash.


1

Die anderen Ansätze hier funktionierten in MacVim irgendwie nicht, wenn sie in der .vimrcDatei verwendet wurden. Hier ist eine, die nachfolgende Leerzeichen hervorhebt:

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

Ausführungsspruch set listchars=trail:·: E474: Invalid argument: listchars=trail:·. Können Sie Ihr Beispiel validieren?
Kenorb



0

Für Benutzer, die es für bestimmte Dateitypen ausführen möchten (FileTypes sind nicht immer zuverlässig):

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

Oder mit vim7:

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

0

Wenn Sie Leerzeichen kürzen, sollten Sie dies nur für Dateien tun, die bereits sauber sind. "Wenn du in Rom bist...". Dies ist eine gute Etikette bei der Arbeit an Codebasen, bei denen falsche Änderungen nicht erwünscht sind.

Diese Funktion erkennt nachgestellte Leerzeichen und aktiviert das Trimmen nur, wenn es bereits sauber war.

Der Verdienst für diese Idee geht an ein Juwel eines Kommentars hier: https://github.com/atom/whitespace/issues/10 (längster Bug-Ticket-Kommentar-Stream aller Zeiten)

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

Sie können das let _s=@/Suchregister auch behalten und am Ende `let @ / = _ s` wiederherstellen. In diesem Fall verwenden wir das Schwarzlochregister
SergioAraujo
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.