¿Cómo puede eliminar automáticamente los espacios en blanco finales en vim

197

Recibo errores de 'espacio en blanco final' al intentar confirmar algunos archivos en git.

Quiero eliminar estos caracteres de espacio en blanco al final automáticamente antes de guardar los archivos de Python.

¿Puedes configurar vim para hacer esto? ¿Si es así, cómo?

Paul D. Eden
fuente
3
esto no solo concierne a Python
2
Use mi complemento DeleteTrailingWhitespace .
Ingo Karkat

Respuestas:

208

Encontré la respuesta aquí .

Agregar lo siguiente a mi archivo .vimrc hizo el truco.

autocmd BufWritePre *.py :%s/\s\+$//e
Paul D. Eden
fuente
1
¡Interesante! El espacio en blanco final es una batalla en el trabajo. Lo detesto, otros no entienden por qué. Usamos tanto vi como vim (yo uso vim; no lo hacen porque tendrían que instalarlo). Tengo un programa que llamo stb para Strip Trailing Blanks y lo uso como filtro; funciona en vi también. Esto es mejor.
Jonathan Leffler el
16
Esto cambia la posición del cursor en cada guardado. ¿Es posible evitarlo?
stepancheg
3
Como esta es la respuesta de facto para esta pregunta, tal vez debería actualizarse para mantener la posición del cursor.
Edu Felipe
2
Esto también eliminará los espacios finales en cadenas de varias líneas, lo que puede no ser deseado en algunos casos. Pero supongo que no hay una manera fácil de evitar esto.
luator
3
Tal vez podría explicar que eal final significa que, si no encontramos el patrón, vi no considera que el comando sustituto haya fallado
LLenain
169

Compilación de la posición del cursor anterior más guardar:

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 desea aplicar esto al guardar en cualquier archivo, omita el segundo autocmdy use un comodín *:

autocmd BufWritePre * :call <SID>StripTrailingWhitespaces()
stepancheg
fuente
9
Puede mejorar su función guardando también la última búsqueda y restableciéndola. let _s = @ / let @ / = _ s
xApple
3
Eliminé la autocmd FileType c,cpp,java,php,ruby,python parte para que se aplique a todos los archivos.
swt83
8
@xApple: no es necesario guardar y restaurar la última búsqueda dentro de las funciones; dejar el contexto de la función se encargará de eso.
Tobias
3
@ swt83 es necesario sustituir también <buffer>con *si usted quiere que funcione en todos los archivos
cadlac
3
Si prefijas el comando sustituto w / keepp, no alterará tu historial de búsqueda, es decirkeepp %s/\s\+$//e
jeberle
68

También suelo tener un:

match Todo /\s\+$/

en mi .vimrcarchivo, de modo que se resaltan los espacios en blanco de fin de línea.

Todo es un nombre de grupo de resaltado de sintaxis que se utiliza para resaltar palabras clave como TODO, FIXMEo XXX. Tiene un color de fondo amarillento molesto y feo, y creo que es lo mejor para ocultar cosas que no quieres en tu código :-)

estera
fuente
77
O puede establecer la lista y establecer listchars + = trail :.
Oli
Excelente: es el punto medio perfecto entre eliminar automáticamente los espacios en blanco finales (incluso cuando no soy consciente de ello, o cuando es el código de otra persona con el que estoy trabajando en el mismo archivo), no hacer nada al respecto . Gracias.
Daniel Hershcovich
2
desafortunadamente, mi esquema de color favorito zenburn no destaca
Peter Long
@PeterLong, tampoco funciona en el tema de railscasts. Compruébalo con :hi Todo. Así que leí detenidamente :hi <Tab>y :help hi. Lo consideré Cursory Error, pero creo que lo intentaré match VisualNOS /\s\+$/ . Podría combinar esto con algunas de las autocmdrespuestas de otras respuestas aquí.
Brady Trainor
51

Destaco los espacios en blanco finales existentes y también elimino los espacios en blanco finales.

Configuro mi editor (vim) para mostrar espacios en blanco al final, por ejemplo

ingrese la descripción de la imagen aquí

con esto en la parte inferior de mi .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()

y lo 'elimino automáticamente' de los archivos al guardarlos, en mi caso * .rb para archivos ruby, nuevamente en mi ~ / .vimrc

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

Aquí hay una manera de filtrar por más de un FileType.

