让 Vim 将所有空格都显示为字符

892

我找不到一种方法使Vim将所有的空格都显示为字符。 我发现的都是关于制表符、尾随空格等的。


17
我也在试图解决这个问题。如果您遇到这个问题,请不要再提及 :set list 的响应。那并没有回答我们的问题。(对于其他人来说,下面的 mrucci 的回答是有帮助的,但不算是真正的“解决方案”)。 - ELLIOTTCABLE
2
对于那些说空格可以通过listlistchars看到的人,请考虑一下空格直接跟在制表符后面的情况。在这种情况下,它几乎是看不见的。我同意你可以捕捉到大多数情况,但如果能正确突出显示所有空格就更好了。 - Kevin Cox
12
对于新访客:这在新版本的vim中已经解决了!请查看brettanomyces在下面的答案 - ELLIOTTCABLE
1
相关(但是不同的堆栈):http://vi.stackexchange.com/questions/422/displaying-tabs-as-characters - AncientSwordRage
23个回答

775

正如其他人所说,您可以使用

:set list

这将与其他元素组合使用

:set listchars=...

如何显示不可见字符。
目前,没有一种明确的选项可以用来显示空格,但在listchars中,您可以设置一个除了空格以外的字符来显示其他所有字符。例如,我的设置如下:

:set listchars=eol:$,tab:>-,trail:~,extends:>,precedes:<

所以,现在,在你使用之后

:set list

如果没有显式显示成其他东西,那么一切都是普通的空格。

通常,要了解listchars如何工作,请使用帮助。它提供了许多关于可以显示哪些字符(例如尾随空格)以及如何显示它们的重要信息:

:help listchars

在编辑过程中添加一个切换按钮可能会很有帮助,这样你可以轻松地查看更改(来源:VIM :set list! as a toggle in .vimrc):

noremap <F5> :set list!<CR>
inoremap <F5> <C-o>:set list!<CR>
cnoremap <F5> <C-c>:set list!<CR>

4
“everything that isn't explicitly shown as something else” 的意思是“除了明确表示为其他内容的一切”。您可以尝试使用 Unicode 的 U+2000..U+200A 范围内的空格。如果固定宽度字体支持它们,则它们将像普通的 0x20 空格一样显示。 - ZyX
3
@ZyX - 我并不是在采用整个Unicode,而是使用比较常见的字符集。如果你对这个答案不满意,可以自由提出改进意见。 - Rook
非常好的提示!我建议将_set listchars_行放入.vimrc文件中,这样就可以随时使用:set list轻松启用显示不可见字符的漂亮方式(无需再次搜索此页面)。 - Melebius
9
在vim中,要切换任何东西的方式都是在末尾加上一个感叹号(!)。因此,它变成了:set list!。 - user146043
让我们再来看看 ALL 部分。我正在寻找所有空格的可视化,而这里提到的所有内容都只适用于制表符和尾随空格。有人有显示所有空格的建议吗? - JVApen
2
我使用了中间点 · 作为空格,现在我的VIM看起来很棒!感谢这个技巧~ - benjaminz

384

从补丁7.4.710开始,您现在可以使用listchars设置一个字符来代替空格的显示!

:set listchars+=space:␣

所以,要显示所有的空白字符作为一个字符,你可以采取以下方法:

:set listchars=eol:¬,tab:>·,trail:~,extends:>,precedes:<,space:␣
:set list

完成后,要隐藏看不见的字符,您需要:
:set nolist

讨论邮件列表:https://groups.google.com/forum/?fromgroups#!topic/vim_dev/pjmW6wOZW_Q


2
这很酷,但我想知道为什么行尾字符没有像其他字符一样被着色。 - CMCDragonkai
4
起初我尝试这个方法,但出现了错误。原来我正在使用稍旧版本的gvim,其中“space”不是一个有效选项。升级gvim后问题得以解决。对于其他出现错误的人,请输入“:help listchars”以检查在“listchars”中,“space”是否为有效选项。如果不是,请将vim升级到@brettanomyces所指定的补丁版本。或者,如果您不介意看到空格,则可以将“space”从设置命令中省略。 - Niko Bellic
8
我使用 Unicode 的中间点符号(U+00B7)作为空格字符(space:·),因为它看起来像 MS Word、Notepad++ 等软件中的空格。 - Dinei
7
在vim中输入<C-K>.M可得到·符号。有关详细信息,请参阅:h digraph - johnchen902
4
也许有人会喜欢我选择的符号:set listchars=tab:⇤–⇥,space:·,trail:·,precedes:⇠,extends:⇢,nbsp:× - GottZ
显示剩余7条评论

278

:set list命令用于启用特殊字符的显示。

:set nolist命令用于禁用特殊字符的显示。


