Hi,

I'm developing a bundle for Stata/Mata, and I want to define a grammar such that Ctrl-Alt-B can select an entire function. I would appreciate any pointers.

Here's an example function:

real matrix y_null(real scalar rho, real scalar T) {
real matrix y
real colvector e
real scalar t
y = J(T, 2, 0)
// use the inverse CDF method to draw from N(0, 1)
e = invnormal(uniform(T, 1))
y[1, 2] = (1 - rho^2) * invnormal(uniform(1, 1))[1, 1]
for (t = 1; t < T; t++) {
y[t, 1] = rho :* y[t, 2] + e[t]
y[(t+1), 2] = y[t, 1]
}
y[T, 1] = rho :* y[T, 2] + e[T]
return(y)
}

And here are the relevant excerpts from the grammar:

patterns = (
{ name = 'meta.function.mata';
begin = '(?x)
                     (?=
                     ^\s*
                     ((transmorphic|numeric|real|complex|string|pointer)\s+)? # eltype
     ((matrix|vector|colvector|rowvector|scalar)\s+)?         # orgtype
                     (\w+)\(.*\)\s+                                           # function name
                     \{$
                     )';
end = '(?<=^\}$)';
beginCaptures = { 5 = { name = 'entity.name.function.mata'; }; };
patterns = ( { include = '#base'; } );
},
{ include = '#base'; },
);

repository = {
base = {
patterns = (

...

{ name = 'storage.type.eltype.mata';
match = '\b(transmorphic|numeric|real|complex|string|pointer)\b';
},
...
);



Now, in most regards, this works fine. The name of the function--"y_null"--shows up in the symbol list, and the contained scopes are identified correctly. Also if I cycle through Ctrl-Alt-B when the cursor is not on "real" or at the beginning of the line, the whole function is selected. However, if I hit Ctrl-Alt-B either at the beginning of the first line or within "real", it fails to recognize the meta.function.mata scope. That is, on the first keypress, TextMate recognizes the storage.type.eltype.mata scope and selects "real", but on the second, it skips right to the source.mata scope and selects the whole program instead of just the function. 

Here are the results from Ctrl-Shift-P:

With cursor at the beginning of "real"/beginning of line -- source.mata, meta.function.mata, storage.type.eltype.mata
With cursor within "real" -- source.mata, meta.function.mata, storage.type.eltype.mata
With cursor anywhere else in the function body -- source.mata, meta.function.mata, other scopes from the base repository if relevant
With "real" selected (by Ctrl-Alt-B or manually) -- source.mata

Any ideas on how to workaround this? It's annoying, because if you navigate to a function via the symbol list, it puts the cursor at the beginning of the line by default.

Thanks!

Michael