<HTML><BODY style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space; "><DIV>Hi,</DIV><DIV><BR class="khtml-block-placeholder"></DIV>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.<DIV><BR class="khtml-block-placeholder"></DIV><DIV>Here's an example function:</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>real matrix y_null(real scalar rho, real scalar T) {</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>real matrix y</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>real colvector e</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>real scalar t</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>y = J(T, 2, 0)</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>// use the inverse CDF method to draw from N(0, 1)<SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN></DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>e = invnormal(uniform(T, 1))</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>y[1, 2] = (1 - rho^2) * invnormal(uniform(1, 1))[1, 1]</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>for (t = 1; t < T; t++) {</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>y[t, 1] = rho :* y[t, 2] + e[t]</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>y[(t+1), 2] = y[t, 1]</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>}</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>y[T, 1] = rho :* y[T, 2] + e[T]</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>return(y)</DIV><DIV>}</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>And here are the relevant excerpts from the grammar:</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>patterns = (</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>{<SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>name = 'meta.function.mata';</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>begin = '(?x)</DIV><DIV> (?=</DIV><DIV> ^\s*</DIV><DIV> ((transmorphic|numeric|real|complex|string|pointer)\s+)? # eltype</DIV><DIV> <SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN> ((matrix|vector|colvector|rowvector|scalar)\s+)? # orgtype</DIV><DIV> (\w+)\(.*\)\s+ # function name</DIV><DIV> \{$</DIV><DIV> )';</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>end = '(?<=^\}$)';</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>beginCaptures = { 5 = { name = 'entity.name.function.mata'; }; };</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>patterns = ( { include = '#base'; } );</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>},</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>{<SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>include = '#base'; },</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>);</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>repository = {</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>base = {</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>patterns = (</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>...</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>{<SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>name = 'storage.type.eltype.mata';</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>match = '\b(transmorphic|numeric|real|complex|string|pointer)\b';</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>},</DIV><DIV>...<SPAN class="Apple-tab-span" style="white-space:pre"></SPAN></DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre"> </SPAN>);</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><SPAN class="Apple-style-span">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. </SPAN></DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>Here are the results from Ctrl-Shift-P:</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>With cursor at the beginning of "real"/beginning of line -- source.mata, meta.function.mata, storage.type.eltype.mata</DIV><DIV>With cursor within "real" -- source.mata, meta.function.mata, storage.type.eltype.mata</DIV><DIV>With cursor anywhere else in the function body -- source.mata, meta.function.mata, other scopes from the base repository if relevant</DIV><DIV><B>With "real" selected (by Ctrl-Alt-B or manually) -- source.mata</B></DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>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.</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>Thanks!</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>Michael</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><BR class="khtml-block-placeholder"></DIV></BODY></HTML>