Subject: bug#77901: tsx-ts-mode: ternary chains are indented as a tree

From: Konstantin Kharlamov <[email-masked]>
Date: Wed, 14 May 2025 21:50:56 +0700

On Tue, 2025-05-13 at 12:45 -0700, Yuan Fu wrote:
> Hey, sorry for the delay.
>
> > On May 10, 2025, at 3:16 AM, Eli Zaretskii <[email-masked]> wrote:
> >
> > > From: Konstantin Kharlamov <[email-masked]>
> > > Date: Thu, 01 May 2025 20:39:02 +0700
> > >
> > > After poking around I wrote a patch (attached).
>
> Thanks! LGTM. For some reason I can’t apply the patch on either
> emacs-30 or master. [1]

Oh, interesting.  I kind of know where the error is coming from, but
only partially.  The reason for the error is that the patch I sent was
applied over the patch for #78121 (which is pending btw 😊) as I'm
using them both for coding.   At the same time, I don't really
understand the source of the error as the same parameters work for me:

    ╰─λ git am --3way -- /tmp/1.patch
    Applying: typescript-ts: align ternary-chain branches (bug#78187)
    Using index info to reconstruct a base tree...
    M       lisp/progmodes/typescript-ts-mode.el
    M       test/lisp/progmodes/typescript-ts-mode-resources/indent.erts
    Falling back to patching base and 3-way merge...
    Auto-merging test/lisp/progmodes/typescript-ts-mode-resources/indent.erts
    Auto-merging lisp/progmodes/typescript-ts-mode.el

Either way, I redone the patch on top of the tree, please try this one

> > > Worth noting though, for
> > > some reason it doesn't work for ternary without starting colon,
> > > e.g.:
> > >
> > >    const a = cond1 ? 1 :
> > >      cond2 ? 2 :
> > >      cond3 ? 3 : 4;
> > >
> > > I'm unclear why, per my understanding the "standalone-parent" of
> > > the
> > > whole ternary chain (disregarding where the point is) is the
> > > `const a
> > > =` declaration.
>
> The standalone rule just keeps going up the parse tree until it finds
> a node that starts on a new line. In this case, if you start form
> cond3, it’ll go up until reaching the teneray_expression node
> containing cond2. This node starts on a new line so standalone-parent
> stops here. So the cond3 line uses the cond2 line as the anchor,
> instead of the “const a” line. If you add a cond4 line, it’ll use the
> cond3 line as anchor.
>
> There’re several ways to fix it. The best way is to add a new anchor
> to the presets that does what standalone-parent does, but
> additionally excludes some nodes. Something like (standalone-parent-
> excluding “regexp”). Then this can be used for both typescript and
> c/c++ (and java, etc).

Oh, I see, thank you!
From 0fc01a896999c38d0613ab2681cf06404e139702 Mon Sep 17 00:00:00 2001
From: Konstantin Kharlamov <[email-masked]>
Date: Thu, 1 May 2025 20:28:29 +0700
Subject: [PATCH] typescript-ts: align ternary-chain branches (bug#78187)

lisp/progmodes/typescript-ts-mode.el (typescript-ts-mode--indent-rules):
make sure each new ternary branch is aligned with the previous one.
test/lisp/progmodes/typescript-ts-mode-resources/indent.erts (Chained
ternary expressions): New test.
---
 lisp/progmodes/typescript-ts-mode.el                     | 2 +-
 .../progmodes/typescript-ts-mode-resources/indent.erts   | 9 +++++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/lisp/progmodes/typescript-ts-mode.el b/lisp/progmodes/typescript-ts-mode.el
index e0458b3192e..93d75f0020b 100644
--- a/lisp/progmodes/typescript-ts-mode.el
+++ b/lisp/progmodes/typescript-ts-mode.el
@@ -162,7 +162,7 @@ typescript-ts-mode--indent-rules
      ((and (parent-is "comment") c-ts-common-looking-at-star)
       c-ts-common-comment-start-after-first-star -1)
      ((parent-is "comment") prev-adaptive-prefix 0)
-     ((parent-is "ternary_expression") parent-bol typescript-ts-mode-indent-offset)
+     ((parent-is "ternary_expression") standalone-parent typescript-ts-mode-indent-offset)
      ((parent-is "member_expression") parent-bol typescript-ts-mode-indent-offset)
      ((parent-is "named_imports") parent-bol typescript-ts-mode-indent-offset)
      ((parent-is "statement_block") parent-bol typescript-ts-mode-indent-offset)
diff --git a/test/lisp/progmodes/typescript-ts-mode-resources/indent.erts b/test/lisp/progmodes/typescript-ts-mode-resources/indent.erts
index 1305029a9e1..e8b1d57f132 100644
--- a/test/lisp/progmodes/typescript-ts-mode-resources/indent.erts
+++ b/test/lisp/progmodes/typescript-ts-mode-resources/indent.erts
@@ -93,6 +93,15 @@ const foo = () => {
 };
 =-=-=
 
+Name: Chained ternary expressions
+
+=-=
+const a = cond1 ? 1
+  : cond2 ? 2
+  : cond3 ? 3
+  : 4;
+=-=-=
+
 Code:
   (lambda ()
     (setq tsx-ts-mode-indent-offset 2)
-- 
2.49.0