Как вы можете автоматически удалить конечные пробелы в Vim


197

Я получаю ошибки «конечный пробел» при попытке зафиксировать некоторые файлы в git.

Я хочу автоматически удалить эти завершающие пробельные символы непосредственно перед сохранением файлов Python.

Можете ли вы настроить Vim для этого? Если да, то как?


3
это не касается только Python

2
Используйте мой плагин DeleteTrailingWhitespace .
Инго Каркат

Ответы:


208

Я нашел ответ здесь .

Добавление следующего в мой файл .vimrc помогло.

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

1
Интересный! Конечный пробел - битва на работе. Я ненавижу это, другие не понимают почему. Мы используем столько же vi, сколько vim (я использую vim; они не используют, потому что им придется его устанавливать). У меня есть программа, которую я называю stb для Strip Trailing Blanks, и я использую ее в качестве фильтра; работает в ви тоже. Это лучше.
Джонатан Леффлер

16
Это меняет положение курсора при каждом сохранении. Можно ли этого избежать?
степанчег

3
Поскольку это де-факто ответ на этот вопрос, возможно, его следует обновить, чтобы сохранить положение курсора.
Эду Фелипе

2
Это также удалит завершающие пробелы в многострочных строках, что может быть нежелательно в некоторых случаях. Но я думаю, что нет простого способа избежать этого?
Луатор

3
Возможно, вы могли бы явно указать, что eв конце означает, что если мы не нашли шаблон, vi не считает заменяющую команду неудачной
LLenain

169

Компиляция выше плюс сохранение позиции курсора:

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

Если вы хотите применить это при сохранении к любому файлу, пропустите второй autocmdи используйте подстановочный знак *:

autocmd BufWritePre * :call <SID>StripTrailingWhitespaces()

9
Вы могли бы улучшить свою функцию, также сохранив последний поиск и восстановив его. let _s = @ / let @ / = _ s
xApple

3
Я удалил autocmd FileType c,cpp,java,php,ruby,python часть, чтобы применить ее ко всем файлам.
swt83

8
@xApple: внутри функций сохранение и восстановление последнего поиска не требуется - выход из контекста функции позаботится об этом.
Тобиас

3
@ swt83 вы также должны заменить <buffer>на, *если вы хотите, чтобы он работал на всех файлах
cadlac

3
Если вы keeppkeepp %s/\s\+$//e
добавите

68

У меня также обычно есть:

match Todo /\s\+$/

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

Todo - это название группы с подсветкой синтаксиса, которая используется для подсветки ключевых слов, таких как TODO, FIXMEили XXX. Он имеет неприятно уродливый желтоватый цвет фона, и я считаю, что лучше всего выделять то, что вам не нужно в вашем коде :-)


7
Или вы можете установить список и установить listchars + = trail :.
Оли

Отлично - это идеальное промежуточное звено между автоматическим удалением конечных пробелов (даже когда я могу не знать об этом или когда это чей-то код, с которым я просто работаю в одном файле) с тем, чтобы ничего не делать с этим , Спасибо.
Даниэль Гершкович

2
к сожалению, моя любимая цветовая схема Zenburn не выделяется
Питер Лонг

@PeterLong, также не работает в теме Railscasts. Проверьте это с :hi Todo. Так что я просмотрел :hi <Tab>и :help hi. Я считал Cursorи Error, но я думаю , что я буду стараться match VisualNOS /\s\+$/ . Я мог бы объединить это с некоторыми autocmdиз других ответов здесь.
Брейди Трейнор

51

Я выделил существующий конечный пробел и также удалил конечный пробел.

Я настраиваю свой редактор (vim), чтобы он показывал пробел в конце, например

введите описание изображения здесь

с этим в нижней части моего .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()

и я автоматически удаляю его из файлов при сохранении, в моем случае * .rb для файлов ruby, снова в моем ~ / .vimrc

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

13

Вот способ фильтрации по нескольким типам файлов.

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

Каждый файл: autocmd FileType * autocmd BufWritePre <буфер>:% s / \ s \ + $ // e
JREAM

7

Скопировано и вставлено с http://blog.kamil.dworakowski.name/2009/09/unobtrusive-highlighting-of-trailing.html (ссылка больше не работает, но нужный вам бит находится ниже)

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

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
Ссылка на блог, кажется, умерла.
Тобиас

Такое же решение можно найти по этой ссылке в разделе «Использование команды match».
ryanjdillon

6

Я видел это решение в комментарии на VIM Wikia - Удалить ненужные места

Мне действительно это понравилось. Добавляет .на нежелательные пробелы.

введите описание изображения здесь

Поместите это в свой .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

Вот как я это делаю. Я не могу вспомнить, где я украл это из ТБХ.

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

2
Хм, это довольно опасно делать на «*», если вы в конечном итоге откроете бинарные файлы, они могут оказаться в довольно плохой форме.
мат

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

Я думаю, что это лучше, чем перечислять все типы файлов, над которыми вы можете работать, нет? Я работаю над rb, php, cs, html, sass, css, js, coffee, xml, xslt, pl и т. Д. И т. Д. И т. Д. И т. Д. И т. Д. Есть ли счастливая среда?
Дерек Приор

4
Если вы не пишете в двоичные файлы в vim, это, вероятно, никогда не будет проблемой.
gregf

Вначале кажется, что %sглобальный (g) флаг так же бесполезен, как пробел в EOL :-)
Jens

3

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

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

В этом случае с git вы можете использовать такой скрипт:

#!/bin/sh

set -e # bail on errors

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

То есть мы храним изменения, а затем фильтруем все +строки в diff, чтобы удалить их пробелы, когда мы повторно применяем изменения к рабочему каталогу. Если этот командный канал успешен, мы сбрасываем тайник.


1

Другие подходы здесь как-то не работают для меня в MacVim при использовании в .vimrcфайле. Итак, вот что делает и выделяет конечные пробелы:

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

Исполнительный set listchars=trail:·говоря: E474: Invalid argument: listchars=trail:·. Можете ли вы подтвердить свой пример?
Кенорб



0

Для людей, которые хотят запустить его для определенных типов файлов (FileTypes не всегда надежны):

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

Или с vim7:

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

0

Если вы удаляете пробелы, вы должны делать это только с файлами, которые уже очищены. "Когда в Риме...". Это хороший этикет при работе с кодовыми базами, где нежелательные изменения нежелательны.

Эта функция обнаруживает конечные пробелы и включает обрезку, только если она уже была чистой.

В основе этой идеи лежит комментарий: https://github.com/atom/whitespace/issues/10 (самый длинный поток комментариев об ошибках в истории)

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

Вы также можете сохранить регистр поиска let _s=@/и восстановить его в конце `let @ / = _ s`. В этом случае мы используем регистр черной дыры
SergioAraujo
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.