Я получаю сообщение об ошибке «конечный пробел» при попытке зафиксировать некоторые файлы в git.
Я хочу автоматически удалить эти завершающие пробельные символы прямо перед сохранением файлов python.
Можете ли вы настроить vim для этого? Если да, то как?
Используйте мой плагин DeleteTrailingWhitespace.
Связанный: Какой самый простой способ удалить конечные пробелы из всех строк в файле? в Vim SE





Нашел ответ здесь.
Добавление следующего в мой файл .vimrc помогло.
autocmd BufWritePre *.py :%s/\s\+$//e
Интересно! Затягивание белого пространства - это настоящая битва. Я ненавижу это, другие не понимают почему. Мы используем столько же vi, сколько и vim (я использую vim; они этого не делают, потому что им придется его установить). У меня есть программа, которую я называю stb для удаления конечных пробелов, и я использую ее как фильтр; работает и в vi. Это лучше.
Это изменяет положение курсора при каждом сохранении. Можно ли этого избежать?
Хорошо, я нашел, ответ ниже.
Поскольку это фактический ответ на этот вопрос, возможно, его следует обновить, чтобы сохранить позицию курсора.
тоже вижу keepjumps: h keepjumps
Вы можете проголосовать за лучший ответ, пока он не станет лучшим из представленных.
Это изменяет позицию курсора при каждом сохранении, однако простой gi вернет вас в предыдущую позицию курсора.
Использование :%!sed -r 's/\s+$//' в качестве команды кажется другим способом (помимо keepjumps) предотвратить перемещение курсора. См. :h filter.
gi переходит на последнюю позицию, в которую был вставлен текст (не всегда позиция курсора перед командой :%s), а :%!sed -r 's/\s+$//' переходит к началу файла. Я не понимаю, как предполагается использовать keepjumps, :keepjumps :%s/\s+$//e, похоже, не делает ничего другого. Я использую :%s/\s\+$//e|normal '', и, похоже, он работает так, как я ожидал (переходит в позицию курсора перед использованием команды :%s).
Поправка к моему предыдущему комментарию: :%s/\s\+$//e|normal '' перейдет в неправильную позицию, если не было найдено конечных пробелов.
Это также удалит конечные пробелы в многострочных строках, что в некоторых случаях может быть нежелательно. Но я думаю, нет простого способа избежать этого?
Возможно, вы могли бы указать, что e в конце означает, что если мы не нашли шаблон, vi не считает заменяющую команду неудачной.
Еще у меня обычно есть:
match Todo /\s\+$/
в моем файле .vimrc, так что пробелы в конце строки подсвечиваются.
Todo - это синтаксическая подсветка имя группы, которая используется для выделения ключевых слов, таких как TODO, FIXME или XXX. У него раздражающе уродливый желтоватый цвет фона, и я считаю, что лучше всего выделять то, что вам нужно не в вашем коде :-)
Или вы можете установить список и установить listchars + = trail :.
Отлично - это идеальная золотая середина между автоматическим удалением конечных пробелов (даже если я не знаю об этом или когда это чей-то код, с которым я просто работаю в одном файле) и ничего не делать с этим. . Спасибо.
к сожалению, моя любимая цветовая схема zenburn не выделяется
@PeterLong, тоже не работает в теме railscasts. Проверьте это с помощью :hi Todo. Поэтому я внимательно просмотрел :hi <Tab> и :help hi. Я рассматривал Cursor и Error, но думаю, что попробую match VisualNOS /\s\+$/ . Я мог бы объединить это с некоторыми из autocmd из других ответов здесь.
Вот как я это делаю. Не могу вспомнить, где я его украл.
autocmd BufWritePre * :call <SID>StripWhite()
fun! <SID>StripWhite()
%s/[ \t]\+$//ge
%s!^\( \+\)\t!\=StrRepeat("\t", 1 + strlen(submatch(1)) / 8)!ge
endfun
Хм, это довольно опасно делать это на "*", если вы в конечном итоге откроете двоичные файлы, они могут оказаться в довольно плохом состоянии.
Да, наверное, не самый умный, но опять же, я не использую vim для шестнадцатеричного редактора. Это не будет выполнено, если вы не сохраните.
Я думаю, что это лучше, чем перечисление каждого отдельного типа файла, с которым вы могли бы работать, не так ли? Я работаю над rb, php, cs, html, sass, css, js, coffee, xml, xslt, pl и т. д., И т. Д. Есть ли золотая середина?
Если вы не пишете двоичные файлы в vim, это, вероятно, никогда не будет проблемой.
Похоже, что в первом %s глобальный флаг (g) так же бесполезен, как пробел в EOL :-)
Компиляция выше плюс сохранение позиции курсора:
function! <SID>StripTrailingWhitespaces()
if !&binary && &filetype != 'diff'
let l:save = winsaveview()
keeppatterns %s/\s\+$//e
call winrestview(l:save)
endif
endfun
autocmd FileType c,cpp,java,php,ruby,python autocmd BufWritePre <buffer> :call <SID>StripTrailingWhitespaces()
Если вы хотите применить это при сохранении к любому файлу, оставьте второй autocmd и используйте подстановочный знак *:
autocmd BufWritePre,FileWritePre,FileAppendPre,FilterWritePre *
\ :call <SID>StripTrailingWhitespaces()
Вы можете улучшить свою функцию, также сохранив последний поиск и восстановив его. let _s = @ / let @ / = _ s
Для других новичков, таких как я, вы ограничиваете файлы, для которых вызывается функция:
Чисто офигенно. Я использую vim, но мне лень обычно искать такие вещи. Это дало мне возможность автоматизировать применение моего арсенала регулярных выражений при сохранении. На данный момент я застрял в использовании Ruby, поэтому мне не нужно вырезать и вставлять мое регулярное выражение, убивающее ракеты.
Я удалил часть autocmd FileType c,cpp,java,php,ruby,python , чтобы применить ее ко всем файлам.
Я не могу понять, почему col (".") Всегда возвращает 1 для меня.
Пришлось добавить *. перед каждым расширением файла.
@xApple: внутри функций сохранение и восстановление последнего поиска не требуется - об этом позаботится выход из контекста функции.
@ swt83 вам также необходимо заменить <buffer> на *, если вы хотите, чтобы он работал со всеми файлами
Есть ли веская причина ограничить это только определенными типами файлов?
Если вы поставите префикс заменяющей команды w / keepp, это не изменит вашу историю поиска, то есть keepp %s/\s\+$//e
Добавьте undojoin, чтобы это не загрязняло вашу историю отмен: autocmd BufWritePre * undojoin | :call <SID>StripTrailingWhitespaces()
Добавьте \m в шаблон, чтобы он не зависел от параметра магия. Сохраните позицию лучше с let l:save = winsaveview() и call winrestview(l:save). Добавьте if !&binary && &filetype != 'diff', чтобы игнорировать двоичные файлы и файлы различий (например, файл патча для удаления пробелов).
Скопировано и вставлено из 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\+$/
Ссылка на блог вроде умерла.
Такое же решение находится в эта ссылка в разделе «Использование команды соответствия».
Вот способ фильтрации по более чем одному типу файла.
autocmd FileType c,cpp,python,ruby,java autocmd BufWritePre <buffer> :%s/\s\+$//e
Каждый файл: autocmd FileType * autocmd BufWritePre <буфер>:% s / \ s \ + $ // e
Я как выделяю существующие конечные пробелы, так и удаляю конечные пробелы.
Я настраиваю свой редактор (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()
Большой! Спасибо !, функция особенно нравится.
Решение, которое просто удаляет конечные пробелы из файла, неприемлемо при любых обстоятельствах. Он будет работать в проекте, в котором эта политика действовала с самого начала, и поэтому нет таких пробелов, которые вы не добавляли бы просто в свой предстоящий коммит.
Предположим, вы хотите просто не добавлять новые экземпляры завершающих пробелов, не затрагивая существующие пробелы в строках, которые вы не редактировали, чтобы ваша фиксация не содержала изменений, не имеющих отношения к вашей работе.
В этом случае с 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, чтобы удалить их конечные пробелы, когда мы повторно применяем изменение к рабочему каталогу. Если этот командный конвейер успешен, мы отбрасываем тайник.
Другие подходы здесь почему-то не работали для меня в MacVim при использовании в файле .vimrc. Итак, вот тот, который выделяет конечные пробелы:
set encoding=utf-8
set listchars=trail:·
set list
Выполнение set listchars=trail:· со словами: E474: Invalid argument: listchars=trail:·. Можете ли вы подтвердить свой пример?
@kenorb см. stackoverflow.com/questions/18321538/…
autocmd BufWritePre * :%s/\s\+$//<CR>:let @/=''<CR>
Для людей, которые хотят запускать его для определенных типов файлов (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
Если вы обрезаете пробелы, вы должны сделать это с помощью Только для уже чистых файлов. "Когда в Риме...". Это хороший этикет при работе с кодовыми базами, где ложные изменения нежелательны.
Эта функция обнаруживает завершающие пробелы и включает обрезку только в том случае, если они уже были чистыми.
Заслуга в этой идее - жемчужина комментария здесь: 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`. В этом случае мы используем регистр черной дыры
Я видел это решение в комментарии на 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()
это касается не только питона