如何让Vim高亮非ASCII字符?

185

我想让 Vim 高亮显示非 ASCII 字符。是否有可用的设置、正则表达式搜索模式或插件来实现?

8个回答

348

在你的搜索中使用[]字符类中的范围,你应该能够排除ASCII十六进制字符范围,因此突出显示(假设你启用了hlsearch)在ASCII范围之外的所有其他字符:

使用[]字符类中的范围,在搜索中可以排除ASCII十六进制字符范围,因此可以突出显示(假设你启用了hlsearch)所有在ASCII范围之外的其他字符。

/[^\x00-\x7F]

这将通过[^]进行负匹配,匹配ASCII 0x00到ASCII 0x7F(0-127)之间的字符,并且在我的简单测试中似乎有效。当然,对于扩展的ASCII,可以使用/[^\x00-\xFF]将范围扩展到\xFF而不是\x7F

您还可以通过\d以十进制表示:

/[^\d0-\d127]

如果您需要更具体的内容,例如排除非可打印字符,您将需要将这些范围添加到字符类[]中。


20
十进制:/ [^ \ d0- \ d127] 的意思是匹配任何不属于 0-127 之间数字的字符。 - Bohr
@Bohr 那是一个不错的补充。我会在上面进行编辑。 - Michael Berkowski
太好了!救了我的一天!一个缩进字符被粘贴到我的Python代码中,导致Unicode错误开始困扰我。在Vim插件使用相同字符的情况下很难检测到! - kollery

41

是的,有一个本地功能可以对任何匹配的字符串进行高亮显示。在 Vim 中执行以下操作:

:help highlight
:help syn-match

syn-match 定义匹配的字符串分组, highlight 定义该分组所使用的颜色。 可以将其用于 vimrc 文件的语法高亮。

因此,您可以在 .vimrc 文件中使用以下命令:

syntax match nonascii "[^\x00-\x7F]"
highlight nonascii guibg=Red ctermbg=2

你不需要在你的vimrc文件中在命令前面加上: - FDinoff
在安装在Ubuntu Server 12.10上的VIM 7.3中,“termbg”似乎不是合法命令。 - dotancohen
4
在安装在Ubuntu Server 12.10上的VIM 7.3中,termbg似乎不是一个合法的参数。 - dotancohen
事实上,普通终端“term”不能有背景颜色,而带有颜色的终端“cterm”可以。 - Dima Tisnek
移除了termbg,但是你也可以添加ctermfg、guifg等来控制前景。 - fatal_error

19

对于其他(从现在开始不那么不幸的)通过搜索引擎到达这里且无法突出非ASCII字符的人,请尝试将以下内容添加到您的.vimrc文件中:

highlight nonascii guibg=Red ctermbg=1 term=standout
au BufReadPost * syntax match nonascii "[^\u0000-\u007F]"

这样做的额外好处是不会与常规(基于文件类型[file extension]的)语法定义发生冲突。


我得到了 E319: 抱歉,此版本中不可用的命令:au BufReadPost * syntax match nonascii "[^\u0000-\u007F]" Press ENTER or type command to continue Linux mint 17.3。 - Nasser
3
尽管已经说明了目标是与已定义的语法定义冲突,但如果您希望这样做,可以在最后一行末尾添加containedin=ALL,使其变为au BufReadPost * syntax match nonascii "[^\u0000-\u007F]" containedin=ALL。当允许Unicode时,我认为这是值得分心的,因为原始答案无法捕获诸如在if语句内部使用非ASCII代码之类的内容... - svenevs
1
在vim中,除非你有非常充分的理由,否则最好将autocmd BufRead ....放在自动组中以确保安全。 - Cbhihe

7
这个正则表达式也可以用于高亮显示。它是从briceolion.com上搜索"vim remove non-ascii characters"的第一个谷歌结果,并且通过:set hlsearch进行高亮显示:
/[^[:alnum:][:punct:][:space:]]/

