uben0 / tree-sitter-typst

Tree Sitter grammar for Typst
MIT License
114 stars 10 forks source link

Include the hash `#` inside the `(call …)` node #32

Closed lukasjuhrich closed 5 months ago

lukasjuhrich commented 5 months ago

In helix, I use the tree-sitter navigation extensively, especially selecting syntax nodes. Since much of the time I will be reorganizing things, I need to select function call blocks including the hash so I can delete the block and place it where:

#todo[
  put the def before the thm
]
#thm[
  I am a theorem.
]
#def[ I am a definition.]

Trying to select the def at maximum selects def[ I am a definition.], but not the hash. More specifically, :tree-sitter-subtree on that selection gives

(call
  item: (ident)
  (content
    (text)))

while :tree-sitter-subtree on a selection containing the # gives the tree for the whole document. Here is a video illustrating this behavior:

https://github.com/uben0/tree-sitter-typst/assets/10060406/ba3a09ca-962d-492c-a2f8-ce02cb735eaf

Is there a way to include the hash as part of the call node, similar to how the def keyword is part of the function_definition node in a python function definition, as illustrated below?

https://github.com/uben0/tree-sitter-typst/assets/10060406/1065c888-04f3-4aad-a75d-9808428c0219

uben0 commented 5 months ago

Yes, I was aware of this issue, but I was too lazy to fix it, despite finding it irritating while type Typst.

But it's done ! 3924cb9ed9e0e62ce7df9c4fe0faa4c234795999 Now, embedded code have its own node called code.

Could you try on your side the updated grammar and tell me if it works correctly?

PS: Sadly, I don't see any easy way to include the # directly inside the code element. The simplest way was to have it inside a nesting node.

lukasjuhrich commented 5 months ago

Yes, I was aware of this issue, but I was too lazy to fix it, despite finding it irritating while type Typst.

But it's done ! 3924cb9 Now, embedded code have its own node called code.

Amazing! I just tested it and everything works fine. This is extremely helpful as my thesis deadline is approaching, so the quick fix is highly appreciated.

PS: Sadly, I don't see any easy way to include the # directly inside the code element. The simplest way was to have it inside a nesting node.

I think this is also reasonable on a semantic level. At least for me it actually improves a textobject query: Having

(code
  (call
  item: (_)
  (_)+ @function.inside
)) @function.around

instead of

(call
  item: (_)
  (_)+ @function.inside
) @function.around

allows me to define only such function calls with preceding # as a „function“, instead of everything which happens inside math mode. You can see it illustrated here:

https://github.com/uben0/tree-sitter-typst/assets/10060406/a510d2b5-0b2d-4c23-a233-a812e7d4fa3d

In the beginning, I am navigating to the „previous @function.around object“, and before being able to match the code sturcture it would have navigated me to the Pol call inside equation, which is much too fine-grained for my taste. I usually want this movement to select the previous „environment“, which is usually a call to a box, align, #thm, or anything else of that sort, and not some pieces of a math environment.

You can also see in the video that the „outer scope“ navigation works perfectly smoothly and as expected now.

Thanks once again!