On 3 Jun 2011, at 00:26, Ben Schmidt wrote: >> I'm experiencing a problem where a valid piece of syntax (a variable >> declaration) sudden;y changes state (becomes an (invalid) procedure >> call) following the insertion elsewhere in the file of an indexed >> assignment. > [...] >> Here is a simple test file that shows the problem, which shows that >> the problem exhibits itself even when the assignment that provokes the >> error is inside a comment. > > This indeed seems very strange. With sync fromstart, I can't imagine why > this would happen, particularly in the case where it's in a comment, as > it's a completely irrelevant syntax item. > > Maybe it's a bug in Vim's syntax engine. We seem to have been finding a > few of those recently. > >> 1. sclProcedureCall is declared earlier in the syntax file than >> sclStringDeclaration. > > Does that matter? Did you try swapping them? If it doesn't matter, > probably not worth mentioning! > >> 2. I use 'foldmethod=syntax' and use folding aggressively to detect >> bad syntax. > > I don't think this is relevant either. With foldmethod=manual the > problem still occurs. > >> 3. sclStringDeclaration is a region with 'start=/\ze\<string\>/ >> skip=/\(\<string\|)\},\)\_s*/ end=/,/ end=/$/' > > Seems a bit different to that in the actual syntax file. The one in the > syntax file seems a bit more sensible, though. > >> 4. The reason for the \ze in the 'start' pattern is to make the folds >> work for declarations and assignments. > > OK. That is helpful to know. > >> 5. An indexed assignment is modelled as a procedure call - it has the >> same semantics as a procedure call returning a reference has. > > OK. > >> Can anyone suggest what might be causing this problem? > > Not yet. Your minimal test data was wonderful, though I've managed to > minimise it even more. This is enough to show the problem: > > string ( 80 ) message := "" > @ )= > > In fact, the problem is easier to see there, because Vim seems to update > more quickly as you edit. Modifying the comment causes the highlighting > to change 'in realtime'. > > I'm still a bit baffled. > > Perhaps work on this even smaller example and see if you can minimise > the syntax file. This example doesn't require a procedure body or > anything like that, so should be able to work with a really small syntax > file, and that should help us pinpoint either the problem with the > syntax file or the bug in Vim.
Here's the smallest sample syntax file that I've so far managed to exhibit both
behaviours (correct and incorrect), minus the highlight groups.
========================================================================
syntax case ignore
syntax sync fromstart
syntax match sclError /\S\+/
syntax match sclError /\k\+/
syntax match sclIdentifier contained /\%(\<string\>\)\@!\<\a\k*\>/
syntax match sclNumber /\<\d\+\>/ contained
syntax match sclStringEsc1 contained
\ /""/
syntax match sclStringEsc2 contained
\ /''/
syntax match sclStringConst
\ /""/
syntax match sclParens contained /[([{})\]]/
syntax match sclComma contained /,/
syntax match sclAssignOp contained /:\==/
"
" Now start building syntactic constructs from them
"
syntax region sclParen fold keepend extend
contains=@sclExpr,@sclAlwaysValid
\ matchgroup=sclParens
\ start=/[[({]/ end=/[])}]/
syntax region sclProcedureCall keepend extend
contains=sclIdentifier,sclActualParameters,@sclAlwaysValid
\ start=/\<\a\k*\>\ze\s*[[({]/
\ end=/[])}]\zs/
syntax match sclType /\<string\>/
syntax region sclStringAssignment fold keepend extend
\ contains=sclProcedureCall,sclAssignOp,@sclStringExpr,
\ @sclAlwaysValid
\ start=/\<\a\k*\>\s*[[({]\_.\{-}[])}]\s*:\==\_s*/
\ skip=/\(:\==\|+\|-\|\<and\>\|\<or\>\|\<after\|\<before\>\)\_s*/
\ end=/\ze,/ end=/\ze;/ end=/$/
syntax region sclStringAssignment fold keepend extend
contains=sclIdentifier,
\ sclAssignOp,@sclStringExpr,@sclAlwaysValid
\ start=/\<\a\k*\>\s*\<is\>\_s*/
\
skip=/\(\<is\>\|+\|-\|\<and\>\|\<or\>\|\<after\|\<before\>\)\_s*/
\ end=/\ze,/ end=/\ze;/ end=/$/
syntax region sclStringAssignment fold keepend extend
contains=sclIdentifier,
\ sclAssignOp,@sclStringExpr,@sclAlwaysValid
\ start=/\<\a\k*\>\s*:\==\_s*/
\ skip=/\(:\==\|+\|-\|\<and\>\|\<or\>\|\<after\|\<before\>\)\_s*/
\ end=/\ze,/ end=/\ze;/ end=/$/
syntax region sclStringAdvisoryLength keepend extend contains=@sclIntExpr,
\ @sclAlwaysValid
\ matchgroup=sclParens
\ start=/(/
\ matchgroup=sclParens
\ end=/)\_s*/
syntax region sclActualParameters fold keepend
contains=sclComment,@sclExpr
\ matchgroup=sclParens
\ start=/[[({]/
\ matchgroup=sclParens
\ end=/[])}]/
syntax region sclStringDeclaration fold keepend extend contains=sclType,
\
sclStringAdvisoryLength,sclStringAssignment,sclIdentifier,
\ sclComma,@sclAlwaysValid
\ start=/\<string\>\_s*\%((\_.\{-})\_s*\)\=/
\ skip=/\(\<string\>\|)\|,\)\_s*/
\ matchgroup=sclSemiColon
\ end=/;/ end=/$/
syntax region sclComment
\ extend
\ start=/@/ end=/\n/ end=/@/
syntax region sclComment contained
\ extend
\ start=/@/ end=/\n/ end=/@/
"
" These clusters group useful types together
"
syntax cluster sclIntOperand contains=sclLocalName,sclIdentifier,sclNumber,
\ sclProcedureCall,sclArithOp,sclParen
syntax cluster sclStringOperand contains=sclIdentifier,sclStringConst,
\ sclProcedureCall,sclStringOp,sclParen
syntax cluster sclIntExpr contains=@sclIntOperand,sclRelOp,sclArithOp
syntax cluster sclStringExpr contains=@sclStringOperand,sclRelOp,sclStringOp
syntax cluster sclExpr contains=@sclStringExpr,@sclSStringExpr,@sclIntExpr,
\ @sclBoolExpr,sclAlwaysValid
syntax cluster sclAlwaysValid contains=sclComment,sclError
========================================================================
If I delete the 'syntax region sclStringAssignment' that contains the
sclProcedureCall, then it stops misbehaving. This is, in fact, probably a more
realistic definition, too, as I was probably trying to overload the clause by
one straw too many - while you can assign a reference a value, you can't do it
as part of a string declaration; I can probably live wigh leaving that as an
sclAnonymousAssignment.
So, while I believe that I have found a bug in the syntax engine, I now have
something that looks, from a distance, like a work-around. Despite that, I'm
prepared to assist in someone else's debugging of this, if I can.
Regards, Andy
--
Andrew Long
andrew dot long at mac dot com
PGP.sig
Description: This is a digitally signed message part
