Comment supprimer automatiquement les espaces de fin dans vim

197

J'obtiens des erreurs de 'espaces blancs' en essayant de valider certains fichiers dans git.

Je veux supprimer ces espaces blancs finaux automatiquement juste avant d'enregistrer des fichiers python.

Pouvez-vous configurer vim pour ce faire? Si c'est le cas, comment?

Paul D. Eden
la source
3
cela ne concerne pas seul python
2
Utilisez mon plugin DeleteTrailingWhitespace .
Ingo Karkat

Réponses:

208

J'ai trouvé la réponse ici .

L'ajout de ce qui suit à mon fichier .vimrc a fait l'affaire.

autocmd BufWritePre *.py :%s/\s\+$//e
Paul D. Eden
la source
1
Intéressant! Traquer les espaces blancs est une bataille au travail. Je déteste ça, les autres ne comprennent pas pourquoi. Nous utilisons autant de vi que de vim (j'utilise vim; ils ne le font pas car ils devraient l'installer). J'ai un programme que j'appelle stb pour supprimer les blancs de fin et je l'utilise comme filtre; fonctionne aussi en vi. C'est mieux.
Jonathan Leffler
16
Cela change la position du curseur à chaque sauvegarde. Est-il possible de l'éviter?
stepancheg
3
Comme il s'agit de la réponse de facto à cette question, elle devrait peut-être être mise à jour pour conserver la position du curseur.
Edu Felipe
2
Cela supprimera également les espaces de fin dans les chaînes multilignes, ce qui peut ne pas être souhaité dans certains cas. Mais je suppose qu'il n'y a pas de moyen facile d'éviter cela?
luator
3
Peut-être pourriez-vous expliquer que la efin signifie que, si nous n'avons pas trouvé le modèle, vi ne considère pas la commande de substitution comme ayant échoué
LLenain
169

Compilation de ce qui précède et sauvegarde de la position du curseur:

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

Si vous souhaitez appliquer cela lors de l'enregistrement à n'importe quel fichier, omettez le second autocmdet utilisez un caractère générique *:

autocmd BufWritePre * :call <SID>StripTrailingWhitespaces()
stepancheg
la source
9
Vous pouvez améliorer votre fonction en enregistrant également la dernière recherche et en la restaurant. let _s = @ / let @ / = _ s
xApple
3
J'ai supprimé la autocmd FileType c,cpp,java,php,ruby,python partie pour qu'elle s'applique à tous les fichiers.
swt83
8
@xApple: Dans les fonctions internes, l'enregistrement et la restauration de la dernière recherche ne sont pas nécessaires - laisser le contexte de la fonction s'en occupera.
Tobias
3
@ swt83 vous devez également le remplacer <buffer>par *si vous voulez qu'il fonctionne sur tous les fichiers
cadlac
3
Si vous préfixez la commande de substitution w / keepp, cela ne modifiera pas votre historique de recherche, c'estkeepp %s/\s\+$//e
jeberle
68

J'ai aussi généralement:

match Todo /\s\+$/

dans mon .vimrcfichier, afin que les blancs de fin de ligne soient mis en évidence.

Todo étant un nom de groupe de syntaxe hilighting utilisé pour les mots clés hilighting comme TODO, FIXMEou XXX. Il a une couleur de fond jaunâtre ennuyeusement laide, et je trouve que c'est le meilleur pour mettre en évidence les choses que vous ne voulez pas dans votre code :-)

tapis
la source
7
Ou vous pouvez définir la liste et définir listchars + = trail :.
Oli
Excellent - c'est le juste milieu entre la suppression automatique des espaces de fin (même lorsque je ne suis pas au courant, ou lorsque c'est le code de quelqu'un d'autre avec lequel je travaille juste dans le même fichier), que je ne fais rien à ce sujet . Merci.
Daniel Hershcovich
2
malheureusement, mon jeu de couleurs préféré zenburn ne met pas en évidence
Peter Long
@PeterLong, ne fonctionne pas non plus dans le thème des diffusions sur rails. Vérifiez-le avec :hi Todo. J'ai donc parcouru :hi <Tab>et :help hi. J'ai réfléchi Cursoret Error, mais je pense que je vais essayer match VisualNOS /\s\+$/ . Je pourrais combiner cela avec certains des autocmds d'autres réponses ici.
Brady Trainor
51

Je souligne à la fois les espaces blancs finaux existants et je dépouille également les espaces blancs finaux.

Je configure mon éditeur (vim) pour afficher un espace blanc à la fin, par exemple

entrez la description de l'image ici

avec ceci au bas de mon .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()

et je le «supprime automatiquement» des fichiers lors de leur enregistrement, dans mon cas * .rb pour les fichiers ruby, à nouveau dans mon ~ / .vimrc

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

