GNU bug report logs - #67036
30.0.50; treesit-forward-sexp not working properly in ruby-ts-mode

Previous Next

Package: emacs;

Reported by: Juri Linkov <juri <at> linkov.net>

Date: Fri, 10 Nov 2023 07:53:02 UTC

Severity: normal

Fixed in version 30.0.50

Done: Juri Linkov <juri <at> linkov.net>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 67036 in the body.
You can then email your comments to 67036 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to dmitry <at> gutov.dev, bug-gnu-emacs <at> gnu.org:
bug#67036; Package emacs. (Fri, 10 Nov 2023 07:53:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Juri Linkov <juri <at> linkov.net>:
New bug report received and forwarded. Copy sent to dmitry <at> gutov.dev, bug-gnu-emacs <at> gnu.org. (Fri, 10 Nov 2023 07:53:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: bug-gnu-emacs <at> gnu.org
Subject: 30.0.50; treesit-forward-sexp not working properly in ruby-ts-mode
Date: Fri, 10 Nov 2023 09:42:17 +0200
[Message part 1 (text/plain, inline)]
X-Debbugs-Cc: dmitry <at> gutov.dev

Please try these 5 cases described in the comments of this diff:

[ruby-ts-mode.patch (text/x-diff, inline)]
diff --git a/test/lisp/progmodes/ruby-mode-resources/ruby.rb b/test/lisp/progmodes/ruby-mode-resources/ruby.rb
index 81d0dfd75c9..abe6a0789b9 100644
--- a/test/lisp/progmodes/ruby-mode-resources/ruby.rb
+++ b/test/lisp/progmodes/ruby-mode-resources/ruby.rb
@@ -123,6 +123,7 @@ def test2 (arg)
     puts "there"
   end
 
+  # from "elsif" and "then" C-M-f should jump to next "elsif"/"else" like with { }
   if a == 2 then
     puts "hello"
   elsif a == 3
@@ -179,6 +180,7 @@ def test2 (arg)
     bar,
     :a
 
+# when point is after @, C-M-f should jump to the end of symbol
 zzz @abc,
     4
 
@@ -211,10 +213,16 @@ def test2 (arg)
 
 class C
   def foo
-    self.end
+    self.end # when point between 'e' and 'n', C-M-b should jump to "self"
     D.new.class
   end
 
+  class << self
+    def bar
+    end
+  end
+  # C-M-b at the end of "end" should jump to "class"
+
   def begin
   end
 end
@@ -522,6 +530,9 @@ def qux
   puts "Japanese translation: #{orig_text} => #{trans_text}"
 end
 
+# C-M-f on '[' doesn't jump to after ']'
+hash['key']
+
 # Tokenizing "**" and "|" separately.
 def resolve(**args)
   members = proc do |**args|
[Message part 3 (text/plain, inline)]
Is it possible to improve ruby-ts-mode to handle these cases?

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#67036; Package emacs. (Sat, 25 Nov 2023 09:26:01 GMT) Full text and rfc822 format available.

Message #8 received at 67036 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>, Yuan Fu <casouri <at> gmail.com>,
 dmitry <at> gutov.dev
Cc: 67036 <at> debbugs.gnu.org
Subject: Re: bug#67036: 30.0.50;
 treesit-forward-sexp not working properly in ruby-ts-mode
Date: Sat, 25 Nov 2023 11:25:06 +0200
Ping!  Yuan and Dmitry, can we please make some progress here?

> Cc: dmitry <at> gutov.dev
> From: Juri Linkov <juri <at> linkov.net>
> Date: Fri, 10 Nov 2023 09:42:17 +0200
> 
> Please try these 5 cases described in the comments of this diff:
> 
> diff --git a/test/lisp/progmodes/ruby-mode-resources/ruby.rb b/test/lisp/progmodes/ruby-mode-resources/ruby.rb
> index 81d0dfd75c9..abe6a0789b9 100644
> --- a/test/lisp/progmodes/ruby-mode-resources/ruby.rb
> +++ b/test/lisp/progmodes/ruby-mode-resources/ruby.rb
> @@ -123,6 +123,7 @@ def test2 (arg)
>      puts "there"
>    end
>  
> +  # from "elsif" and "then" C-M-f should jump to next "elsif"/"else" like with { }
>    if a == 2 then
>      puts "hello"
>    elsif a == 3
> @@ -179,6 +180,7 @@ def test2 (arg)
>      bar,
>      :a
>  
> +# when point is after @, C-M-f should jump to the end of symbol
>  zzz @abc,
>      4
>  
> @@ -211,10 +213,16 @@ def test2 (arg)
>  
>  class C
>    def foo
> -    self.end
> +    self.end # when point between 'e' and 'n', C-M-b should jump to "self"
>      D.new.class
>    end
>  
> +  class << self
> +    def bar
> +    end
> +  end
> +  # C-M-b at the end of "end" should jump to "class"
> +
>    def begin
>    end
>  end
> @@ -522,6 +530,9 @@ def qux
>    puts "Japanese translation: #{orig_text} => #{trans_text}"
>  end
>  
> +# C-M-f on '[' doesn't jump to after ']'
> +hash['key']
> +
>  # Tokenizing "**" and "|" separately.
>  def resolve(**args)
>    members = proc do |**args|
> 
> Is it possible to improve ruby-ts-mode to handle these cases?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#67036; Package emacs. (Sun, 26 Nov 2023 16:13:02 GMT) Full text and rfc822 format available.

Message #11 received at 67036 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dmitry <at> gutov.dev>
To: Eli Zaretskii <eliz <at> gnu.org>, Juri Linkov <juri <at> linkov.net>,
 Yuan Fu <casouri <at> gmail.com>
Cc: 67036 <at> debbugs.gnu.org
Subject: Re: bug#67036: 30.0.50; treesit-forward-sexp not working properly in
 ruby-ts-mode
Date: Sun, 26 Nov 2023 18:12:41 +0200
I've pushed an update which improves some of these (commit 2ec4526b972).

On 25/11/2023 11:25, Eli Zaretskii wrote:
> Ping!  Yuan and Dmitry, can we please make some progress here?
> 
>> Cc: dmitry <at> gutov.dev
>> From: Juri Linkov <juri <at> linkov.net>
>> Date: Fri, 10 Nov 2023 09:42:17 +0200
>>
>> Please try these 5 cases described in the comments of this diff:
>>
>> diff --git a/test/lisp/progmodes/ruby-mode-resources/ruby.rb b/test/lisp/progmodes/ruby-mode-resources/ruby.rb
>> index 81d0dfd75c9..abe6a0789b9 100644
>> --- a/test/lisp/progmodes/ruby-mode-resources/ruby.rb
>> +++ b/test/lisp/progmodes/ruby-mode-resources/ruby.rb
>> @@ -123,6 +123,7 @@ def test2 (arg)
>>       puts "there"
>>     end
>>   
>> +  # from "elsif" and "then" C-M-f should jump to next "elsif"/"else" like with { }
>>     if a == 2 then
>>       puts "hello"
>>     elsif a == 3
>> @@ -179,6 +180,7 @@ def test2 (arg)
>>       bar,
>>       :a

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.

>> +# 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.

Also, interactive forward-sexp never reports "No next sexp" when inside 
parens or begin...end. It will do forward-up-list instead.

>> @@ -211,10 +213,16 @@ def test2 (arg)
>>   
>>   class C
>>     def foo
>> -    self.end
>> +    self.end # when point between 'e' and 'n', C-M-b should jump to "self"
>>       D.new.class
>>     end

Same as above, although the point will jump to before "end" (after the 
period). And the next C-M-b will jump to before "self".

>> +  class << self
>> +    def bar
>> +    end
>> +  end
>> +  # C-M-b at the end of "end" should jump to "class"
>> +

Now fixed.

>>     def begin
>>     end
>>   end
>> @@ -522,6 +530,9 @@ def qux
>>     puts "Japanese translation: #{orig_text} => #{trans_text}"
>>   end
>>   
>> +# 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.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#67036; Package emacs. (Mon, 27 Nov 2023 17:09:02 GMT) Full text and rfc822 format available.

Message #14 received at 67036 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 67036 <at> debbugs.gnu.org,
 Yuan Fu <casouri <at> gmail.com>
Subject: Re: bug#67036: 30.0.50; treesit-forward-sexp not working properly
 in ruby-ts-mode
Date: Mon, 27 Nov 2023 19:06:05 +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.

>>> +# 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.

> 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.

>>>     def foo
>>> -    self.end
>>> +    self.end # when point between 'e' and 'n', C-M-b should jump to "self"
>
> Same as above, although the point will jump to before "end" (after the
> period). And the next C-M-b will jump to before "self".

This looks right.

>>> +  class << self
>>> +    def bar
>>> +    end
>>> +  end
>>> +  # C-M-b at the end of "end" should jump to "class"
>>> +
>
> Now fixed.

Thanks, confirmed.

>>>     def begin
>>>     end
>>>   end
>>> @@ -522,6 +530,9 @@ def qux
>>>     puts "Japanese translation: #{orig_text} => #{trans_text}"
>>>   end
>>>   +# 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.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#67036; Package emacs. (Tue, 28 Nov 2023 22:17:02 GMT) Full text and rfc822 format available.

Message #17 received at 67036 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dmitry <at> gutov.dev>
To: Juri Linkov <juri <at> linkov.net>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 67036 <at> debbugs.gnu.org,
 Yuan Fu <casouri <at> gmail.com>
Subject: Re: bug#67036: 30.0.50; treesit-forward-sexp not working properly in
 ruby-ts-mode
Date: Wed, 29 Nov 2023 00:15:50 +0200
On 27/11/2023 19:06, Juri Linkov wrote:
>>>>    +  # 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.

>>>> +# 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.

>> 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.

>>>>      def begin
>>>>      end
>>>>    end
>>>> @@ -522,6 +530,9 @@ def qux
>>>>      puts "Japanese translation: #{orig_text} => #{trans_text}"
>>>>    end
>>>>    +# 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.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#67036; Package emacs. (Wed, 29 Nov 2023 07:21:01 GMT) Full text and rfc822 format available.

Message #20 received at 67036 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 67036 <at> debbugs.gnu.org,
 Yuan Fu <casouri <at> gmail.com>
Subject: Re: bug#67036: 30.0.50; treesit-forward-sexp not working properly
 in ruby-ts-mode
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'.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#67036; Package emacs. (Mon, 11 Dec 2023 00:48:02 GMT) Full text and rfc822 format available.

Message #23 received at 67036 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dmitry <at> gutov.dev>
To: Juri Linkov <juri <at> linkov.net>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 67036 <at> debbugs.gnu.org,
 Yuan Fu <casouri <at> gmail.com>
Subject: Re: bug#67036: 30.0.50; treesit-forward-sexp not working properly in
 ruby-ts-mode
Date: Mon, 11 Dec 2023 02:47:10 +0200
On 29/11/2023 09:04, Juri Linkov wrote:
>>>>>>     +  # 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"?

With custom code? Like with other questions, I'm not sure where to plug 
it in.

I guess it's possible to set up a ruby-ts-mode specific wrapper for 
treesit-forward-sexp, but that may not be the most optimal way to do 
that. Anyway, I haven't studied this direction yet.

>>>> 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.

Sounds worth a separate bug-report/feature-request.

>>>>>> +# 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".

IIUC, treesit knows about the bounds of said thing, it just chooses not 
to move in such situation. That just seems like a bug, not a fundamental 
limitaiton.

>>>>>> +# 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'.

Maybe.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#67036; Package emacs. (Mon, 11 Dec 2023 17:22:01 GMT) Full text and rfc822 format available.

Message #26 received at 67036 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 67036 <at> debbugs.gnu.org,
 Yuan Fu <casouri <at> gmail.com>
Subject: Re: bug#67036: 30.0.50; treesit-forward-sexp not working properly
 in ruby-ts-mode
Date: Mon, 11 Dec 2023 19:09:54 +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"?
>
> With custom code? Like with other questions, I'm not sure where to plug it
> in.
>
> I guess it's possible to set up a ruby-ts-mode specific wrapper for
> treesit-forward-sexp, but that may not be the most optimal way to do
> that. Anyway, I haven't studied this direction yet.

Shouldn't treesit-forward-sexp provide a way for ts-modes to override
the default handling?  By default for all ts-modes such a hook could
check if point is inside strings/comments then to use syntax navigation.
And ruby-ts-mode could use such a hook to implement exceptions like
handling 'else'.

>>>>> 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.
>
> Sounds worth a separate bug-report/feature-request.

Such option would be nice, but still need to investigate here
why "No next sexp" not reported inside begin/class/module.

>>>>>>> +# 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".
>
> IIUC, treesit knows about the bounds of said thing, it just chooses not to
> move in such situation. That just seems like a bug, not a fundamental
> limitaiton.

This could be fixed like described above.

>>>>>>> +# 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'.
>
> Maybe.

Idem.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#67036; Package emacs. (Sun, 14 Apr 2024 16:29:02 GMT) Full text and rfc822 format available.

Message #29 received at 67036 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 67036 <at> debbugs.gnu.org,
 Yuan Fu <casouri <at> gmail.com>
Subject: Re: bug#67036: 30.0.50; treesit-forward-sexp not working properly
 in ruby-ts-mode
Date: Sun, 14 Apr 2024 19:25:11 +0300
[Message part 1 (text/plain, inline)]
>>>>>>>> +# 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'.
>
> Shouldn't treesit-forward-sexp provide a way for ts-modes to override
> the default handling?  By default for all ts-modes such a hook could
> check if point is inside strings/comments then to use syntax navigation.

This is now implemented in bug#68993.  So here is the patch that 
handles such cases as C-M-f jumping from '[' to ']' in

  hash[:key]
  hash['key']

and from '{' to '}' in

  "abc #{ghi} def"

[ruby-ts-mode-text.patch (text/x-diff, inline)]
diff --git a/lisp/progmodes/ruby-ts-mode.el b/lisp/progmodes/ruby-ts-mode.el
index 7133cb0b5b0..098cca2cb56 100644
--- a/lisp/progmodes/ruby-ts-mode.el
+++ b/lisp/progmodes/ruby-ts-mode.el
@@ -1171,7 +1171,20 @@ ruby-ts-mode
                                 "global_variable"
                                 )
                                eol)