14
感谢您向我们展示如何在模式之间切换,您会认为其他高级答案也会教授这一点。 - Jonathan Komar
2
是的,这很有帮助。我希望它能成为最佳答案,因为我自己找到了这个答案,只是发现它已经在网站上了,只是不太显眼。 - Ejoso
13
: set list! 更好 :) - skippr
1
@Skippr 从哪个角度来看呢?除了 Shift!no 更难打之外,它们的按键次数是相同的。如果你要将其放入你的 .vimrc 文件中,我同意感叹号形式更易于阅读。 - Dan Bechard
9
如果您想在相对短的时间内切换打开或关闭此功能,可以使用命令:set list!来完成,无需再输入nolist!符号只是将当前设置的值取反。我经常使用这种方法,特别是在使用:set paste!时。我不喜欢按箭头键查找:set paste或者:set nopaste,哈哈。 - skippr

217

我认为这里的其他答案更全面,但我想分享一个我通常用来视觉区别制表符和空格的技巧:

:syntax on
:set syntax=whitespace

这是针对Whitespace编程语言的语法高亮规则 - 制表符显示为绿色,空格显示为红色。 :)

可以与其他答案提到的:set list结合使用,尽管制表符将显示为^I而没有绿色高亮,但空格将以红色显示。


8
我喜欢这个答案,它相当聪明,感觉比其他大多数答案都更好。不过并不是一个随时可用的解决方案。 - ComputerDruid
5
我更喜欢传统的方法,但我会点赞这个创新的做法。 - Sietse van der Molen
35
我知道语言总会有用处。 - Dan Bechard
1
你介意提供一下你正在使用的 .vim 语法文件的链接来进行代码高亮吗? - Seldom 'Where's Monica' Needy
4
@SeldomNeedy 你不需要下载任何东西,Vim的空格高亮规则已经内置多年了。除非你使用的是奇怪或非常旧的版本,否则它们应该基本上是内置的。 - Eliot
显示剩余3条评论

104

:set list 命令会将所有空格显示为字符。除了空格以外的所有字符都会变得与正常状态不同,这意味着如果您仍然看到一个普通的空格,那么它确实是一个普通的空格。 :)


40
使用 :set nolist 命令来关闭此功能。 - Greg K
6
如果你想看到空格字符(就像在Sublime Text 2中打开“显示空格”一样),该怎么办?我发现这真的很有帮助。 - Olical
不是我来这里的目的,但非常有帮助。谢谢。 - harperville
7
还可以通过在结尾加上 ! 来切换无选项:set list! - baldrs
3
我想设置listchars中的space字符,似乎可以通过space:•来实现。

我的设置如下:

set showbreak=↪\ set listchars=tab:→\ ,eol:↲,nbsp:␣,trail:•,extends:⟩,precedes:⟨,space:•
- Kevin Friedheim

75

如果你设置:

:highlight Search cterm=underline gui=underline ctermbg=none guibg=none ctermfg=none guifg=none

然后执行一个搜索空格的操作,每个空格字符都会显示为下划线字符。

您可以将此命令用于方便的函数中,该函数切换空格的“下划线”状态。

set hls
let g:HLSpace = 1
let g:HLColorScheme = g:colors_name
function ToggleSpaceUnderscoring()
    if g:HLSpace
        highlight Search cterm=underline gui=underline ctermbg=none guibg=none ctermfg=none guifg=none
        let @/ = " "
    else
        highlight clear
        silent colorscheme "".g:HLColorScheme
        let @/ = ""
    endif
    let g:HLSpace = !g:HLSpace
endfunction

使用以下方法将该函数映射到快捷键:

nmap <silent> <F3> <Esc>:call ToggleSpaceUnderscoring()<CR>

NB:在设置颜色方案之后,在vimrc中定义该函数。


1
嗯,这有点像黑客行为,但比迄今为止的任何方法都更接近。赏金已发放!:D - ELLIOTTCABLE

48

根据当前缓冲区的语法规则,类似这样的内容可能有效:

:syn match WhiteSpace / / containedin=ALL conceal cchar=Æ
:setl conceallevel=2 concealcursor=nv

这需要一个带有+conceal功能的vim 7.3

