Subject: bug#67036: 30.0.50; treesit-forward-sexp not working properly in ruby-ts-mode

From: Juri Linkov <[email-masked]>
Date: Wed, 29 Nov 2023 09:04:14 +0200

>>>>>    +  # from "elsif" and "then" C-M-f should jump to next "elsif"/"else"
>>>>>      if a == 2 then
>>>>>        puts "hello"
>>>>>      elsif a == 3
>>>
>>> Try out the change referenced above, but it doesn't do exactly
>>> this. Because the tree-sitter parse tree doesn't match the intuition you
>>> described above.
>> Thanks for adding "then" and "else" that works not bad.
>> Then "elsif" could be added as well.
>
> You can try it and report back. My impression is that it made navigation
> worse: the "elsif" nodes are not siblings of one another, they are
> nested. So it doesn't exactly match your expectations.

Now I tried and indeed it does wrong thing: jumps to the end of the
last "else" instead of the end of own block because they are nested.
But maybe possible to skip "condition" and jump to the end of its
"consequence" before "alternative"?

>>> Also, interactive forward-sexp never reports "No next sexp" when inside
>>> parens or begin...end. It will do forward-up-list instead.
>> On the one hand, it's inconsistent with the default non-treesit behavior
>> of
>> forward-sexp.  On the other hand, the default behavior is too annoying
>> when it screams all the time with "Containing expression ends prematurely!"
>> instead of doing something useful.
>
> Looks like I have been spoiled by Paredit's paredit-forward which catches
> such errors and does the appropriate thing. Might be nice to bring this
> behavior to Emacs as forward-sexp-command, for example.

Agreed, at least as opt-in.

>>>>> +# when point is after @, C-M-f should jump to the end of symbol
>>>>>    zzz @abc,
>>>>>        4
>>>
>>> This is something that would need to be changed somewhere inside
>>> treesit-forward-sexp (or treesit--navigate-thing). The default forward-sexp
>>> behaves differently when in the middle of a symbol.
>> Agreed, more general changes are needed when point is inside symbols,
>> strings, comments, etc.
>
> This is regarding behavior "inside" a thing as understood by
> treesit. Unrelated to Emacs's syntactic entities.

"Inside a thing" could be handled the same way as "inside strings/comments".

>>>>> +# C-M-f on '[' doesn't jump to after ']'
>>>>> +hash['key']
>>>>> +
>>>
>>> As discussed previously, there is no specific node which spans from [ to
>>> ]. Some custom code could probably be written (there *are* leaf nodes for [
>>> and ]), but the current capabilities of treesit-thing-settings don't offer
>>> a good way to plug that in.
>> Like for point inside strings, this might require more general changes
>> that take into account syntax tables.
>
> Possibly, but I expect a solution that doesn't use the syntax table would
> be tried first.

Since there is no available information from treesit, handling
treesit-forward-sexp inside strings/comments could forward to the syntax table
like `prog-fill-reindent-defun' forwards to `fill-paragraph'.