-                              #'ruby-ts--sexp-p)))))
+                              #'ruby-ts--sexp-p))
+                 (text ,(lambda (node)
+                          (or (member (treesit-node-type node)
+                                      '("comment" "string_content"))
+                              (and (member (treesit-node-text node)
+                                           '("[" "]"))
+                                   (equal (treesit-node-type
+                                           (treesit-node-parent node))
+                                          "element_reference"))
+                              (and (member (treesit-node-text node)
+                                           '("#{" "}"))
+                                   (equal (treesit-node-type
+                                           (treesit-node-parent node))
+                                          "interpolation"))))))))
 
   ;; AFAIK, Ruby can not nest methods
   (setq-local treesit-defun-prefer-top-level nil)

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#67036; Package emacs. (Thu, 02 May 2024 06:32:02 GMT) Full text and rfc822 format available.

Message #32 received at 67036 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: 67036 <at> debbugs.gnu.org
Subject: Re: bug#67036: 30.0.50; treesit-forward-sexp not working properly
 in ruby-ts-mode
Date: Thu, 02 May 2024 09:29:41 +0300
close 67036 30.0.50
thanks

>>>>>>>>> +# 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'.
>>
>> Shouldn't treesit-forward-sexp provide a way for ts-modes to override
>> the default handling?  By default for all ts-modes such a hook could
>> check if point is inside strings/comments then to use syntax navigation.
>
> This is now implemented in bug#68993.  So here is the patch that 
> handles such cases as C-M-f jumping from '[' to ']' in
>
>   hash[:key]
>   hash['key']
>
> and from '{' to '}' in
>
>   "abc #{ghi} def"
>
> diff --git a/lisp/progmodes/ruby-ts-mode.el b/lisp/progmodes/ruby-ts-mode.el

I guess this patch was ok.  So I pushed it to master, and closed.
Anything could be adjusted later if needed.




bug marked as fixed in version 30.0.50, send any further explanations to 67036 <at> debbugs.gnu.org and Juri Linkov <juri <at> linkov.net> Request was from Juri Linkov <juri <at> linkov.net> to control <at> debbugs.gnu.org. (Thu, 02 May 2024 06:32:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Thu, 30 May 2024 11:24:06 GMT) Full text and rfc822 format available.

This bug report was last modified 57 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.