-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Directive blocks are not represented #28
Comments
I took a look at implementing this change in da2b726 I'm not sure it's possible to robustly support the grouping of directives. An example like so seems straight-forward: <%= if true do %>
<%= if true do %>
<% end %>
<% end %> Using heuristics similar to what the HEEx engine uses (i.e. looking at the first/last tokens in the directive,
So far this looks straightforward but there are more complicated cases like so: <%= case x do %>
<%= ^x -> %>X
<%= _x -> %>Not X
<% end %> Which is essentially:
This is still doable. When we nest them though, we're in trouble: <%= if true do %>
<%= case x do %>
<%= ^x -> %>X
<%= _x -> %>Not X
<% end %>
<% end %>
Which And we can't simply use the <%= Enum.map(things, fn _thing -> %>
Thing
<% end) %> Between However for the purposes of indentation, I think it's only necessary to indent when you see a |
Thanks for the detailed response and explanation. Do you mind if I tinker with your change for a day or two and see if I can make it work? The next step for heex-mode is to add better navigation which also required directives to be part of the tree, but it is not essential and if we move towards :if and :for within the tags the effort on this might not be worth the trouble. Just to give some insight on how Emacs treesit (tree-sitter binding ) works according to my understanding. There are 3 parts:
(defvar heex--treesit-indent-rules
(let ((offset heex-indent-level))
`((heex
((node-is "end_tag") parent-bol 0)
((node-is "end_component") parent-bol 0)
((node-is "end_slot") parent-bol 0)
((parent-is "component") parent-bol ,offset)
((parent-is "slot") parent-bol ,offset)
((parent-is "tag") parent-bol ,offset)
)))) It is possible to indent based on siblings, but it gets more tricky as custom functions needs to exists. Adding custom functions makes it possible, but also makes it less elegant and harder to maintain.
|
@the-mikedavis this is the same issue elixir-mode faced with a weak partial parser, but then injected artificial tokens for repeating match blocks to be able to be able to identify: https://github.com/elixir-editors/emacs-elixir/blob/master/elixir-smie.el#LL272C39-L272C39 The change to have an partial and ending_expression will make it possible to solve it in some way, but still probably not a very simple way :). It will be better, thanks. I am not sure to what extend vscode/sublime etc.. uses or will use tree-sitter for indentation, but if this will only be an emacs thing ( and an optional dependency ) then it won't be worth spending too much time on this as it might not be a simple change to nest expressions. In the future if there is time for me to learn how tree-sitter grammar works I would like to attempt to change this. It will help with maintenance moving this complexity to this shared repo. How would backward compatible work if we change this down the road? |
I'm not sure how it works for emacs but with other tree-sitter consumers like nvim or helix, any change that removes/renames nodes is breaking: any queries that include those nodes will fail the query analysis step and be unusable. Adding an The tree-sitter consumers that I know about lock down the versions of the |
I am currently implementing indentation using emacs treesit ( tree-sitter integration ), which uses this library. Everything works well except for directive blocks like
which produces
Since the directive is not the parent of the component there is no simple way of checking parent for indentation.
The text was updated successfully, but these errors were encountered: