Subject: bug#66183: elixir-ts-mode test failure

From: Wilhelm Kirschbaum <[email-masked]>
Date: Tue, 26 Sep 2023 22:26:11 +0200

>>> need to adjust it but the idea is there.
>>> 
>>> With the new language-at-point definition, treesit-language-at 
>>> can
>>> return the correct language, and the test passes again.
>>> 
>>> Yuan
>>> 
>>> [2. text/x-patch; example.diff]...
>> 
>> This seems to work if you set named on: 
>> treesit-node-prev-sibling,
>> otherwise it just tries to match the \"\"\" against H or F.
>> 
>>  (let* ((node (treesit-node-at point 'elixir)))
>>    (if (and (equal (treesit-node-type node) "quoted_content")
>>             (string-match-p
>>              (rx bos (or "H" "F") eos)
>> -              (treesit-node-text (treesit-node-prev-sibling 
>> node))))
>> +              (treesit-node-text (treesit-node-prev-sibling 
>> node t))))
>>        'heex
>>      'elixir)))
>> 
>> I will spend some time in the next couple of hours to catch up 
>> to all
>> the changes.
>
> Ah, right. I’ll leave the specifics to you. As long as the 
> language is derived from the node at point rather than parser 
> range, it will be fine. Also, there’s no rush.
>

Hi Yuan,

With the new changes I had to update some indentation rules as 
well.
The following patch was tested against a couple of elixir files.

There is another indentation issue with HEEx embeds, but think its
unrelated to this issue and will have a look this weekend.

>From 046950eb63b5499ab7f60434c5ebd0bbe5ada274 Mon Sep 17 00:00:00 2001
From: Wilhelm H Kirschbaum <[email-masked]>
Date: Tue, 26 Sep 2023 21:32:40 +0200
Subject: [PATCH] Fix treesit-langauge-at-point for elixir-ts-mode.

The treesit-language-at-point function is only suppose to query the
host language.

* lisp/progmodes/elixir-ts-mode.el
(elixir-ts--indent-rules): Add missing rules.
(elixir-ts--treesit-language-at-point): Update function to only query
the host language.
* test/lisp/progmodes/elixir-ts-mode-resources/indent.erts: Add test
for inline docs.
---
 lisp/progmodes/elixir-ts-mode.el              | 35 ++++++++++---------
 .../elixir-ts-mode-resources/indent.erts      | 16 +++++++++
 2 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/lisp/progmodes/elixir-ts-mode.el b/lisp/progmodes/elixir-ts-mode.el
index 7175fe4bff8..fd4400c6c53 100644
--- a/lisp/progmodes/elixir-ts-mode.el
+++ b/lisp/progmodes/elixir-ts-mode.el
@@ -312,7 +312,16 @@ elixir-ts--indent-rules
        ((parent-is "^catch_block$") parent ,offset)
        ((parent-is "^keywords$") parent-bol 0)
        ((node-is "^call$") parent-bol ,offset)
-       ((node-is "^comment$") parent-bol ,offset)))))
+       ((node-is "^comment$") parent-bol ,offset)
+       ((node-is "\"\"\"") parent-bol 0)
+       ;; Handle quoted_content indentation on the last
+       ;; line before the closing \"\"\", where it might
+       ;; see it as no-node outside a HEEx tag.
+       (no-node (lambda (_n _p _bol)
+                  (treesit-node-start
+                   (treesit-node-parent
+                    (treesit-node-at (point) 'elixir))))
+                  0)))))
 
 (defvar elixir-ts--font-lock-settings
   (treesit-font-lock-rules
@@ -510,21 +519,15 @@ elixir-ts--treesit-anchor-grand-parent-bol
 
 (defun elixir-ts--treesit-language-at-point (point)
   "Return the language at POINT."
-  (let* ((range nil)
-         (language-in-range
-          (cl-loop
-           for parser in (treesit-parser-list)
-           do (setq range
-                    (cl-loop
-                     for range in (treesit-parser-included-ranges parser)
-                     if (and (>= point (car range)) (<= point (cdr range)))
-                     return parser))
-           if range
-           return (treesit-parser-language parser))))
-    (if (null language-in-range)
-        (when-let ((parser (car (treesit-parser-list))))
-          (treesit-parser-language parser))
-      language-in-range)))
+  (let ((node (treesit-node-at point 'elixir)))
+    (if (and (equal (treesit-node-type node) "quoted_content")
+             (let ((prev-sibling (treesit-node-prev-sibling node t)))
+               (when (treesit-node-p prev-sibling)
+                 (string-match-p
+                  (rx bos (or "H" "F") eos)
+                  (treesit-node-text (treesit-node-prev-sibling node t))))))
+        'heex
+      'elixir)))
 
 (defun elixir-ts--defun-p (node)
   "Return non-nil when NODE is a defun."
diff --git a/test/lisp/progmodes/elixir-ts-mode-resources/indent.erts b/test/lisp/progmodes/elixir-ts-mode-resources/indent.erts
index 1f855d3c977..fe09a37a32b 100644
--- a/test/lisp/progmodes/elixir-ts-mode-resources/indent.erts
+++ b/test/lisp/progmodes/elixir-ts-mode-resources/indent.erts
@@ -330,6 +330,22 @@ Name: Long tuple
  "October", "November", "December"}
 =-=-=
 
+Name: Doc
+
+=-=
+defmodule Foo do
+"""
+    bar
+    """
+end
+=-=
+defmodule Foo do
+  """
+    bar
+  """
+end
+=-=-=
+
 Name: Embedded HEEx
 
 =-=
-- 
2.42.0

Wilhelm