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

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

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

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

это касается не только питона

user3850 11.12.2008 12:47

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

Ingo Karkat 22.06.2012 11:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
205
3
68 860
13
Перейти к ответу Данный вопрос помечен как решенный

Ответы 13

Ответ принят как подходящий

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

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

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

Интересно! Затягивание белого пространства - это настоящая битва. Я ненавижу это, другие не понимают почему. Мы используем столько же vi, сколько и vim (я использую vim; они этого не делают, потому что им придется его установить). У меня есть программа, которую я называю stb для удаления конечных пробелов, и я использую ее как фильтр; работает и в vi. Это лучше.

Jonathan Leffler 15.01.2009 17:06

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

stepancheg 24.10.2009 19:59

Хорошо, я нашел, ответ ниже.

stepancheg 24.10.2009 20:11

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

Edu Felipe 04.05.2011 18:26

тоже вижу keepjumps: h keepjumps

SergioAraujo 01.09.2011 02:03

Вы можете проголосовать за лучший ответ, пока он не станет лучшим из представленных.

Sylvain Defresne 08.12.2011 19:32

Это изменяет позицию курсора при каждом сохранении, однако простой gi вернет вас в предыдущую позицию курсора.

user645579 10.05.2013 01:15

Использование :%!sed -r 's/\s+$//' в качестве команды кажется другим способом (помимо keepjumps) предотвратить перемещение курсора. См. :h filter.

Victor Zamanian 29.05.2013 16:54
gi переходит на последнюю позицию, в которую был вставлен текст (не всегда позиция курсора перед командой :%s), а :%!sed -r 's/\s+$//' переходит к началу файла. Я не понимаю, как предполагается использовать keepjumps, :keepjumps :%s/\s+$//e, похоже, не делает ничего другого. Я использую :%s/\s\+$//e|normal '', и, похоже, он работает так, как я ожидал (переходит в позицию курсора перед использованием команды :%s).
humodz 20.07.2014 03:44

Поправка к моему предыдущему комментарию: :%s/\s\+$//e|normal '' перейдет в неправильную позицию, если не было найдено конечных пробелов.

humodz 20.07.2014 04:49

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

luator 11.08.2015 11:58

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

LLenain 01.12.2016 15:46

Еще у меня обычно есть:

match Todo /\s\+$/

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

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

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

Oli 11.12.2008 10:17

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

Daniel Hershcovich 22.06.2011 11:13

к сожалению, моя любимая цветовая схема zenburn не выделяется

Peter Long 22.07.2011 12:14

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

Brady Trainor 27.07.2014 02:16

Вот как я это делаю. Не могу вспомнить, где я его украл.

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

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

mat 18.12.2008 23:45

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

gregf 02.04.2009 00:43

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

Derek Prior 18.06.2011 05:27

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

gregf 21.06.2011 01:47

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

Jens 06.02.2013 19:41

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

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

xApple 21.06.2011 18:58

Для других новичков, таких как я, вы ограничиваете файлы, для которых вызывается функция:

Jason 18.05.2012 02:28

Чисто офигенно. Я использую vim, но мне лень обычно искать такие вещи. Это дало мне возможность автоматизировать применение моего арсенала регулярных выражений при сохранении. На данный момент я застрял в использовании Ruby, поэтому мне не нужно вырезать и вставлять мое регулярное выражение, убивающее ракеты.

Keith Layne 10.06.2013 22:30

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

swt83 29.08.2013 22:50

Я не могу понять, почему col (".") Всегда возвращает 1 для меня.

Eric Johnson 01.11.2013 18:43

Пришлось добавить *. перед каждым расширением файла.

Michael Stalker 03.12.2013 19:18

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

Tobias 25.02.2014 17:16

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

cadlac 19.05.2014 05:32

Есть ли веская причина ограничить это только определенными типами файлов?

425nesp 20.01.2015 10:21

Если вы поставите префикс заменяющей команды w / keepp, это не изменит вашу историю поиска, то есть keepp %s/\s\+$//e

jeberle 23.07.2016 07:55

Добавьте undojoin, чтобы это не загрязняло вашу историю отмен: autocmd BufWritePre * undojoin | :call <SID>StripTrailingWhitespaces()

tom-james-watson 27.04.2020 13:23

Добавьте \m в шаблон, чтобы он не зависел от параметра магия. Сохраните позицию лучше с let l:save = winsaveview() и call winrestview(l:save). Добавьте if !&binary && &filetype != 'diff', чтобы игнорировать двоичные файлы и файлы различий (например, файл патча для удаления пробелов).

Hans Ginzel 06.01.2021 13:00

Скопировано и вставлено из 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\+$/

Ссылка на блог вроде умерла.

Tobias 25.02.2014 17:18

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

ryanjdillon 02.08.2019 12:07

Вот способ фильтрации по более чем одному типу файла.

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

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

JREAM 10.03.2017 02:19

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

Я настраиваю свой редактор (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()

Большой! Спасибо !, функция особенно нравится.

EHM 15.09.2020 23:49

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

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

В этом случае с 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 16.02.2015 17:16

@kenorb см. stackoverflow.com/questions/18321538/…

mb21 16.02.2015 17:35

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`. В этом случае мы используем регистр черной дыры

SergioAraujo 23.11.2016 16:02

Я видел это решение в комментарии на 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()

Другие вопросы по теме