Answers:
由于我编辑的某些页面实际上需要尾随空格(例如markdown),而其他页面则不需要,因此我设置了一个键绑定,F5以便无需自动即可轻松完成。为此,将以下代码(来自vim.wikia)添加到您的代码.vimrc
:
"Remove all trailing whitespace by pressing F5
nnoremap <F5> :let _s=@/<Bar>:%s/\s\+$//e<Bar>:let @/=_s<Bar><CR>
nnoremap <F5>
F5
在正常模式下对密钥进行 非递归映射:let _s=@/
将最后一个搜索词(来自宏@/
)存储在变量中_s
<Bar>
用作|
分隔命令的管道符号的功能,但是|
会在此上下文中结束命令,因此<Bar>
必须代替使用。:%s/\s\+$//e
搜索尾随空格并将其删除到缓冲区中的所有位置(有关此表达式的详细分类,请参阅CarpetSmoker的答案)let @/=_s
将您的最后一个搜索词恢复到宏@/
,以便下次单击时可用n
。<CR>
结束映射如果您不想去除所有尾随空白,可以使用一种模式来提高选择性。例如,以下代码显示了仅当分号位于分号后(此处与绑定F8)时,才如何剥离尾部空白。
nnoremap <F8> :let _s=@/<Bar>:%s/;\s\+$/;/e<Bar>:let @/=_s<Bar><CR>
如果像我一样,如果您有一些带有markdown之类的文件,例如heredocs,并且这些文件散布在以分号结尾的编程语句中,则这很有用。
:keeppatterns
防止覆盖@/
。还要看看:keepjumps
。
:help keeppattern
,什么也没得到。
:nohl
,如果您要突出显示某个内容,它将继续突出显示它(请参阅我更新的答案)。
“最简单”的方法是只使用:substitute
:
:%s/\s\+$//e
:%s
在整个缓冲区:substitute
范围内运行%
。\s
t匹配所有空白字符。\+
重复一次或多次。$
锚定在该行的末尾。e
如果没有匹配项(即文件已经没有尾随空格),则不发出错误的标志。但是,这可能不是“最佳”方法,因为它会引起两个副作用:
您可以通过将其变为函数来修复这两个项目:
fun! TrimWhitespace()
let l:save = winsaveview()
keeppatterns %s/\s\+$//e
call winrestview(l:save)
endfun
然后像这样使用它:
:call TrimWhitespace()
winsaveview()
将保存当前“视图”,其中包括的光标位置,折叠,跳跃,等等。winrestview()
在最后将从保存变量恢复此。:keeppatterns
防止\s\+$
被添加到搜索历史记录模式。由于一直很麻烦键入内容:call
,因此可以定义一个命令:
command! TrimWhitespace call TrimWhitespace()
可以在不使用的情况下使用:call
:
:TrimWitespace
您当然可以将其绑定到密钥:
:noremap <Leader>w :call TrimWhitespace()<CR>
有些人喜欢在将文件写入磁盘之前自动执行此操作,如下所示:
autocmd BufWritePre * :call TrimWhitespace()
我不喜欢它,因为某些格式需要尾随空格(例如Markdown),而在另一些情况下,甚至需要在代码中尾随空格(例如格式化电子邮件并使用--<Space>
标记来指示签名的开始) )。
无耻的插入模式:不久前,我写了一个Python脚本来一次清理整个项目的空白。
`
在替换完成后按两次即可。这将打开的可能性,以创建这样一个oneliner:%s/\s\+$//e | exe "normal ``"
要删除所有尾随空格(在每行末尾),可以使用以下命令:
:%s/ \+$//
要包含选项卡,请使用\s
而不是空格。
在命令行中:
$ ex +'%s/\s\+$//e' -cwq file.c
当前目录中的所有文件(递归使用**/*.*
):
$ ex +'bufdo!%s/\s\+$//e' -cxa *.*
Python方式:
:py import vim
:pydo vim.current.buffer[linenr - 1] = vim.current.buffer[linenr - 1].strip()
要么:
:py import vim
:py for i, l in enumerate(vim.current.buffer): vim.current.buffer[i] = l.rstrip()
使用lstrip()
用于左带(拖尾),rstrip()
用于右带(超前)或strip()
从两端除去。
这是有用的函数,它可以删除行尾的多余空白,您可以将其添加到您的.vimrc
:
" Removes superfluous white space from the end of a line
function! RemoveWhiteSpace()
:%s/\s*$//g
:'^
"`.
endfunction
也有为此的DeleteTrailingWhitespace插件。
突出空白
要仔细检查所有尾随空格是否消失,请使用:
输入/ $
以找到它们。如果有的话,vim会为您突出显示它们。
使用颜色突出显示它们:
:highlight ws ctermbg=red guibg=red
:match ws /\s\+$/
使用可见字符(来源):
:set encoding=utf-8
:set listchars=trail:·
:set list
另请参阅:高亮显示多余的空间
要在默认情况下突出显示尾随空白,您可以配置.vimrc
如下:
highlight ws ctermbg=red guibg=red
match ws /\s\+$/
autocmd BufWinEnter * match ws / \+$/
默认情况下删除空格
如果要确保在保存时自动删除文件中的所有尾随空白,可以将以下命令添加到您的.vimrc
:
autocmd BufWritePre *.c,*.php :%s/ \+$//ge
不建议这样做,因为它将从用户保存的每个文件中删除尾随空格(即使可能需要空格)。
也可以看看:
克里斯托弗·巴托姆斯(Christopher Bottoms)的回答有些令人惊讶:乔纳森·帕拉迪( Jonathan Palardy)对此写了一篇很好的文章。他在其中编写了一个函数,该函数Preserve(command)
在运行任意命令时保留编辑器的状态(主要是光标位置和最后一个搜索模式):
function! Preserve(command)
" Preparation: save window state
let l:saved_winview = winsaveview()
" Run the command:
execute a:command
" Clean up: restore previous window position
call winrestview(l:saved_winview)
endfunction
这具有多用途的优点,例如,您可以通过将其映射到以下位置来使用它来替换所有尾随空格(就像乔纳森所做的那样):
nnoremap <F5> :call Preserve("%s/\\s\\+$//e")<CR>
您也可以将其用于视觉模式映射,以删除视觉选择的行上的尾随空格:
xnoremap <F5> :call Preserve("'<,'>s/\\s\\+$//e")<CR>
而且您可以将其用于其他调用,例如=
在保留位置的同时使用格式化整个文档(这次最好使用其他密钥,以免发生冲突):
nnoremap <F6> :call Preserve("normal gg=G")<CR>
总而言之,我发现该Preserve(command)
函数是一个不错的工具。
@/
不需要混为一谈(无论如何,在这种情况下)。
winsaveview()
并且winrestview()
远远优于。
StripTrailingSpaces函数的另一个版本:
if !exists('*StripTrailingWhitespace')
function! StripTrailingWhitespace() range
if !&binary && &filetype != 'diff'
call Preserve(":" . a:firstline . "," . a:lastline . "s/\\s\\+$//e")
endif
endfunction
endif
实际上,此功能有一个错误(此错误):由于“范围”选项,该位置没有保留。如果将其删除,效果很好,但是我正在共享代码以获取帮助。
如您所见,它还使用上面所示的Preserve功能,但方式略有不同。
此处的区别在于,我可以选择一个范围的行或段落,vip
然后该范围:'<,'>
将自动出现在命令提示符下。
这个想法来自Bez Hermoso的职位。