2011-11-29 24 views
12

había añadido la siguiente función en mi .vimrc para la eliminación de espacios finales blancos antes de grabarExtracción espacios en blanco finales sólo para líneas editadas

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

autocmd BufWritePre *.h :call <SID>StripTrailingWhitespaces() 
autocmd BufWritePre *.cpp :call <SID>StripTrailingWhitespaces() 
autocmd BufWritePre *.c :call <SID>StripTrailingWhitespaces() 

Funciona muy bien. Sin embargo, en ciertos casos, me gustaría eliminar los espacios blancos finales solo de las líneas que he editado. Esto es para asegurar que mi salida diff se vea cuerda ya que para ciertos archivos de código heredados casi todas las líneas tienen espacios retrospectivos y no quiero cargar mi revisor de código con diferencias innecesarias.

diff -b no es una solución en este momento ya que también ignora los espacios en blanco desde cualquier lugar en una línea y, a veces ese cambio es lo suficientemente importante como para incluirse en la salida diff.

Así que mi pregunta es: ¿es posible quitar los espacios en blanco al final de solo las líneas que se han editado en esta sesión en un archivo en vim?

+1

Tengo una regla de resaltado que destaca (de una manera muy molesta) los espacios en blanco al final, por lo que es muy fácil para mí ver qué espacio debe eliminarse; pero +1 porque sería bueno automatizar la mayor parte de eso. – SingleNegationElimination

+1

¿Por qué no, como una tarea única, quita todos los espacios en blanco finales de todos tus archivos heredados? –

+1

@MatthewStrawbridge Hacer eso oscurece quién escribió (o cambió por última vez) las líneas cuando ejecuta algo como git annotate. (Todavía se puede encontrar, pero lleva pasos adicionales.) –

Respuesta

2

mMontu's answer tiene la idea correcta, pero no maneja un caso extremo. A saber, si muevo el cursor hacia abajo, y luego hacia atrás, todo en el modo de edición, no recoge los cambios en esas líneas. Si nos gustaría manejar esto, entonces necesitamos almacenar las líneas superior e inferior visitadas por el usuario. Aquí hay un código más robusto, con todo agrupan en funciones:

fun! <SID>SetupTrailingWhitespaces() 
    let curline = line('.') 
    let b:insert_top = curline 
    let b:insert_bottom = curline 
endfun 

fun! <SID>UpdateTrailingWhitespace() 
    let curline = line('.') 
    if b:insert_top > curline 
     let b:insert_top = curline 
    elseif b:insert_bottom < curline 
     let b:insert_bottom = curline 
    endif 
endfun 

fun! <SID>StripTrailingWhitespaces() 
    let original_cursor = getpos('.') 
    exe b:insert_top ',' b:insert_bottom 's/\s\+$//e' 
    call setpos('.', original_cursor) 
endfun 

Ahora sólo invocar estas funciones en el momento adecuado:

autocmd InsertEnter * :call <SID>SetupTrailingWhitespaces() 
autocmd InsertLeave * :call <SID>StripTrailingWhitespaces() 
autocmd CursorMovedI * :call <SID>UpdateTrailingWhitespace() 

Por otra parte, he escrito a plugin que proporciona esta funcionalidad actualizada , con varias características adicionales como pelar en modo normal también.

4

Una posibilidad sería utilizar autocmd InsertLeave para despojar a los espacios en blanco de la línea actual cada vez que salga del modo de inserción:

autocmd InsertLeave *.[ch] :call <SID>StripTrailingWhitespaces() 

, y cambiar de comandos sustituto de StripTrailingWhitespaces() función cambió a

s/\s\+$//e 

Se funcionará si todas las líneas que incluye no terminan en espacios blancos , solo el último. Será posible cambiar las líneas que no haya modificado , si ingresa y sale del modo de inserción (i seguido de ESC).

Esta solución se puede cambiar a trabajar si se incluyen las líneas que termina en el espacio blanco (líneas pegadas de código heredado, por ejemplo):

autocmd InsertEnter *.[ch] :let b:insert_start = line('.') 
autocmd InsertLeave *.[ch] :call <SID>StripTrailingWhitespaces() 

fun! StripTrailingWhitespaces() 
    let original_cursor = getpos('.') 
    exe b:insert_start . ',.s/\s\+$//e' 
    call setpos('.', original_cursor) 
endfun  

Si la sustitución de las líneas que han de entrar y el inserto de salida modo (i seguido de ESC) es un problema, entonces la solución podría guardar b:changedtick-variable al ingresar al modo de inserción y verificarlo al salir del modo de inserción para detectar cambios.

0

Escribo un complemento llamado 'vim-scavenger' para limpiar múltiples líneas en blanco y espacios al final.

Simplemente agregue la siguiente configuración en su.vimrc:

let g:scavenger_auto_clean_up_on_write = 1 

Para más detalles, puede llegar a eso Github repo para aprender más. Siéntete libre de darme consejos para mejorar el plugin.

+0

Este complemento ya se ha cambiado a 'vim-janitor'. Por favor, vaya [aquí] (https://github.com/KuoE0/vim-janitor). – KuoE0

Cuestiones relacionadas