I’m building a typst editor in GTK4/Rust using GtkSourceView5, and I’m trying to fix a quirk with delimiter auto-pairing (e.g. auto-closing *...*, _..._, $...$, (...)). The correct behaviour depends on which typst syntax context the cursor is currently in, specifically whether it’s in markup mode, code mode, or math mode, since different delimiters are valid in different modes.
Typst contexts can be arbitrarily nested. For example:
#( ← code (parentheses block)
[ ← markup (content block)
#( ← code again
[ ← markup again
$ ← math
I have a custom .lang file with contexts classed code, markup, and math. My problem is determining which of these is the innermost active context at the cursor.
I’ve tried get_context_classes_at_iter returns all active classes as a flat list, e.g. ["no-spell-check", "code", "markup"]. The ordering isn’t reliable enough to determine innermost context, as it varies depending on nesting depth and which contexts are structurally outer containers vs. actual content contexts. For instance, if we have a code mode context encompassing a markup mode context encompassing another code mode context (this sounds convoluted, but is actually rather common when designing templates and the like), the code context is specified once, before the markup context. Selecting only the final context from get_context_classes_at_iter therefore incorrectly gives us markup.
Is there a correct way to determine the innermost/most-specific active syntax context at a given position using the GtkSourceView API? Or is there a better approach for implementing context-sensitive editor behaviour like delimiter pairing? Any advice on language file design that would make this easier would also be very welcome.