Many thanks to everyone at Panic for creating what’s already a fantastic editor, and an extension framework that is (mostly!) a joy to work with. It’s particularly great to see such extensive and well-written documentation. I really feel motivated to integrate my workflows with Nova.
Having said that, I’m struggling to fully understand how code folding, symbol contexts and scope interact. I’ve published a couple of versions of my R extension so far, but I’ve been going around in circles somewhat when trying to handle function definitions. For background, R allows unbraced single-statement functions like
add1 <- function(x) x+1
and compound functions with curly braces, viz.
add2 <- function(x)
{
return (x + 2)
}
Arguments can be fairly complex, with or without default values, and can potentially include anonymous functions, calls to other functions, etc.
My strategy so far has been to use a match scope to capture assignment with the function
keyword on the right-hand side, a start–end scope to capture the bracketed arguments, and a pair of scopes to match the braces at the beginning and end of blocks, where present. This allows the function name to be symbolicated, and the function code block to fold between the braces, but (presumably) because the function itself has no end-point in this arrangement, argument symbols don’t seem to be available within the function body.
I have looked at various examples from other syntax definitions, but every alternative I’ve tried has produced less successful results than the current one. Whatever I try I can’t get function and argument symbolication and code folding all to work properly. Perhaps I’m thinking about the concepts wrongly – apologies if so – but any pointers would be welcome!
As a subquestion, I was surprised that
<collection name="blocks">
<scope name="r.block.start">
<symbol type="block">
<context behavior="start" group="block" />
</symbol>
<expression>\{</expression>
<capture number="0" name="r.bracket.brace" />
</scope>
<scope name="r.block.end">
<symbol type="block">
<context behavior="end" group="block" />
</symbol>
<expression>\}</expression>
<capture number="0" name="r.bracket.brace" />
</scope>
</collection>
produces code folding between brace-pairs, but
<collection name="blocks">
<scope name="r.blocks">
<symbol type="block">
<context behavior="subtree" group="block" />
</symbol>
<starts-with>
<expression>\{</expression>
<capture number="0" name="r.bracket.brace" />
</starts-with>
<ends-width>
<expression>\}</expression>
<capture number="0" name="r.bracket.brace" />
</ends-width>
<subscopes>
<include syntax="self" collection="all" />
</subscopes>
</scope>
</collection>
does not. In fact, the latter approach (which is the first one I tried) doesn’t match on braces at all, judging from the syntax inspector. This is awkward, because the two-scopes approach doesn’t allow for subscopes so I can’t control parsing within the block.
Sorry to go on for so long!