]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve treesit settings for js-ts-mode (bug#73404)
authorJuri Linkov <juri@linkov.net>
Mon, 3 Mar 2025 18:38:40 +0000 (20:38 +0200)
committerEshel Yaron <me@eshelyaron.com>
Tue, 4 Mar 2025 21:04:40 +0000 (22:04 +0100)
* lisp/progmodes/js.el (js--treesit-font-lock-settings):
Add 'class' alongside 'class_declaration'.
(js--treesit-defun-name): Add "variable_declaration"
alongside "lexical_declaration".
(js--treesit-valid-imenu-entry): Add "variable_declaration"
and provide the predicate to 'treesit-node-top-level'.
(js--treesit-sentence-nodes): Add "jsx_attribute" like in html-ts-mode
instead of jsx elements matched in 'js--treesit-list-nodes'.
(js--treesit-list-nodes): Add "jsx_element" and "jsx_self_closing_element"
instead of "_jsx_string".
(js--treesit-simple-imenu-settings): Move "method_definition" to separate
section "Method" from the "Class" section.  Add "variable_declaration"
to the "Variable" section.
(js-ts-mode--outline-predicate): New variable.
(js--treesit-defun-type-regexp): Add bos/eos.
(js--treesit-jsdoc-comment-regexp): Add bos/eos.
(js-ts-mode): Set treesit-outline-predicate to
'js-ts-mode--outline-predicate'.

* lisp/textmodes/mhtml-ts-mode.el (mhtml-ts-mode--html-defun-name):
Remove unused function.
(mhtml-ts-mode): Use 'js-ts-mode--outline-predicate' in
'treesit-aggregated-outline-predicate'.

* lisp/textmodes/yaml-ts-mode.el (yaml-ts-mode--outline-predicate):
Use 'treesit-node-top-level' instead of 'treesit-parent-until'.

(cherry picked from commit dbc0e5a52d855773a495e0ca89b738f8f2246df9)

lisp/progmodes/js.el
lisp/textmodes/mhtml-ts-mode.el
lisp/textmodes/yaml-ts-mode.el

index 27ec5200eeb93b5ac81fee92a6f06bd2fdb2b6c4..4346e0fd3a92c49bfac1d0f4497c53f6678bc406 100644 (file)
@@ -3544,6 +3544,9 @@ Check if a node type is available, then return the right indent rules."
    :feature 'definition
    `(,@(js--treesit-font-lock-compatibility-definition-feature)
 
+     (class
+      name: (identifier) @font-lock-type-face)
+
      (class_declaration
       name: (identifier) @font-lock-type-face)
 
@@ -3708,7 +3711,7 @@ Return nil if there is no name or if NODE is not a defun node."
   (treesit-node-text
    (treesit-node-child-by-field-name
     (pcase (treesit-node-type node)
-      ("lexical_declaration"
+      ((or "lexical_declaration" "variable_declaration")
        (treesit-search-subtree node "variable_declarator" nil nil 1))
       ((or "function_declaration" "method_definition" "class_declaration")
        node))
@@ -3716,9 +3719,15 @@ Return nil if there is no name or if NODE is not a defun node."
    t))
 
 (defun js--treesit-valid-imenu-entry (node)
-  "Return nil if NODE is a non-top-level \"lexical_declaration\"."
+  "Return nil if NODE is a non-top-level lexical/variable declaration."
   (pcase (treesit-node-type node)
-    ("lexical_declaration" (treesit-node-top-level node))
+    ((or "lexical_declaration" "variable_declaration")
+     (not (treesit-node-top-level
+           node (rx bos (or "class_declaration"
+                            "method_definition"
+                            "function_declaration"
+                            "function_expression")
+                    eos))))
     (_ t)))
 
 (defun js--treesit-language-at-point (point)
@@ -3854,8 +3863,7 @@ Currently there are `js-mode' and `js-ts-mode'."
     "labeled_statement"
     "variable_declaration"
     "lexical_declaration"
-    "jsx_element"
-    "jsx_self_closing_element")
+    "jsx_attribute")
   "Nodes that designate sentences in JavaScript.
 See `treesit-thing-settings' for more information.")
 
@@ -3903,8 +3911,9 @@ See `treesit-thing-settings' for more information.")
     "object_pattern"
     "array"
     "array_pattern"
+    "jsx_element"
     "jsx_expression"
