[TxMt] How to match recursive blocks when begin goes over two lines
Andreas Pardeike
andreas at pardeike.net
Fri Sep 15 13:26:50 UTC 2006
Hi,
I am slowly adapting to the language defs. Great.
Now, I am having difficulties to specify recursive blocks for a
language.
So far, I got it working pretty good for things like
-----------------
%function foo() {
%{
%}
%}
-----------------
as I created a matcher for {%..%} that calls itself and thus the matcher
for the function which for simplicity I state here as
begin = '%function .*\(\) \{'
end = '%}'
will match the last %} and not the previous one. Cool.
Now, how do I allow for this case:
---------------
%function foo()
{
%{
%}
%}
---------------
I can't get it to work even though I know that the matcher only
matches whole
lines. The language I try to define is an obsolete old IBM mainframe
macro
language called Net.DATA (please, don't ask why).
So a block starts either as '%keyword_and_more {' or as '%
keyword_and_more\n{'
and always ends in '%}'.
Is it possible to define this? I assume that I need to define two
rule sets to
simulate the two states and then either start in state A or B and do the
recursion within each set. Right?
Andreas Pardeike
PS: If you like, you can see my current definition:
{ scopeName = 'source.netdata';
fileTypes = ( '' );
foldingStartMarker = '%.*\{|%(?i:if)';
foldingStopMarker = '%\}|%(?i:endif)';
patterns = (
{ include = '#embeddedstuff'; },
{ name = 'source.netdata.comment';
match = '^%\{.*?%\}';
},
);
repository =
{ embeddedstuff = { patterns = (
{ include = '#shtml'; },
{ include = '#netdata'; },
);
};
netdata = { patterns = (
{ name = 'keyword.control.netdata.conditional';
match = '%(?i:if|else|endif)';
},
{ name = 'keyword.control.netdata.include';
match = '%(?i:include).*';
},
{ name = 'keyword.control.shtml.include';
match = '<!--#%(?i:include).*-->';
},
{ name = 'source.netdata.block';
begin = '(%\{(?i:macro)?)';
end = '(%\})';
captures = { 1 = { name = 'keyword.control.netdata'; }; };
patterns = ( { include = '#embeddedstuff'; } );
},
{ name = 'source.netdata.function';
begin = '(%function\s*\(([^)]*)\))\s+(\w+\(.*\))\s*(\{)';
end = '(%\})';
captures =
{ 1 = { name = 'keyword.control.netdata'; };
2 = { name = 'source.netdata.function.type'; };
3 = { name = 'source.netdata.function.name'; };
};
patterns = ( { include = '#embeddedstuff'; } );
},
{ name = 'source.netdata.block';
begin = '(%.*?)\s*\(.*\)\s*(\{)';
end = '(%\})';
captures =
{ 1 = { name = 'keyword.control.netdata'; };
2 = { name = 'keyword.control.netdata'; };
};
patterns = ( { include = '#embeddedstuff'; } );
},
{ name = 'source.netdata.block';
begin = '(%.*)\s?(\{)';
end = '(%\})';
captures =
{ 1 = { name = 'keyword.control.netdata'; };
2 = { name = 'keyword.control.netdata'; };
};
patterns = ( { include = '#embeddedstuff'; } );
},
);
};
shtml =
{ name = 'source.netdata.embedded.shtml';
begin = '(?=<!--#)';
end = '-->';
patterns = (
{ name = 'keyword.control.shtml.include';
match = '(?i:include.*?=".*?")';
}
);
};
};
}
More information about the textmate
mailing list