GNU bug report logs - #78703
beginning-of-defun and friends still wrong in typescript-ts-mode

Previous Next

Package: emacs;

Reported by: Daniel Colascione <dancol <at> dancol.org>

Date: Thu, 5 Jun 2025 23:41:02 UTC

Severity: normal

To reply to this bug, email your comments to 78703 AT debbugs.gnu.org.

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

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


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#78703; Package emacs. (Thu, 05 Jun 2025 23:41:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Daniel Colascione <dancol <at> dancol.org>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Thu, 05 Jun 2025 23:41:02 GMT) Full text and rfc822 format available.

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

From: Daniel Colascione <dancol <at> dancol.org>
To: bug-gnu-emacs <at> gnu.org
Subject: beginning-of-defun and friends still wrong in typescript-ts-mode
Date: Thu, 05 Jun 2025 16:40:03 -0700
Right now, C-M-a runs treesit-beginning-of-defun which goes to the
start of the previous defun in buffer text, not the enclosing defun.

If we have this program:

    1 function foo() {
    2   function bar() {
    3     return 5
    4   }
    5   return 7
    6 }


and point is on line 5, then if we hit C-M-a, point goes to line 2, not
line 1.  In every single situation, when I use beginning-of-defun, I
intend to go to the start of my enclosing defun not the one that happens
to be previous in buffer linearization.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78703; Package emacs. (Fri, 06 Jun 2025 07:02:02 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Daniel Colascione <dancol <at> dancol.org>,
 Yuan Fu <casouri <at> gmail.com>
Cc: 78703 <at> debbugs.gnu.org
Subject: Re: bug#78703: beginning-of-defun and friends still wrong in
 typescript-ts-mode
Date: Fri, 06 Jun 2025 10:01:20 +0300
> From: Daniel Colascione <dancol <at> dancol.org>
> Date: Thu, 05 Jun 2025 16:40:03 -0700
> 
> Right now, C-M-a runs treesit-beginning-of-defun which goes to the
> start of the previous defun in buffer text, not the enclosing defun.
> 
> If we have this program:
> 
>     1 function foo() {
>     2   function bar() {
>     3     return 5
>     4   }
>     5   return 7
>     6 }
> 
> 
> and point is on line 5, then if we hit C-M-a, point goes to line 2, not
> line 1.  In every single situation, when I use beginning-of-defun, I
> intend to go to the start of my enclosing defun not the one that happens
> to be previous in buffer linearization.

I think you want to set treesit-defun-tactic to 'top-level'.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78703; Package emacs. (Fri, 06 Jun 2025 07:24:02 GMT) Full text and rfc822 format available.

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

From: Yuan Fu <casouri <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Daniel Colascione <dancol <at> dancol.org>, 78703 <at> debbugs.gnu.org
Subject: Re: bug#78703: beginning-of-defun and friends still wrong in
 typescript-ts-mode
Date: Fri, 6 Jun 2025 00:23:23 -0700

> On Jun 6, 2025, at 12:01 AM, Eli Zaretskii <eliz <at> gnu.org> wrote:
> 
>> From: Daniel Colascione <dancol <at> dancol.org>
>> Date: Thu, 05 Jun 2025 16:40:03 -0700
>> 
>> Right now, C-M-a runs treesit-beginning-of-defun which goes to the
>> start of the previous defun in buffer text, not the enclosing defun.
>> 
>> If we have this program:
>> 
>>    1 function foo() {
>>    2   function bar() {
>>    3     return 5
>>    4   }
>>    5   return 7
>>    6 }
>> 
>> 
>> and point is on line 5, then if we hit C-M-a, point goes to line 2, not
>> line 1.  In every single situation, when I use beginning-of-defun, I
>> intend to go to the start of my enclosing defun not the one that happens
>> to be previous in buffer linearization.
> 
> I think you want to set treesit-defun-tactic to 'top-level’.

Yes. Most likely top-level is what you want. 

Yuan






Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78703; Package emacs. (Fri, 06 Jun 2025 07:58:01 GMT) Full text and rfc822 format available.

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

From: Daniel Colascione <dancol <at> dancol.org>
To: Yuan Fu <casouri <at> gmail.com>, Eli Zaretskii <eliz <at> gnu.org>
Cc: 78703 <at> debbugs.gnu.org
Subject: Re: bug#78703: beginning-of-defun and friends still wrong in typescript-ts-mode
Date: Fri, 06 Jun 2025 00:57:36 -0700

On June 6, 2025 12:23:23 AM PDT, Yuan Fu <casouri <at> gmail.com> wrote:
>
>
>> On Jun 6, 2025, at 12:01 AM, Eli Zaretskii <eliz <at> gnu.org> wrote:
>> 
>>> From: Daniel Colascione <dancol <at> dancol.org>
>>> Date: Thu, 05 Jun 2025 16:40:03 -0700
>>> 
>>> Right now, C-M-a runs treesit-beginning-of-defun which goes to the
>>> start of the previous defun in buffer text, not the enclosing defun.
>>> 
>>> If we have this program:
>>> 
>>>    1 function foo() {
>>>    2   function bar() {
>>>    3     return 5
>>>    4   }
>>>    5   return 7
>>>    6 }
>>> 
>>> 
>>> and point is on line 5, then if we hit C-M-a, point goes to line 2, not
>>> line 1.  In every single situation, when I use beginning-of-defun, I
>>> intend to go to the start of my enclosing defun not the one that happens
>>> to be previous in buffer linearization.
>> 
>> I think you want to set treesit-defun-tactic to 'top-level’.
>
>Yes. Most likely top-level is what you want. 
>
>Yuan
>
>

I don't think that's right either --- if I'm on line 3, I should go to line 2, not 1. Go to beginning of defun should mean go to the beginning of *my* defun. That's the traditional behavior from cc-mode, js-mode, etc. and the one that makes most sense. I can see top-level being an option, but I don't think the way nested works right now is useful and it's confusing and inconsistent as a default.








Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78703; Package emacs. (Fri, 06 Jun 2025 17:01:01 GMT) Full text and rfc822 format available.

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

From: Troy Brown <brownts <at> troybrown.dev>
To: Daniel Colascione <dancol <at> dancol.org>
Cc: Yuan Fu <casouri <at> gmail.com>, 78703 <at> debbugs.gnu.org,
 Eli Zaretskii <eliz <at> gnu.org>
Subject: Re: bug#78703: beginning-of-defun and friends still wrong in
 typescript-ts-mode
Date: Fri, 6 Jun 2025 13:00:22 -0400
Daniel Colascione <dancol <at> dancol.org> writes:

> On June 6, 2025 12:23:23 AM PDT, Yuan Fu <casouri <at> gmail.com> wrote:
>>
>>
>>> On Jun 6, 2025, at 12:01 AM, Eli Zaretskii <eliz <at> gnu.org> wrote:
>>>
>>>> From: Daniel Colascione <dancol <at> dancol.org>
>>>> Date: Thu, 05 Jun 2025 16:40:03 -0700
>>>>
>>>> Right now, C-M-a runs treesit-beginning-of-defun which goes to the
>>>> start of the previous defun in buffer text, not the enclosing defun.
>>>>
>>>> If we have this program:
>>>>
>>>>    1 function foo() {
>>>>    2   function bar() {
>>>>    3     return 5
>>>>    4   }
>>>>    5   return 7
>>>>    6 }
>>>>
>>>>
>>>> and point is on line 5, then if we hit C-M-a, point goes to line 2, not
>>>> line 1.  In every single situation, when I use beginning-of-defun, I
>>>> intend to go to the start of my enclosing defun not the one that happens
>>>> to be previous in buffer linearization.
>>>
>>> I think you want to set treesit-defun-tactic to 'top-level’.
>>
>>Yes. Most likely top-level is what you want.
>>
>>Yuan
>>
>>
>
> I don't think that's right either --- if I'm on line 3, I should go to
> line 2, not 1. Go to beginning of defun should mean go to the
> beginning of *my* defun. That's the traditional behavior from cc-mode,
> js-mode, etc. and the one that makes most sense. I can see top-level
> being an option, but I don't think the way nested works right now is
> useful and it's confusing and inconsistent as a default.

I agree.  This behavior is not intuitive at all.  I reported this in
detail in Bug#68664, but it never seemed to go anywhere.  Furthermore,
using a `treesit-defun-tactic` of `top-level` doesn't work when you
are arbitrarily nested and just want to go to the beginning of the
function containing point.

This behavior not only impacts interactive use of
`treesit-beginning-of-defun` (via "C-M-a"), but other functionality
which builds upon `beginning-of-defun`, most notably
`prog-fill-reindent-defun`.  For the Tree-sitter modes that I
maintain, I had to create a mode-specific version of
`prog-fill-reindent-defun` instead.  That's because, as written,
`prog-fill-reindent-defun` uses `beginning-of-defun`, and since in
cases like this, `treesit-beginning-of-defun' goes to the previous
nested function, rather than the function containing point, you end up
re-indenting the previous nested function rather than the function
containing point.  The mode-specific version that I created, instead
uses `treesit-defun-at-point` to locate the containing function.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78703; Package emacs. (Sat, 07 Jun 2025 06:10:01 GMT) Full text and rfc822 format available.

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

From: Yuan Fu <casouri <at> gmail.com>
To: Troy Brown <brownts <at> troybrown.dev>
Cc: Eli Zaretskii <eliz <at> gnu.org>, Daniel Colascione <dancol <at> dancol.org>,
 78703 <at> debbugs.gnu.org
Subject: Re: bug#78703: beginning-of-defun and friends still wrong in
 typescript-ts-mode
Date: Fri, 6 Jun 2025 23:08:57 -0700

> On Jun 6, 2025, at 10:00 AM, Troy Brown <brownts <at> troybrown.dev> wrote:
> 
> Daniel Colascione <dancol <at> dancol.org> writes:
> 
>> On June 6, 2025 12:23:23 AM PDT, Yuan Fu <casouri <at> gmail.com> wrote:
>>> 
>>> 
>>>> On Jun 6, 2025, at 12:01 AM, Eli Zaretskii <eliz <at> gnu.org> wrote:
>>>> 
>>>>> From: Daniel Colascione <dancol <at> dancol.org>
>>>>> Date: Thu, 05 Jun 2025 16:40:03 -0700
>>>>> 
>>>>> Right now, C-M-a runs treesit-beginning-of-defun which goes to the
>>>>> start of the previous defun in buffer text, not the enclosing defun.
>>>>> 
>>>>> If we have this program:
>>>>> 
>>>>>   1 function foo() {
>>>>>   2   function bar() {
>>>>>   3     return 5
>>>>>   4   }
>>>>>   5   return 7
>>>>>   6 }
>>>>> 
>>>>> 
>>>>> and point is on line 5, then if we hit C-M-a, point goes to line 2, not
>>>>> line 1.  In every single situation, when I use beginning-of-defun, I
>>>>> intend to go to the start of my enclosing defun not the one that happens
>>>>> to be previous in buffer linearization.
>>>> 
>>>> I think you want to set treesit-defun-tactic to 'top-level’.
>>> 
>>> Yes. Most likely top-level is what you want.
>>> 
>>> Yuan
>>> 
>>> 
>> 
>> I don't think that's right either --- if I'm on line 3, I should go to
>> line 2, not 1. Go to beginning of defun should mean go to the
>> beginning of *my* defun. That's the traditional behavior from cc-mode,
>> js-mode, etc. and the one that makes most sense. I can see top-level
>> being an option, but I don't think the way nested works right now is
>> useful and it's confusing and inconsistent as a default.
> 
> I agree.  This behavior is not intuitive at all.  I reported this in
> detail in Bug#68664, but it never seemed to go anywhere.  Furthermore,
> using a `treesit-defun-tactic` of `top-level` doesn't work when you
> are arbitrarily nested and just want to go to the beginning of the
> function containing point.
> 
> This behavior not only impacts interactive use of
> `treesit-beginning-of-defun` (via "C-M-a"), but other functionality
> which builds upon `beginning-of-defun`, most notably
> `prog-fill-reindent-defun`.  For the Tree-sitter modes that I
> maintain, I had to create a mode-specific version of
> `prog-fill-reindent-defun` instead.  That's because, as written,
> `prog-fill-reindent-defun` uses `beginning-of-defun`, and since in
> cases like this, `treesit-beginning-of-defun' goes to the previous
> nested function, rather than the function containing point, you end up
> re-indenting the previous nested function rather than the function
> containing point.  The mode-specific version that I created, instead
> uses `treesit-defun-at-point` to locate the containing function.

So for this tactic, point should move out of the enclosing defun if it is inside a defun; and if point isn’t inside any defun it should move to the previous defund-beginning?

Any suggestions for a good name for this tactic? Right now we have `nested` and `top-level`.

Yuan



Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78703; Package emacs. (Sat, 07 Jun 2025 07:15:01 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Yuan Fu <casouri <at> gmail.com>
Cc: 78703 <at> debbugs.gnu.org, brownts <at> troybrown.dev, dancol <at> dancol.org
Subject: Re: bug#78703: beginning-of-defun and friends still wrong in
 typescript-ts-mode
Date: Sat, 07 Jun 2025 10:14:34 +0300
> From: Yuan Fu <casouri <at> gmail.com>
> Date: Fri, 6 Jun 2025 23:08:57 -0700
> Cc: Daniel Colascione <dancol <at> dancol.org>,
>  Eli Zaretskii <eliz <at> gnu.org>,
>  78703 <at> debbugs.gnu.org
> 
> So for this tactic, point should move out of the enclosing defun if it is inside a defun; and if point isn’t inside any defun it should move to the previous defund-beginning?
> 
> Any suggestions for a good name for this tactic? Right now we have `nested` and `top-level`.

Something like 'same-level'?




This bug report was last modified today.

Previous Next


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