-    "_jsx_string"
+    "jsx_self_closing_element"
     "string"
     "regex"
     "arguments"
@@ -3935,24 +3944,34 @@ See `treesit-thing-settings' for more information.")
   "Settings for `treesit-font-lock-feature-list'.")
 
 (defvar js--treesit-simple-imenu-settings
-  `(("Function" "\\`function_declaration\\'" nil nil)
-    ("Variable" "\\`lexical_declaration\\'"
-     js--treesit-valid-imenu-entry nil)
-    ("Class" ,(rx bos (or "class_declaration"
-                          "method_definition")
-                  eos)
-     nil nil))
+  `(("Class" "\\`class_declaration\\'" nil nil)
+    ("Method" "\\`method_definition\\'" nil nil)
+    ("Function" "\\`function_declaration\\'" nil nil)
+    ("Variable" ,(rx bos (or "lexical_declaration"
+                             "variable_declaration")
+                     eos)
+     ,#'js--treesit-valid-imenu-entry nil))
   "Settings for `treesit-simple-imenu'.")
 
+(defvar js-ts-mode--outline-predicate
+  `(or (and "\\`class\\'" named)
+       ,(rx bos (or"class_declaration"
+                   "method_definition"
+                   "function_declaration"
+                   "function_expression")
+            eos)))
+
 (defvar js--treesit-defun-type-regexp
-  (rx (or "class_declaration"
-          "method_definition"
-          "function_declaration"
-          "lexical_declaration"))
+  (rx bos (or "class_declaration"
+              "method_definition"
+              "function_declaration"
+              "lexical_declaration"
+              "variable_declaration")
+      eos)
   "Settings for `treesit-defun-type-regexp'.")
 
 (defvar js--treesit-jsdoc-comment-regexp
-  (rx (or "comment" "line_comment" "block_comment" "description"))
+  (rx bos (or "comment" "line_comment" "block_comment" "description") eos)
   "Regexp for `c-ts-common--comment-regexp'.")
 
 ;;;###autoload
@@ -4006,6 +4025,8 @@ See `treesit-thing-settings' for more information.")
 
     ;; Imenu
     (setq-local treesit-simple-imenu-settings js--treesit-simple-imenu-settings)
+    ;; Outline minor mode
+    (setq-local treesit-outline-predicate js-ts-mode--outline-predicate)
 
     (treesit-major-mode-setup)
 
index 4d538514f1c91b48c037a343acc02fce29c20970..5c4f90cd19361ce1ad8de17303512f293c5a9a16 100644 (file)
@@ -367,15 +367,6 @@ NODE and PARENT are ignored."
 (defvar mhtml-ts-mode--prettify-symbols-alist js--prettify-symbols-alist
   "Alist of symbol prettifications for various supported languages.")
 
-(defun mhtml-ts-mode--html-defun-name (node)
-  "Return the defun name of NODE.
-Return nil if there is no name or if NODE is not a defun node."
-  (when (string-match-p "element" (treesit-node-type node))
-    (treesit-node-text
-     node
-     ;; (treesit-search-subtree node "\\`tag_name\\'" nil nil 2)
-     t)))
-
 ;; In order to support `which-fuction-mode' we should define
 ;; a function that return the defun name.
 ;; In a multilingual treesit mode, this can be implemented simply by
@@ -584,8 +575,7 @@ Powered by tree-sitter."
 
     (setq-local treesit-aggregated-outline-predicate
                 `((html . ,#'html-ts-mode--outline-predicate)
-                  ;; TODO: add a predicate like for html above
-                  (javascript . "\\`function_declaration\\'")
+                  (javascript . ,js-ts-mode--outline-predicate)
                   (css . ,css-ts-mode--outline-predicate)))
 
     (treesit-major-mode-setup)
index 9b211902e14f333cec2b4b9f68807628bc241dc0..7d11223aefa503a29a5729b696c9dd1f24575c1b 100644 (file)
@@ -154,7 +154,7 @@ Return nil if there is no name or if NODE is not a defun node."
   "Limit outlines to top-level mappings."
   (let ((regexp (rx (or "block_mapping_pair" "block_sequence_item"))))
     (when (string-match-p regexp (treesit-node-type node))
-      (not (treesit-parent-until node regexp)))))
+      (not (treesit-node-top-level node regexp)))))
 
 ;;;###autoload
 (define-derived-mode yaml-ts-mode text-mode "YAML"