在vim中突出显示不匹配的括号

14

我在使用vim编写Python代码时,经常遇到未匹配的括号问题。对于C代码,我喜欢它们是如何处理的 - vim会将所有未匹配的大括号高亮显示为红色。我简要查看了c.vim语法文件以尝试理解它,但处理括号错误的部分非常复杂。有人能够解释一下这段代码是如何工作的,并提出如何编写类似于Python代码的代码吗?

包含未匹配括号的示例C代码:

int main(void
{  /* brace highlighted in red */
}  /* brace highlighted in red */

由于Python代码没有花括号进行突出显示,所以我们必须选择其他东西(例如其他圆括号)。

顺便说一下,我尝试了这个vim插件,但是我对其行为不满意。

编辑:

我正在使用Python生成C++代码(一种喜欢括号和分号的语言)。 我有一个恶习就是在file.write()方法调用的结尾处省略括号。 如果我能让vim更加明显地显示这个错误就好了。

更新:

好的,这是我迄今为止尝试过的内容。

:syn region pParen transparent start="(" end=")" contains=ALL
:syn match pError display ")"
:hi def link pError Error

很不幸,这只是强调所有平衡括号的右括号为错误,而我想要的恰恰相反。我真的不明白我在这里做了什么(只是复制了现有的C语法文件)。如果有人能解释我做错了什么,我将不胜感激。


你能发一些示例代码吗?我使用Python已经将近6年了,从未遇到过这样的问题。如果需要很多括号,你的代码听起来相当不符合Pythonic风格。 - André
7个回答

8
您可以让vim执行相反的操作:执行

:set showmatch

它会突出显示匹配的括号。当它不突出显示任何内容时,您就知道括号不平衡了。
我还假设您熟悉“%”命令,它会将您弹到匹配的元素。

showmatch 只有在配对的括号出现在屏幕上时才会匹配,它不会跳转。 - Rook

6
如果我理解正确,您正在尝试查看在Python中生成的C代码中不匹配的括号,我建议您从Dr Chip's Site安装rainbow.vim。 这将根据缩进级别以不同颜色突出显示大括号,并将如您所请求的那样用红色突出显示不匹配的大括号。 一个屏幕截图http://img294.imageshack.us/img294/8586/rainbow.jpg http://img294.imageshack.us/img294/8586/rainbow.jpg 要安装,请下载rainbow.vim并放置在vimfiles / after / syntax / c /中(如果不存在,请创建此目录)。
在Linux上,这将是~ / .vim / after / syntax / c / rainbow.vim 在Windows上,它可能是c:\ vim \ vimfiles \ after \ syntax \ c \ rainbow.vim或可能在其他地方,请参阅:help runtimepath
请注意,有一些插件与rainbow.vim存在冲突,但是让它们合作并不太难。
如果您想在Python代码中突出显示不匹配的括号,可以修改rainbow.vim以使用Python语法集群而不是C语法集群,但这需要更多的工作,但是您可以使用类似于(Dr Chip的彩虹代码修改版)的东西:
syn cluster pyParenGroup contains=pythonString,pythonRawString,pythonEscape,pythonNumber,pythonBuiltin,pythonException
syn match pyParenError display ')'
syn region  pyParen     transparent matchgroup=hlLevel0 start='(' end=')' contains=@pyParenGroup,pyParen1
syn region  pyParen1        transparent matchgroup=hlLevel1 start='(' end=')' contains=@pyParenGroup,pyParen2
syn region  pyParen2        transparent matchgroup=hlLevel2 start='(' end=')' contains=@pyParenGroup,pyParen3
syn region  pyParen3        transparent matchgroup=hlLevel3 start='(' end=')' contains=@pyParenGroup,pyParen4
syn region  pyParen4        transparent matchgroup=hlLevel4 start='(' end=')' contains=@pyParenGroup,pyParen5
syn region  pyParen5        transparent matchgroup=hlLevel5 start='(' end=')' contains=@pyParenGroup,pyParen6
syn region  pyParen6        transparent matchgroup=hlLevel6 start='(' end=')' contains=@pyParenGroup,pyParen7
syn region  pyParen7        transparent matchgroup=hlLevel7 start='(' end=')' contains=@pyParenGroup,pyParen8
syn region  pyParen8        transparent matchgroup=hlLevel8 start='(' end=')' contains=@pyParenGroup,pyParen9
syn region  pyParen9        transparent matchgroup=hlLevel9 start='(' end=')' contains=@pyParenGroup,pyParen
hi link pyParenError Error

if &bg == "dark"
    hi default   hlLevel0 ctermfg=red         guifg=red1
    hi default   hlLevel1 ctermfg=yellow      guifg=orange1      
    hi default   hlLevel2 ctermfg=green       guifg=yellow1      
    hi default   hlLevel3 ctermfg=cyan        guifg=greenyellow  
    hi default   hlLevel4 ctermfg=magenta     guifg=green1       
    hi default   hlLevel5 ctermfg=red         guifg=springgreen1 
    hi default   hlLevel6 ctermfg=yellow      guifg=cyan1        
    hi default   hlLevel7 ctermfg=green       guifg=slateblue1   
    hi default   hlLevel8 ctermfg=cyan        guifg=magenta1     
    hi default   hlLevel9 ctermfg=magenta     guifg=purple1
else
    hi default   hlLevel0 ctermfg=red         guifg=red3
    hi default   hlLevel1 ctermfg=darkyellow  guifg=orangered3
    hi default   hlLevel2 ctermfg=darkgreen   guifg=orange2
    hi default   hlLevel3 ctermfg=blue        guifg=yellow3
    hi default   hlLevel4 ctermfg=darkmagenta guifg=olivedrab4
    hi default   hlLevel5 ctermfg=red         guifg=green4
    hi default   hlLevel6 ctermfg=darkyellow  guifg=paleturquoise3
    hi default   hlLevel7 ctermfg=darkgreen   guifg=deepskyblue4
    hi default   hlLevel8 ctermfg=blue        guifg=darkslateblue
    hi default   hlLevel9 ctermfg=darkmagenta guifg=darkviolet
endif

编辑:

作为测试,我从ftp://ftp.vim.org/pub/vim/pc/下载了gvim70.zipvim70rt.zip(这些是Vim 7.0的Windows版本)。我将这两个文件解压到一个新目录中,并从vim/vim70/gvim.exe运行gvim.exe。我没有任何vim配置存储在“C:\Documents and Settings”中,因此运行此vim与运行“香草”配置相同。然后,我从amk.ca/python/simple/pyprint.html下载了pyprint.py作为示例代码,并将上述代码复制到名为code.vim的文件中。在gVim中,我输入了:e pyprint.py。它在白色背景窗口中打开,没有语法高亮。然后,我输入了:syntax on,它切换了默认的语法高亮。我在第8行添加了第二个)字符。最后,我输入了:source code.vim,使第二个)字符变成红色高亮显示。

我也在Linux上进行了这个测试(使用Vim 7.2),输入以下命令序列:

cd ~
mv .vimrc old_dot_vimrc
mv .gvimrc old_dot_gvimrc
mv .vim old_dot_vim
vim pyprint.py
:e pyprint.py
" Add extra bracket here!
:syntax on
:source code.vim

再次,第二个括号被突出显示,其他内容似乎正常。


啊!好主意。这并不是严格必要的,因为它本质上定义了哪些匹配项在括号内被突出显示。然而,我已经尝试制作了一个示例,并且似乎可以与我的测试代码一起使用。 - DrAl
这似乎破坏了正确的Python代码的高亮显示。第一个'('后面的所有内容都没有被高亮显示,当我添加不匹配的括号时也没有错误高亮显示。当我向pyParenGroup添加项目时,我会得到一些高亮显示。 - Michael Kristofik
我刚刚尝试了一下从网上获取的一些示例代码,并创建了以下截图(http://img401.imageshack.us/img401/6887/pyprint.png)。它似乎在工作,但我猜可能是因为我对你正在使用的代码风格或你的设置不够了解。 - DrAl
我尝试了图片中的示例代码,但是我没有看到你所说的相同高亮效果。在第一个'('之后唯一高亮的是第9行的字符串。我正在使用gvim版本7.0.237。 - Michael Kristofik
评论框不够长,所以我在上面添加了一个“EDIT”并提供了详细信息。我无法重现这个问题。你能否尝试使用原始配置(没有 .vimrc 等)来查看是否可以在该情况下工作?之后,我们可以尝试确定是什么冲突导致的。 - DrAl
显示剩余4条评论

4

临时解决方案:

:imap ( ()<C-[>i

这将使每次您输入左括号时,它都会自动插入右括号并让您处于在两者之间输入的位置。

在一些已经存在的“字符串”中简单添加“(”符号怎么样? - Mykola Golubyev

3
我不确定这对您来说会更加清晰还是更加混乱,但您可以查看lisp.vim语法文件(特别是处理g:lisp_rainbow的部分),以了解如何突出显示匹配的括号。
如果您成功突出显示所有匹配的括号,则剩余的括号(即未匹配的括号)将具有默认的错误突出显示。这似乎是lisp文件所做的事情。
编辑:这个怎么样?
syn match parenError ")"
syn region matchingParens transparent start="(" end=")" contains=matchingParens
hi parenError guifg=red

如果你输入:syn clear并执行,似乎可以正常工作。请注意,syn命令的执行顺序很重要。根据:h :syn-priority,匹配规则最后生效,这可能是为什么你的规则在文件中突出显示了所有的结束括号。

编辑#2:

c.vim实际上正在突出显示()内部的任何{},无论是否正确关闭。尝试在C模式下键入({}),它仍然将{}标记为错误。

我认为这种方法不能直接用于测试没有匹配)(,因为:syn region不关心结束模式是否存在。

因此,您必须找到一些Python特定的内容,它永远不应该出现在()中。然后匹配"(\_ [^)] * the_forbidden_something"。我不太了解Python,不知道那可能是什么。

如果没有其他办法,您可以执行以下操作:

syn match openParen "(\_[^)]*\%$"

该正则表达式匹配在文件末尾之前没有闭合括号的开放括号。如果它发现任何闭合括号,它就会失败,这意味着它甚至不能捕获(()<EOF>


是的,lisp.vim和c.vim看起来是不错的参考资料。不过,很遗憾,我并不真正理解我所阅读的内容。 :-) - Michael Kristofik
这将突出显示所有额外的右括号为红色。它的副作用是移除括号内的所有高亮。在平衡括号之前,我无法恢复高亮显示。这是一个很好的开始。我们能不能改进一下? - Michael Kristofik

1

你尝试使用matchit.vim了吗?它支持各种匹配,并且应该可以在Python中使用。


0

插件vim-matchopen可以实现您想要的功能


高亮颜色会根据您的配色方案而改变


0
作为一种解决方法,我在vim网站上找到了this indent script,据说它可以更好地缩进Python代码。当您以不平衡的括号结束一行时,它会将下一行缩进以与开放括号对齐。

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