GNU bug report logs - #78187
tsx-ts-mode: wrong indentation of object parameters

Previous Next

Package: emacs;

Reported by: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>

Date: Thu, 1 May 2025 12:57:02 UTC

Severity: normal

To reply to this bug, email your comments to 78187 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#78187; Package emacs. (Thu, 01 May 2025 12:57:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Konstantin Kharlamov <Hi-Angel <at> yandex.ru>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Thu, 01 May 2025 12:57:02 GMT) Full text and rfc822 format available.

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

From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
To: bug-gnu-emacs <at> gnu.org
Subject: tsx-ts-mode: wrong indentation of object parameters
Date: Thu, 01 May 2025 19:56:12 +0700
Given this snippet indented as expected:

    interface iface { f1: string,
                      f2: string
    }

indenting `f2` gives:

    interface iface { f1: string,
      f2: string
    }

May not be the best example, but JavaScript/TypeScript are heavy users of curly braces, and sometimes I do want to write the first field on the line with opening curly brace, which usually implies aligning other fields to it.

---------

I spent quite some time trying to write a patch for this, but I am at loss. The closest I come to a solution is a rule:

    ((node-is "property_signature") prev-sibling 0)

it works correctly for every param starting with 2nd, but it misindents the 1st parameter. Probably some condition required like "for the 1st parameter do the offset, for consequent ones follow previous siblings indentation". But I have no idea how to do that.

I looked at `c++-ts-mode` (which does it right) for inspiration, but couldn't figure out what it does in the same situation.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78187; Package emacs. (Thu, 01 May 2025 13:11:02 GMT) Full text and rfc822 format available.

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

From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
To: 78187 <at> debbugs.gnu.org
Subject: bug#78187: tsx-ts-mode: wrong indentation of object parameters
Date: Thu, 01 May 2025 20:10:01 +0700
Looking at c++-ts-mode more, I found it seems to do that with a rule
function (c-ts-mode--parenthesized-expression-indent-rule).  Makes me
wonder: can't it be made into a general rule, similar to prev-sibling,
like "prev-same-sibling-or-offset"? The situation it seems pretty
common for all programming languages.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78187; Package emacs. (Sat, 10 May 2025 10:18:02 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>,
 Yuan Fu <casouri <at> gmail.com>
Cc: 78187 <at> debbugs.gnu.org
Subject: Re: bug#78187: tsx-ts-mode: wrong indentation of object parameters
Date: Sat, 10 May 2025 13:17:26 +0300
> From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
> Date: Thu, 01 May 2025 19:56:12 +0700
> 
> Given this snippet indented as expected:
> 
>     interface iface { f1: string,
>                       f2: string
>     }
> 
> indenting `f2` gives:
> 
>     interface iface { f1: string,
>       f2: string
>     }
> 
> May not be the best example, but JavaScript/TypeScript are heavy users of curly braces, and sometimes I do want to write the first field on the line with opening curly brace, which usually implies aligning other fields to it.
> 
> ---------
> 
> I spent quite some time trying to write a patch for this, but I am at loss. The closest I come to a solution is a rule:
> 
>     ((node-is "property_signature") prev-sibling 0)
> 
> it works correctly for every param starting with 2nd, but it misindents the 1st parameter. Probably some condition required like "for the 1st parameter do the offset, for consequent ones follow previous siblings indentation". But I have no idea how to do that.
> 
> I looked at `c++-ts-mode` (which does it right) for inspiration, but couldn't figure out what it does in the same situation.

Yuan, any comments?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78187; Package emacs. (Tue, 13 May 2025 19:57:03 GMT) Full text and rfc822 format available.

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

From: Yuan Fu <casouri <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 78187 <at> debbugs.gnu.org, Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
Subject: Re: bug#78187: tsx-ts-mode: wrong indentation of object parameters
Date: Tue, 13 May 2025 12:56:31 -0700

> On May 10, 2025, at 3:17 AM, Eli Zaretskii <eliz <at> gnu.org> wrote:
> 
>> From: Konstantin Kharlamov <Hi-Angel <at> yandex.ru>
>> Date: Thu, 01 May 2025 19:56:12 +0700
>> 
>> Given this snippet indented as expected:
>> 
>>    interface iface { f1: string,
>>                      f2: string
>>    }
>> 
>> indenting `f2` gives:
>> 
>>    interface iface { f1: string,
>>      f2: string
>>    }
>> 
>> May not be the best example, but JavaScript/TypeScript are heavy users of curly braces, and sometimes I do want to write the first field on the line with opening curly brace, which usually implies aligning other fields to it.
>> 
>> ---------
>> 
>> I spent quite some time trying to write a patch for this, but I am at loss. The closest I come to a solution is a rule:
>> 
>>    ((node-is "property_signature") prev-sibling 0)
>> 
>> it works correctly for every param starting with 2nd, but it misindents the 1st parameter. Probably some condition required like "for the 1st parameter do the offset, for consequent ones follow previous siblings indentation". But I have no idea how to do that.

The “match” matcher allow you to do that. You probably want to modify this rule:

 ((parent-is "interface_body") parent-bol typescript-ts-mode-indent-offset)

So each property aligns to the first non-comment sibling. And the first sibling aligns to the parent + 1 indent level.

I don’t think we have an existing anchor to find the first non-comment sibling, we might need to add something like (first-sibling-excluding “regexp”)

>> 
>> I looked at `c++-ts-mode` (which does it right) for inspiration, but couldn't figure out what it does in the same situation.

You can set treesit--indent-verbose to t and indent the line, then the matched rule will be printed in the echo area. Right now on master build, that indentation is handled by the c-ts-common-baseline-indent-rule, which is a smart baseline rule I created recently that can handle 90% of the indentation for C-like languages. We should probably migrate other C-like languages to use this rule, but that’s the topic for another discussion.

Yuan



This bug report was last modified 10 days ago.

Previous Next


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