Подтвердить что ты не робот

Удаление заднего пробела только для отредактированных строк

Я добавил следующую функцию в мой .vimrc для удаления конечных пробелов непосредственно перед сохранением

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

Это работает очень хорошо. Однако в некоторых случаях я хотел бы удалить конечные пробелы только из строк, которые я редактировал. Это делается для того, чтобы мой вывод diff выглядел разумным, так как для некоторых устаревших файлов кода почти все строки имеют задние пространства, и я не хочу обременять мой обозреватель кода ненужным различием.

diff -b не является решением прямо сейчас, так как он также игнорирует пробелы из любой точки в строке, и иногда это изменение достаточно важно для включения в вывод diff.

Итак, мой вопрос: можно ли отделять пробельные пробелы только от строк, которые были отредактированы в этом сеансе в файле в vim?

4b9b3361

Ответ 1

mMontu answer имеет правильную идею, но он не обрабатывает регистр. А именно, если я перемещаю курсор вниз, а затем создаю резервную копию, все в режиме редактирования, он не подбирает изменения в этих строках. Если мы хотим справиться с этим, нам нужно сохранить верхнюю и нижнюю строки, которые посетил пользователь. Вот еще более надежный код, со всем сгруппированным в функции:

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

Теперь мы просто вызываем эти функции в нужное время:

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

В качестве альтернативы я написал плагин, который предоставляет эту обновленную функциональность, с несколькими дополнительными функциями, такими как снятие в нормальном режиме.

Ответ 2

Одной из возможностей было бы использовать autocmd InsertLeave для удаления пробелов из текущей строки при каждом выходе из режима вставки:

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

и замените команду подменю StripTrailingWhitespaces() на функцию

s/\s\+$//e

Он будет работать, если все строки, которые вы включаете, не заканчиваются белым цветом пробелы, только последний. Возможно, вы измените строки, которые вы не если вы входите и выходите из режима вставки (i, за которым следует ESC).

Это решение может быть изменено для работы, если вы включаете строки, заканчивающиеся в белом пространстве (например, вставленные строки из унаследованного кода):

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     

Если замена на линии из-за входа и выхода режима вставки (i, за которой следует ESC), является проблемой, тогда решение может сохранить b:changedtick-variable при входе в режим вставки и проверить его при выходе из режима вставки, чтобы обнаружить изменения.

Ответ 3

Я пишу плагин с именем vim-scavenger ', чтобы очистить несколько пустых строк и конечных пробелов.

Просто добавьте следующую конфигурацию в .vimrc:

let g:scavenger_auto_clean_up_on_write = 1

Более подробную информацию вы можете найти в Github repo, чтобы узнать больше. Не стесняйтесь давать мне советы по улучшению плагина.