autocmd FileType c,cpp,python,ruby,java autocmd BufWritePre <buffer> :%s/\s\+$//e
syvex
fuente
Cada archivo: autocmd FileType * autocmd BufWritePre <buffer>:% s / \ s \ + $ // e
JREAM
7

Copiado y pegado de http://blog.kamil.dworakowski.name/2009/09/unobtrusive-highlighting-of-trailing.html (el enlace ya no funciona, pero el bit que necesita está debajo)

"Esto tiene la ventaja de no resaltar cada espacio que escribe al final de la línea, solo cuando abre un archivo o sale del modo de inserción. Muy ordenado".

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\+$/
sistema perezoso
fuente
1
El enlace del blog parece haber muerto.
Tobias
La misma solución se encuentra en este enlace en "Uso del comando de coincidencia".
ryanjdillon
6

Vi esta solución en un comentario en VIM Wikia - Eliminar espacios no deseados

Realmente me gustó. Agrega un .en los espacios en blanco no deseados.

ingrese la descripción de la imagen aquí

Pon esto en tu .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
fuente
5

Así es como lo estoy haciendo. No recuerdo dónde lo robé de tbh.

autocmd BufWritePre * :call <SID>StripWhite()
fun! <SID>StripWhite()
    %s/[ \t]\+$//ge
    %s!^\( \+\)\t!\=StrRepeat("\t", 1 + strlen(submatch(1)) / 8)!ge
endfun
Gregg
fuente
2
Hum, es bastante peligroso hacerlo en "*" si eventualmente abres archivos binarios, pueden terminar en una forma bastante mala.
mat
Sí, probablemente no sea el más inteligente, pero tampoco uso vim para un editor hexadecimal. Eso no se ejecutará a menos que guarde.
gregf 01 de
Creo que esto supera la alternativa de enumerar cada tipo de archivo en el que podría trabajar, ¿no? Trabajo en rb, php, cs, html, sass, css, js, coffee, xml, xslt, pl, etc, etc, etc ... ¿Hay algún medio feliz?
Derek Prior
44
A menos que esté escribiendo en archivos binarios en vim, esto probablemente nunca será un problema.
gregf
Aparece en el primero que %sla bandera global (g) es tan inútil como un espacio en EOL :-)
Jens
3

Una solución que simplemente elimina los espacios en blanco finales del archivo no es aceptable en todas las circunstancias. Funcionará en un proyecto que ha tenido esta política desde el principio, por lo que no hay espacios en blanco que no haya agregado en su próxima confirmación.

Suponga que simplemente no desea agregar nuevas instancias de espacios en blanco al final, sin afectar el espacio en blanco existente en las líneas que no editó, para mantener su confirmación libre de cambios que son irrelevantes para su trabajo.

En ese caso, con git, puede usar un script como este:

#!/bin/sh

set -e # bail on errors

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

Es decir, ocultamos los cambios y luego filtramos todas las +líneas en el diff para eliminar su espacio en blanco al volver a aplicar el cambio al directorio de trabajo. Si esta tubería de comando tiene éxito, dejamos caer el alijo.

Kaz
fuente
1

Los otros enfoques aquí de alguna manera no funcionaron para mí en MacVim cuando se usaban en el .vimrcarchivo. Así que aquí hay uno que hace y resalta los espacios finales:

set encoding=utf-8
set listchars=trail:·
set list
mb21
fuente
Ejecutar set listchars=trail:·diciendo: E474: Invalid argument: listchars=trail:·. ¿Puedes validar tu ejemplo?
kenorb
0

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

aemonge
fuente
0

Para las personas que desean ejecutarlo para tipos de archivo específicos (los FileTypes no siempre son confiables):

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
Mr_Pouet
fuente
0

Si recorta los espacios en blanco, solo debe hacerlo en archivos que ya están limpios. "Cuando en Roma...". Esta es una buena etiqueta cuando se trabaja en bases de código donde los cambios espurios no son bienvenidos.

Esta función detecta espacios en blanco al final y activa el recorte solo si ya estaba limpio.

El crédito para esta idea va a la gema de un comentario aquí: https://github.com/atom/whitespace/issues/10 (el flujo de comentarios de boleto de error más largo de la historia)

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
fuente
También puede mantener el registro de búsqueda let _s=@/y restaurarlo al final `let @ / = _ s`. En este caso, estamos utilizando el registro de agujeros negros
SergioAraujo