Subject: bug#60602: 29.0.60; treesit-simple-indent doesn't work for top-level nodes

From: Theodor Thornhill <[email-masked]>
Date: Fri, 20 Jan 2023 22:40:51 +0100

Hi there!

Yuan Fu <[email-masked]> writes:

> Piotr Trojanek <[email-masked]> writes:
>
>> This problem can be reproduced with a correctly configured c-ts-mode,
>> which fails to indent the first line of a code like this, i.e. with
>> extra space at the very beginning of file and cursor positioned at
>> "main"):
>>
>> ===
>>    int main (int argc, char *argv[])
>> {
>>   return 0;
>> }
>> ===
>>
>> The intent of c-ts-mode--indent-styles is clearly to indent this line
>> to 0th column:
>>
>> (defun c-ts-mode--indent-styles (mode)
>>   ...
>>          `(((parent-is "translation_unit") parent-bol 0)
>>
>> However, when indenting this line treesit-simple-indent is called with
>> node=translation_unit and parent=nil. It exits too early and doesn't
>> consider any indentation rules:
>>
>> (defun treesit-simple-indent (node parent bol)
>>   "..."
>>   (if (null parent)
>>       (progn (when treesit--indent-verbose
>>                (message "PARENT is nil, not indenting"))
>>              (cons nil nil))
>>
>> Note that other tree-sitter modes have similar indentation rules, e.g.
>> ruby-ts-mode.el:
>>
>>    ;; Slam all top level nodes to the left margin
>>    ((parent-is "program") parent 0)
>>
>> and same for typescript-ts-mode.el:
>>
>>   ((parent-is "program") parent-bol 0)
>>
>> Perhaps the early exit from treesit-simple-indent could be removed, so
>> the indentation rules can decide how to handle a nil parent.
>
> Now NODE is never the root node, so parent is never nil. I believe this
> is the best approach.  And personally I think the rule should be
>
> ((parent-is "program") point-min 0)
>
> Yuan

You okay with this patch, Piotr and Dmitry?

Theo

>From ab13b78f02452e8e1be633593a6792d9f8b6050c Mon Sep 17 00:00:00 2001
From: Theodor Thornhill <[email-masked]>
Date: Fri, 20 Jan 2023 22:37:47 +0100
Subject: [PATCH] Use point-min to anchor top-level constructs (bug#60602)

* lisp/progmodes/c-ts-mode.el (c-ts-mode--indent-styles): New anchor.
* lisp/progmodes/java-ts-mode.el (java-ts-mode--indent-rules): New
anchor.
* lisp/progmodes/ruby-ts-mode.el (ruby-ts--indent-rules): New anchor.
* lisp/progmodes/typescript-ts-mode.el
(typescript-ts-mode--indent-rules): New anchor.
---
 lisp/progmodes/c-ts-mode.el          | 2 +-
 lisp/progmodes/java-ts-mode.el       | 2 +-
 lisp/progmodes/ruby-ts-mode.el       | 2 +-
 lisp/progmodes/typescript-ts-mode.el | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 348d027af1..2370a2c964 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -115,7 +115,7 @@ c-ts-mode--indent-styles
   "Indent rules supported by `c-ts-mode'.
 MODE is either `c' or `cpp'."
   (let ((common
-         `(((parent-is "translation_unit") parent-bol 0)
+         `(((parent-is "translation_unit") point-min 0)
            ((node-is ")") parent 1)
            ((node-is "]") parent-bol 0)
            ((node-is "else") parent-bol 0)
diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el
index 03093e0980..6bcf5d1253 100644
--- a/lisp/progmodes/java-ts-mode.el
+++ b/lisp/progmodes/java-ts-mode.el
@@ -69,7 +69,7 @@ java-ts-mode--syntax-table
 
 (defvar java-ts-mode--indent-rules
   `((java
-     ((parent-is "program") parent-bol 0)
+     ((parent-is "program") point-min 0)
      ((node-is "}") (and parent parent-bol) 0)
      ((node-is ")") parent-bol 0)
      ((node-is "]") parent-bol 0)
diff --git a/lisp/progmodes/ruby-ts-mode.el b/lisp/progmodes/ruby-ts-mode.el
index f0337775d5..809f0da2a0 100644
--- a/lisp/progmodes/ruby-ts-mode.el
+++ b/lisp/progmodes/ruby-ts-mode.el
@@ -535,7 +535,7 @@ ruby-ts--indent-rules
   (let ((common
          `(
            ;; Slam all top level nodes to the left margin
-           ((parent-is "program") parent 0)
+           ((parent-is "program") point-min 0)
 
            ;; Do not indent here docs or the end.  Not sure why it
            ;; takes the grand-parent but ok fine.
diff --git a/lisp/progmodes/typescript-ts-mode.el b/lisp/progmodes/typescript-ts-mode.el
index f7bf7ed7e4..c0c18d65cc 100644
--- a/lisp/progmodes/typescript-ts-mode.el
+++ b/lisp/progmodes/typescript-ts-mode.el
@@ -69,7 +69,7 @@ typescript-ts-mode--indent-rules
   "Rules used for indentation.
 Argument LANGUAGE is either `typescript' or `tsx'."
   `((,language
-     ((parent-is "program") parent-bol 0)
+     ((parent-is "program") point-min 0)
      ((node-is "}") parent-bol 0)
      ((node-is ")") parent-bol 0)
      ((node-is "]") parent-bol 0)
-- 
2.34.1