2
问题要求突出显示非ASCII字符,而不是删除它们 - chutsu
3
谢谢指出,我已编辑我的回答。很容易看出这个正则表达式也以一种不同于其他答案的方式回答了这个问题。我的原始答案是 :%s/[^[:alnum:][:punct:][:space:]]//gc ,它先进行高亮显示,然后再进行替换。 - Grant Bowman
[:alnum:][:punct:][:space:] 是字符类,它们包含 UTF-8 区域设置下的非 ASCII 字符。 - KamilCuk

4
如果您对非打印字符也感兴趣,请使用此代码:/[^\x00-\xff]/ 我在一个函数中使用它:
 function! NonPrintable()
   setlocal enc=utf8
   if search('[^\x00-\xff]') != 0
     call matchadd('Error', '[^\x00-\xff]')
     echo 'Non printable characters in text'
   else
     setlocal enc=latin1
     echo 'All characters are printable'
   endif
 endfunction

你的函数在这里不起作用,它没有高亮显示,而且还搞乱了编码。你为什么要改变本地编码? - Werner
尝试将“enc”更改为“fenc”。我更改了编码,因为我的默认编码是(2013年时)latin1。如果字符集是latin1,则该函数不会突出显示非可打印字符。要查看高亮显示,您必须在颜色语法文件中具有“ERROR”键。这是我的:hi Error guifg=Black guibg=Orange - Reman

2

根据此主题的其他答案和我在这里得到的答案,我已将以下内容添加到我的.vimrc文件中,以便通过键入<C-w>1来控制非ASCII高亮显示。它还会显示在注释中,但是您需要为每个文件语法添加注释组。也就是说,如果您要编辑zsh文件,则需要将zshComment添加到该行。

au BufReadPost * syntax match nonascii "[^\x00-\x7F]" containedin=cComment,vimLineComment,pythonComment

否则它将无法显示非ASCII字符(如果您想确保在所有组中显示非ASCII字符,还可以设置containedin = ALL)。要检查如何在不同的文件类型上调用注释,请打开所需类型的文件并在vim上输入“:sy”,然后在语法项中搜索注释。
function HighlightNonAsciiOff()
  echom "Setting non-ascii highlight off"
  syn clear nonascii
  let g:is_non_ascii_on=0
  augroup HighlightUnicode
  autocmd!
  augroup end
endfunction

function HighlightNonAsciiOn()
  echom "Setting non-ascii highlight on"
  augroup HighlightUnicode
  autocmd!
  autocmd ColorScheme *
        \ syntax match nonascii "[^\x00-\x7F]" containedin=cComment,vimLineComment,pythonComment |
        \ highlight nonascii cterm=underline ctermfg=red ctermbg=none term=underline
  augroup end
  silent doautocmd HighlightUnicode ColorScheme
  let g:is_non_ascii_on=1
endfunction

function ToggleHighlightNonascii()
  if g:is_non_ascii_on == 1
    call HighlightNonAsciiOff()
  else
    call HighlightNonAsciiOn()
  endif
endfunction

silent! call HighlightNonAsciiOn()
nnoremap <C-w>1 :call ToggleHighlightNonascii()<CR>

0

不知何故,以上的答案都对我没用。

所以我使用了:1,$ s/[^0-9a-zA-Z,-_\.]//g

它保留了我感兴趣的大部分字符。


3
这将会删除字符,而操作要求的是突出显示。 - Bernhard Wagner
你是不是指的是[^0-9a-zA-Z,-_.],即-? - ben26941

0

有人已经回答了这个问题。然而,对于仍然遇到问题的其他人,这里提供另一种解决方案来突出显示注释中的非ASCII字符(或任何语法组)。这不是最好的方法,但它是一个临时的解决办法。

可以尝试以下方法:

:syntax match nonascii "[^\u0000-\u007F]" containedin=ALL contained |
            \ highlight nonascii ctermfg=yellow guifg=yellow

这个方案混合了其他解决方案的部分。你可以移除 contained,但是根据文档,可能会存在递归自身的潜在问题(就我所知)。要查看其他定义的模式,syn-contains 部分将包含它。

:help syn-containedin
:help syn-contains 

复制问题来自:如何在vim中将项目设置为更高的突出显示优先级


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