在编程或打开文本文件时遇到行尾带有空格的文件时,这很常见。 vim可以通过在trail选项中设置listchars选项然后打开list来显示此信息。没有插件)?

评论

相应的堆栈溢出问题是如何使用正则表达式删除尾部空白而不删除空行(代码清除)。

这是有关该主题的文档条目。

如果您已安装vim-faq,则可以在此处获得脱机答案::h vim-faq并搜索/ trailing。难记的标签是:h faq-12.1。

#1 楼

使用键绑定删除所有尾随空格

由于我编辑的某些页面实际上需要尾随空格(例如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时可用。


...或者更具选择性

如果遇到某些情况下不想剥离所有尾随空白的情况,可以使用一种模式来更具选择性。例如,以下代码显示了如何仅在尾部空格后加分号(在此处将其与F8绑定)才剥离尾部空格。

nnoremap <F8> :let _s=@/<Bar>:%s/;\s\+$/;/e<Bar>:let @/=_s<Bar><CR>


我,您有一些带有markdown的heredocs文件,这些文件散布在以分号结尾的编程语句中。

评论


尝试:keeppatterns以防止覆盖@ /。还可以看看:keepjumps。

– Bohr
2015年3月7日在6:14

@Bohr您正在使用什么版本的vim?我尝试了:help keeppattern,什么也没得到。

–克里斯托弗下装
2015年3月9日在22:01

@ChristopherBottoms至少为7.4.155版。

– Bohr
2015年3月10日在4:51

@玻尔。谢谢!来发现我仍在使用7.4.0。我安装了最新版本,并且可用。

–克里斯托弗下装
2015年3月10日14:08



您可以通过将此命令包装在函数中来获得相同的效果,因为之后最后一个搜索词会自动恢复:-)这样,您也不必与:nohl混为一谈。继续突出显示它(请参阅我更新的答案)。

–马丁·图尔诺伊(Martin Tournoij)
2015年6月25日在16:39



#2 楼

“最简单”的方法是只使用:substitute
:%s/\s\+$//e



:%s在整个缓冲区:substitute的范围内运行%

\s可以匹配所有空白字符。

\+可以匹配其中的一个或多个字符。

$可以固定在行尾。
e标志如果没有匹配项,则不会给出错误(即文件已经没有尾随空格)。

但是,这可能不是“最佳”方法,因为它会引起两个副作用:

将光标移动到最后一个匹配项;
将命令添加到历史记录和搜索历史中;
重设上一个搜索词。

您可以通过将其变成一个函数来修复这两个项目:
fun! TrimWhitespace()
    let l:save = winsaveview()
    keeppatterns %s/\s\+$//e
    call winrestview(l:save)
endfun

,然后像这样使用它:包括光标位置,折叠,跳转等。最后的winsaveview()将从保存的变量中恢复e。
winrestview()防止将:keeppatterns模式添加到搜索历史记录中。
最后一个搜索项在离开函数后会自动恢复,因此我们无需为此做任何其他事情。

由于一直以来都很难键入\s\+$,因此可以定义一个命令:
:call TrimWhitespace()

不使用:call可以使用以下命令:
您当然可以将其绑定到密钥:
command! TrimWhitespace call TrimWhitespace()


有些人喜欢在将文件写入磁盘之前自动执行此操作,例如:
:TrimWitespace

我不喜欢它,因为某些格式要求尾随空格(例如Markdown),而在某些其他情况下,甚至需要在代码中尾随空格(例如格式化电子邮件,并使用:call标记指示签名的开始。)

无耻的插入模式:不久前,我编写了一个Python脚本来一次清理整个项目的空白。

评论


如果您不想创建移至先前位置的功能,则只需在替换完成后按两次``即可。这样就可以创建像这样的oneliner:%s / \ s \ + $ // e | exe“正常”

–NeaţuOvidiu Gabriel
16 Mar 8 '10:00



@NeaţuOvidiuGabriel,当然,然后在执行oneliner之后,双重反引号将无法正常工作。 ;)

–通配符
17年1月10日在2:04

类似:stackoverflow.com/a/1618401。但是我更喜欢Martin的代码。

–约翰c。 j。
19年1月31日,11:25

#3 楼

要删除所有尾随空格(在每行末尾),可以使用以下命令:

:%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 /\s\+$/



默认情况下删除空格

如果要确保所有尾随空格都在文件会在保存时自动删除,您可以将以下命令添加到您的.vimrc中:

autocmd BufWritePre *.c,*.php :%s/\s\+$//ge


,建议不要这样做,因为它将无条件地删除末尾的空白用户保存的该类型的每个文件都会保存,没有一种好的方法来防止可能需要尾随空格的情况(这种情况很少见,但仍然如此)。


另请参见:



在vim wikia上删除不需要的空间

如何修剪空白(包括标签)?在stackoverflow

如何自动删除结尾的空格?在stackoverflow


#4 楼

克里斯托弗·巴托姆斯(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>


总而言之,我发现=函数是一个不错的工具拥有。

评论


离开函数时,应自动保留最后使用的搜索词;因此,不需要与@ /混为一谈(无论如何,在这种情况下)。

–马丁·图尔诺伊(Martin Tournoij)
2015年6月25日在16:43

winsaveview()和winrestview()优越得多。

–dash-tom-bang
16 Mar 5 '16 at 1:01

非常正确!根据您的反馈进行了更新。

– Alex
17年12月14日在22:13

#5 楼

StripTrailingSpaces函数的另一个版本:

if !exists('*StripTrailingWhitespace')
    function! StripTrailingWhitespace() range
        if !&binary && &filetype != 'diff'
            call Preserve(":" . a:firstline . "," . a:lastline . "s/\s\+$//e")
        endif
    endfunction
endif

" http://technotales.wordpress.com/2010/03/31/preserve-a-vim-function-that-keeps-your-state/
if !exists('*Preserve')
    function! Preserve(command)
        try
            let l:win_view = winsaveview()
             "silent! keepjumps keeppatterns execute a:command
            silent! execute 'keeppatterns keepjumps ' . a:command
        finally
            call winrestview(l:win_view)
        endtry
    endfunction
endif
实际上,此函数中有一个错误(该错误):

位置不正确由于使用“范围”选项而保留。
将其删除,并且效果很好。但是,我正在共享代码以获取帮助。

如您所见,它还使用上面所示的Preserve函数,但方式略有不同。

区别在于,我可以使用vip选择行范围或段落,然后范围:'<,'>将自动出现在命令提示符下。

这个想法来自Bez Hermoso帖子。

评论


关于“我正在共享代码以获取帮助”:您在问一个问题吗?

– Peter Mortensen
19年11月5日在20:14

很抱歉花了这么长时间给您反馈。最终添加了所需的“保留”功能。现在我的回答很有道理了。试图使摆脱尾随空格变得容易。

– SergioAraujo
19年11月10日在11:11