Voici un moyen de filtrer par plus d'un FileType.

autocmd FileType c,cpp,python,ruby,java autocmd BufWritePre <buffer> :%s/\s\+$//e
syvex
la source
Chaque fichier: autocmd FileType * autocmd BufWritePre <buffer>:% s / \ s \ + $ // e
JREAM
7

Copié et collé depuis http://blog.kamil.dworakowski.name/2009/09/unobtrusive-highlighting-of-trailing.html (le lien ne fonctionne plus, mais le bit dont vous avez besoin est ci-dessous)

"Cela a l'avantage de ne pas mettre en surbrillance chaque espace que vous tapez à la fin de la ligne, uniquement lorsque vous ouvrez un fichier ou quittez le mode d'insertion. Très soigné."

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
la source
1
Le lien du blog semble être mort.
Tobias
La même solution se trouve sur ce lien sous "Utilisation de la commande match".
ryanjdillon
6

J'ai vu cette solution dans un commentaire à VIM Wikia - Supprimer les espaces indésirables

J'aime vraiment ça. Ajoute un .sur les espaces blancs indésirables.

entrez la description de l'image ici

Mettez ça dans votre .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
la source
5

Voilà comment je le fais. Je ne me souviens pas où je l'ai volé à tbh.

autocmd BufWritePre * :call <SID>StripWhite()
fun! <SID>StripWhite()
    %s/[ \t]\+$//ge
    %s!^\( \+\)\t!\=StrRepeat("\t", 1 + strlen(submatch(1)) / 8)!ge
endfun
gregf
la source
2
Hum, c'est assez dangereux de le faire sur "*" si vous ouvrez finalement des fichiers binaires, ils peuvent finir dans une assez mauvaise forme.
mat
Ouais probablement pas le plus intelligent, encore une fois, je n'utilise pas vim pour un éditeur hexadécimal non plus. Cela ne s'exécutera que si vous enregistrez.
gregf
Je pense que cela bat l'alternative de répertorier chaque type de fichier sur lequel vous pourriez travailler, non? Je travaille sur rb, php, cs, html, sass, css, js, coffee, xml, xslt, pl, etc, etc, etc ... Y at-il un juste milieu?
Derek Prior
4
À moins que vous n'écriviez dans des fichiers binaires dans vim, cela ne sera probablement jamais un problème.
gregf
Il apparaît dans le premier que %sle drapeau global (g) est aussi inutile qu'un espace à EOL :-)
Jens
3

Une solution qui supprime simplement les espaces de fin du fichier n'est pas acceptable en toutes circonstances. Cela fonctionnera dans un projet qui a eu cette politique depuis le début, et donc il n'y a pas de tels espaces que vous ne vous êtes pas simplement ajoutés dans votre prochain commit.

Supposons que vous souhaitiez simplement ne pas ajouter de nouvelles instances d'espaces de fin, sans affecter les espaces existants dans les lignes que vous n'avez pas modifiées, afin de garder votre validation exempte de modifications qui ne sont pas pertinentes pour votre travail.

Dans ce cas, avec git, vous pouvez utiliser un script comme celui-ci:

#!/bin/sh

set -e # bail on errors

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

C'est-à-dire que nous cachons les modifications, puis filtrons toutes les +lignes dans le diff pour supprimer leurs espaces de fin lorsque nous réappliquons les modifications au répertoire de travail. Si ce canal de commande réussit, nous supprimons la cachette.

Kaz
la source
1

Les autres approches ici n'ont pas fonctionné pour moi dans MacVim lorsqu'elles sont utilisées dans le .vimrcfichier. Voici donc un qui fait et met en évidence les espaces de fin:

set encoding=utf-8
set listchars=trail:·
set list
mb21
la source
Exécution set listchars=trail:·disant: E474: Invalid argument: listchars=trail:·. Pouvez-vous valider votre exemple?
kenorb
0

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

aemonge
la source
0

Pour les personnes qui souhaitent l'exécuter pour des types de fichiers spécifiques (les FileTypes ne sont pas toujours fiables):

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

Ou avec vim7:

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

Si vous coupez des espaces, vous devez seulement le faire sur les fichiers qui sont déjà propres. "Quand à Rome ...". C'est une bonne étiquette lorsque vous travaillez sur des bases de code où des modifications parasites ne sont pas les bienvenues.

Cette fonction détecte les espaces vides et n'active le rognage que s'il était déjà propre.

Le mérite de cette idée revient à un joyau d'un commentaire ici: https://github.com/atom/whitespace/issues/10 (le plus long flux de commentaires de tickets de bogue jamais)

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
la source
Vous pouvez également conserver le registre de recherche let _s=@/et le restaurer à la fin `let @ / = _ s`. Dans ce cas, nous utilisons le registre de trou noir
SergioAraujo