更新于2014年10月24日 稍微详细解释一下,当然可以为隐藏的字符定义一些高亮显示。

  • 您可以配置隐藏字符的外观。要进行突出显示,您至少需要一次配置“Conceal”突出显示组(请参见:h hl-Conceal帮助文档)。这可以在您的颜色方案中完成,然后您就不需要再次重新配置它。但是,这会影响所有隐藏字符(例如,如果您的语法脚本隐藏了其他项目,则它们将显示为白色空格字符)。可能看起来像这样:

    :hi Conceal ctermfg=7 ctermbg=NONE guifg=LightGrey guibg=NONE

  • 似乎有一个特殊情况,即如果语法脚本使用skipwhite关键字,则Vim不会突出显示空格。没有办法绕过它(也许这将被修复,我发布了patch

  • 似乎有一个补丁正在流传,可以自定义在list模式下空格的外观。目前最新的补丁似乎是this one。(这意味着您需要构建自己的Vim才能使用它)。
  • conceallevelconcealcursor是窗口本地选项。这意味着它们可以在不同的窗口中不同(并且可能也会由文件类型插件或其他插件脚本设置)。
  • 每当重新加载语法定义文件时,都需要执行语法突出显示组。这可以使用BufWinEnter甚至可能是SyntaxFileType自动命令来完成。(我没有测试哪个实际上有效)。
最后两个条目意味着,您需要设置一些自动命令来重置语法规则和相应的选项。对于第一个,您可能希望使用ColorScheme自动命令设置高亮显示(这样隐藏的字符始终看起来相同,独立于颜色方案实际设置的内容)。要获得完整的解决方案,请查看romainl的答案,这应该可以让您有一个开端。如果您设置了一个函数,就可以轻松设置一个切换命令来打开或关闭特殊高亮显示。
更新10/26/2014:我将此问题制作成插件
更新04/22/2015:Vim中已包含一个补丁,可使用list选项实现此功能。只需设置set list listchars+=space:␣即可。这适用于Vim 7.4.711

这个很好用!怎样将它添加到.vimrc中? - Eric Martindale
1
由于此操作适用于当前缓冲区,您可能需要将其包装到自动命令中。BufEnter甚至是Syntax自动命令可能适合您: - Christian Brabandt
3
为什么不选择“·”而是用这个奇怪的字符“Æ”呢? - Marius Gedminas
1
这实际上是正确的答案。有什么想法如何为这个字符添加适当的语法高亮?如果它是一个非常淡的·,那就更好了。 - airstrike
@ChristianBrabandt,你的存储库中有许多尾随nrrwrgn相关文件污染了它。 - romainl
@romainl。谢谢。已经修复了。 - Christian Brabandt

31
我使用这个。
/\s
:set hlsearch

为了突出显示空格。它搜索所有的空格,然后启用突出显示以使其突出显示。但是,它不会打印特殊字符。


在我看来,这是最简单的解决方案。结合一个清除搜索的命令非常好(我使用 nnoremap <leader><space> :noh<cr>)。 - Lenna

25
如果您说的是空格字符' ',那么我的建议就是进行搜索/替换操作。正如其他人所暗示的那样,set list会将非打印字符更改为在listchars中配置的可见字符。
要显式显示空格作为其他字符,类似于下面的内容应该可以解决问题: :%s / /█/g 然后只需撤消更改即可返回。
(为了获得█,我按下了这个确切的键序列:%s/ /CTRL-KFB/g

2
我喜欢这个答案胜过其他答案,对我来说它看起来像是 :set list 的反义词,将可见字符('space')改变为一个不可打印的字符。我想知道是否可以在匹配中使用它,比如 :match MyBlackBlockChar "appropriate_regex",那应该能解决问题,对吧? - Sudhi
其他的答案也有用,但这个是第一个真正回答了楼主的问题的,加一。 - Alexx Roche
1
或者使用 :%s/\s/█/g 命令来替换所有的空格。同时,使用 :set hlsearch:&s/\s//gn 命令也是很有用的。 - user1655874

16
下面的代码基于Christian Brabandt的回答,看起来可以实现OP想要的功能:
function! Whitespace()
    if !exists('b:ws')
        highlight Conceal ctermbg=NONE ctermfg=240 cterm=NONE guibg=NONE guifg=#585858 gui=NONE
        highlight link Whitespace Conceal
        let b:ws = 1
    endif

    syntax clear Whitespace
    syntax match Whitespace / / containedin=ALL conceal cchar=·
    setlocal conceallevel=2 concealcursor=c
endfunction

augroup Whitespace
    autocmd!
    autocmd BufEnter,WinEnter * call Whitespace()
augroup END

将这些行添加到您的~/.vimrc文件中,并启动新的Vim会话,以查看仍然不完美的魔法发生。

随意编辑默认颜色和隐藏字符。


注意:在几种语言的*FuncBody语法组中,某些内容会阻止中间点显示。我还不知道如何使该解决方案更加可靠。


这就是我所说的“取决于语法组”的意思,我怀疑这是与syn关键字结合使用skipwhite标志的问题。 - Christian Brabandt
@ChristianBrabandt,是的,除了使它“自动化”之外,我无法超越您已经完成的内容。 - romainl
1
是的,在语法规则中,skipwhite参数防止语法组匹配(尽管它应该允许包含在所有组中)。 - Christian Brabandt
有没有办法让这个与Indent Guides很好地配合使用,它会为缩进添加背景?我怀疑这是一个不覆盖背景颜色的问题,但这似乎并不容易解决。 - Mike
如何在不需要突出显示空格时禁用它?寻找一种简短的切换命令。 - yuvaeasy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接