MatchParen uses knowledge of how the character under the cursor is highlighted to help guide its matching. However, it is only looking at the top-most item in the syntax stack, which may not match the patterns being checked.
The behavior of matchparen in the following zsh script demonstrates the problem. $ cat foo.zsh #! /bin/zsh Data_Path_Saved="${HOME}/some/valid/path/" SavedFilesList=("${(f@)$(ls ${Data_Path_Saved}**/*(.))}") print "Found ${#SavedFilesList} files." In this case, the problematic line is SavedFilesList=("${(f@)$(ls ${Data_Path_Saved}**/*(.))}") / / \ cursor expected actual match match The syntax of the ")" to the left of the expected match is zshString. This causes searchpairpos() to skip over it when trying to match the "(" under the cursor because it isn't also a "string" syntax item. However, the entire syntax stack for the cursor's position is ['zshParentheses', 'zshString', 'zshSubst', 'zshSubst', 'zshSubstDelim']. The attached patch changes matchparen to check the whole syntax stack. I also added some more comments about exactly how this part works because it took me a few reads to grok what was going on. Hopefully the comments make it a little clearer for the next reader. Cheers, -- James GPG Key: 4096R/331BA3DB 2011-12-05 James McCoy <james...@jamessan.com> -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/plugin/matchparen.vim b/runtime/plugin/matchparen.vim --- a/runtime/plugin/matchparen.vim +++ b/runtime/plugin/matchparen.vim @@ -92,10 +92,17 @@ call cursor(c_lnum, c_col - before) endif - " When not in a string or comment ignore matches inside them. + " Build an expression that detects whether the current cursor position is in + " certain syntax types (string, comment, etc.), for use as searchpairpos()'s + " skip argument. " We match "escape" for special items, such as lispEscapeSpecial. - let s_skip ='synIDattr(synID(line("."), col("."), 0), "name") ' . - \ '=~? "string\\|character\\|singlequote\\|escape\\|comment"' + let s_skip = '!empty(filter(map(synstack(line("."), col(".")), ''synIDattr(v:val, "name")''), ' . + \ '''v:val =~? "string\\|character\\|singlequote\\|escape\\|comment"''))' + " If executing the expression determines that the cursor is currently in + " one of the syntax types, then we want searchpairpos() to find the pair + " within those syntax types (i.e., not skip). Otherwise, the cursor is + " outside of the syntax types and s_skip should keep its value so we skip any + " matching pair inside the syntax types. execute 'if' s_skip '| let s_skip = 0 | endif' " Limit the search to lines visible in the window.