I'm getting burned repeatedly by unmatched parentheses while writing python code in vim. I like how they're handled for C code - vim highlights in red all of the curly braces following the unmatched paren. I looked at the c.vim
syntax file briefly to try to understand it, but the section that handles bracket errors is very complex. Can anyone explain how that code works and suggest how I might write something similar for python code?
Example C code with unmatched parens:
int main(void
{ /* brace highlighted in red */
} /* brace highlighted in red */
Since python code doesn't have curly braces to highlight, we'll have to choose something else (perhaps other parentheses).
BTW, I tried out this vim plugin but I wasn't happy with the behavior.
Edit:
I'm using python to generate C++ code (a language that likes parentheses and semicolons). I have a nasty habit of leaving the trailing paren off a file.write()
method call. It would be nice if I could get vim to make that mistake more visually obvious.
Update:
Ok, here's what I've tried so far.
:syn region pParen transparent start="(" end=")" contains=ALL
:syn match pError display ")"
:hi def link pError Error
Unfortunately, all this does is highlight as an error the right paren of all balanced parentheses, the opposite of what I want to do. I really don't understand what I'm doing here (just copied off of the existing C syntax file). If anyone could explain what I did (wrong), I would appreciate it.
As a workaround, I found this indent script on the vim website that supposedly does a better job of indenting Python code. When you end a line with unbalanced parens, it indents the next line to line up with the open paren.
You can get vim to do the opposite: do a
and it will highlight matching parens. You'll know when you're unbalanced when it doesn't highlight something.
I'm also assuming you're familiar with the '%' command, which bounces you to the matching element.
The plugin vim-matchopen does what you are looking for
The highlight color changes based on your colorscheme
If I understand correctly and you are trying to look at non-matching parenthesis in C code (that was generated in python), I would recommend you install rainbow.vim from Dr Chip's Site. This will highlight braces in different colours depending on the levels of indentation and will highlight unmatching braces in red as you have requested. A screenshot http://img294.imageshack.us/img294/8586/rainbow.jpg http://img294.imageshack.us/img294/8586/rainbow.jpg
To install, download
rainbow.vim
and place invimfiles/after/syntax/c/
(create this directory if it is not present).On Linux, this will be
~/.vim/after/syntax/c/rainbow.vim
On Windows, it may be
c:\vim\vimfiles\after\syntax\c\rainbow.vim
or possibly somewhere else, see:help runtimepath
.Note that there are some plugins that conflict with
rainbow.vim
, but it's not too hard to make them co-operate.If you are trying to highlight non-matching parenthesis in the python code, you could modify rainbow.vim to use the python syntax clusters instead of the C ones, but this is a little more involved, but you could use something along the lines of (modified version of Dr Chip's rainbow code):
EDIT:
As a test, I downloaded gvim70.zip and vim70rt.zip from ftp://ftp.vim.org/pub/vim/pc/ (these are the Windows versions of Vim 7.0). I unzipped the two files into a new directory and ran
gvim.exe
fromvim/vim70/gvim.exe
. I do not have any vim configuration stored in "C:\Documents and Settings", so running this vim is the same as running a 'vanilla' configuration. I then downloadedpyprint.py
from amk.ca/python/simple/pyprint.html as a piece of sample code and copied the above code into a file called code.vim. In gVim, I entered:e pyprint.py
. It opened in the white-background window, with no syntax highlighting. I then entered:syntax on
, which switched the default syntax highlighting on. I added a second)
character on line 8. Finally, I entered:source code.vim
, which made the second)
character be highlighted in red.I've also carried out this test on Linux (with Vim 7.2), by entering the following command sequence:
Again, the second bracket is highlighted and everything else seems normal.
Not sure if it'll be more or less confusing for you, but you could look at the
lisp.vim
syntax file (especially the part whereg:lisp_rainbow
is handled) to see how you can highlight matching parens.If you manage to highlight all the matching parens, you could have the leftover parens (i.e. unmatched parens) have default Error highlighting. This is what the lisp file seems to be doing.
EDIT: How about this:
If you
:syn clear
and run those, it seems to work. Note that the order thesyn
commands are executed matters. Per:h :syn-priority
, the rule matched last is the one that takes effect, which may be why your rules highlighted all the end-parens in the file.EDIT #2:
What c.vim is actually doing is highlighting any
{}
inside of()
, whether everything is properly closed or not. Try typing({})
in C mode, it still highlights the{}
as an error.I don't think this approach can be used to test directly for a
(
with an unmatched)
, because:syn region
doesn't care whether the end-pattern is there or not.So you have to find something Python-specific that should never belong inside
()
. Then match against"(\_[^)]*the_forbidden_something"
. I don't know Python enough to know what that might be.If nothing else, you can do:
which matches an open paren with no closing parens before the end-of-file. This fails if it finds any closing paren at all, which means it won't even catch
(()<EOF>
.Stop gap solution:
This will make it so every time you type a left paren it will automatically put in the right and put you in the position of typing in between.