]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve treesit settings for typescript/tsx-ts-mode (bug#73404)
authorJuri Linkov <juri@linkov.net>
Wed, 5 Mar 2025 17:44:44 +0000 (19:44 +0200)
committerEshel Yaron <me@eshelyaron.com>
Sun, 9 Mar 2025 07:05:44 +0000 (08:05 +0100)
* lisp/progmodes/typescript-ts-mode.el
(typescript-ts-mode--font-lock-settings): Add @font-lock-type-face
for 'internal_module' with 'identifier'.
(typescript-ts-mode--defun-type-regexp): New variable with
"internal_module" and "interface_declaration".
(typescript-ts-mode--defun-name): New function that uses
'js--treesit-defun-name' and adds "internal_module" and
"interface_declaration".
(typescript-ts-mode--simple-imenu-settings): New variable
like in 'js-ts-mode' with "Namespace" and "Interface" sections.
(typescript-ts-mode--outline-predicate): New variable.
(typescript-ts-base-mode): Set treesit-defun-type-regexp to
typescript-ts-mode--defun-type-regexp, treesit-defun-name-function
to typescript-ts-mode--defun-name, treesit-simple-imenu-settings
to typescript-ts-mode--simple-imenu-settings,
treesit-outline-predicate to typescript-ts-mode--outline-predicate.
Use js--regexp-opt-symbol for treesit-thing-settings.
(tsx-ts-mode): For 'sentence' thing use the same nodes as
js--treesit-sentence-nodes.  Use js--regexp-opt-symbol for
treesit-thing-settings.

* lisp/progmodes/js.el (js--treesit-sentence-nodes): Add
"jsx_opening_element" and "jsx_closing_element" like in html.

* lisp/progmodes/c-ts-mode.el (c-ts-mode--outline-predicate): Add
outline headings for C++ "namespace_definition" and "class_specifier".

(cherry picked from commit 68def672e61a5b25ec5bdee69493c09d79632ce2)

lisp/progmodes/c-ts-mode.el
lisp/progmodes/js.el
lisp/progmodes/typescript-ts-mode.el

index 499c2ad66d4f183a58fa4ddc1747c2e3ae7b5179..fa5f8567b602dc67cc92e3dba1afb934d56a22cd 100644 (file)
@@ -1048,7 +1048,9 @@ Return nil if NODE is not a defun node or doesn't have a name."
            (treesit-parent-until node "function_definition"))
       ;; DEFUNs in Emacs sources.
       (and c-ts-mode-emacs-sources-support
-           (c-ts-mode--emacs-defun-p node))))
+           (c-ts-mode--emacs-defun-p node))
+      (member (treesit-node-type node) '("namespace_definition"
+                                         "class_specifier"))))
 
 ;;; Defun navigation
 
index 4346e0fd3a92c49bfac1d0f4497c53f6678bc406..abe7e15b9c7929749fb2da071c5c9ca1170fefe6 100644 (file)
@@ -3863,7 +3863,9 @@ Currently there are `js-mode' and `js-ts-mode'."
     "labeled_statement"
     "variable_declaration"
     "lexical_declaration"
-    "jsx_attribute")
+    "jsx_opening_element"
+    "jsx_attribute"
+    "jsx_closing_element")
   "Nodes that designate sentences in JavaScript.
 See `treesit-thing-settings' for more information.")
 
@@ -3955,10 +3957,10 @@ See `treesit-thing-settings' for more information.")
 
 (defvar js-ts-mode--outline-predicate
   `(or (and "\\`class\\'" named)
-       ,(rx bos (or"class_declaration"
-                   "method_definition"
-                   "function_declaration"
-                   "function_expression")
+       ,(rx bos (or "class_declaration"
+                    "method_definition"
+                    "function_declaration"
+                    "function_expression")
             eos)))
 
 (defvar js--treesit-defun-type-regexp
@@ -4004,9 +4006,7 @@ See `treesit-thing-settings' for more information.")
     (setq-local treesit-simple-indent-rules js--treesit-indent-rules)
     ;; Navigation.
     (setq-local treesit-defun-type-regexp js--treesit-defun-type-regexp)
-
     (setq-local treesit-defun-name-function #'js--treesit-defun-name)
-
     (setq-local treesit-thing-settings js--treesit-thing-settings)
 
     ;; Fontification.
index 0a3b91d12c14d1d95c5013a95fe3597362cedb02..ece8eebd028c53bc07fbae6f8432632751cb017b 100644 (file)
@@ -317,6 +317,8 @@ Argument LANGUAGE is either `typescript' or `tsx'."
                                object: (identifier) @font-lock-type-face
                                property: (property_identifier) @font-lock-type-face))
 
+       (internal_module (identifier) @font-lock-type-face)
+
        (arrow_function
         parameter: (identifier) @font-lock-variable-name-face)
 
@@ -509,6 +511,49 @@ See `treesit-thing-settings' for more information.")
   "Nodes that designate lists in TypeScript.
 See `treesit-thing-settings' for more information.")
 
+(defvar typescript-ts-mode--defun-type-regexp
+  (rx bos (or "internal_module"
+              "interface_declaration"
+              "class_declaration"
+              "method_definition"
+              "function_declaration"
+              "lexical_declaration")
+      eos)
+  "Settings for `treesit-defun-type-regexp'.")
+
+(defun typescript-ts-mode--defun-name (node)
+  "Return the defun name of NODE.
+Return nil if there is no name or if NODE is not a defun node."
+  (or (js--treesit-defun-name node)
+      (treesit-node-text
+       (pcase (treesit-node-type node)
+         ("internal_module"
+          (treesit-node-child node 1))
+         ("interface_declaration"
+          (treesit-node-child-by-field-name node "name")))
+       t)))
+
+(defvar typescript-ts-mode--simple-imenu-settings
+  `(("Namespace" "\\`internal_module\\'" nil nil)
+    ("Interface" "\\`interface_declaration\\'" 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 typescript-ts-mode--outline-predicate
+  (rx bos (or "internal_module"
+              "interface_declaration"
+              "class_declaration"
+              "method_definition"
+              "function_declaration"
+              "function_expression")
+      eos))
+
 ;;;###autoload
 (define-derived-mode typescript-ts-base-mode prog-mode "TypeScript"
   "Generic major mode for editing TypeScript.
@@ -524,33 +569,21 @@ This mode is intended to be inherited by concrete major modes."
   (setq-local electric-indent-chars
               (append "{}():;,<>/" electric-indent-chars))
   ;; Navigation.
-  (setq-local treesit-defun-type-regexp
-              (regexp-opt '("class_declaration"
-                            "method_definition"
-                            "function_declaration"
-                            "lexical_declaration")))
-  (setq-local treesit-defun-name-function #'js--treesit-defun-name)
+  (setq-local treesit-defun-type-regexp typescript-ts-mode--defun-type-regexp)
+  (setq-local treesit-defun-name-function #'typescript-ts-mode--defun-name)
 
   (setq-local treesit-thing-settings
               `((typescript
-                 (sexp ,(regexp-opt typescript-ts-mode--sexp-nodes 'symbols))
-                 (list ,(regexp-opt typescript-ts-mode--list-nodes
-                                         'symbols))
-                 (sentence ,(regexp-opt
-                             typescript-ts-mode--sentence-nodes 'symbols))
-                 (text ,(regexp-opt '("comment"
-                                      "template_string")
-                                    'symbols)))))
-
-  ;; Imenu (same as in `js-ts-mode').
+                 (sexp ,(js--regexp-opt-symbol typescript-ts-mode--sexp-nodes))
+                 (list ,(js--regexp-opt-symbol typescript-ts-mode--list-nodes))
+                 (sentence ,(js--regexp-opt-symbol typescript-ts-mode--sentence-nodes))
+                 (text ,(js--regexp-opt-symbol '("comment" "template_string"))))))
+
+  ;; Imenu (same as in `js-ts-mode') + namespace/interface.
   (setq-local 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))))
+              typescript-ts-mode--simple-imenu-settings)
+  ;; Outline minor mode
+  (setq-local treesit-outline-predicate typescript-ts-mode--outline-predicate))
 
 ;;;###autoload
 (define-derived-mode typescript-ts-mode typescript-ts-base-mode "TypeScript"
@@ -616,24 +649,21 @@ at least 3 (which is the default value)."
 
     (setq-local treesit-thing-settings
                 `((tsx
-                   (sexp ,(regexp-opt
+                   (sexp ,(js--regexp-opt-symbol
                            (append typescript-ts-mode--sexp-nodes
                                    '("jsx"))))
-                   (list ,(concat "^"
-                                       (regexp-opt
-                                        (append typescript-ts-mode--list-nodes
-                                                '(
-                                                  "jsx_element"
-                                                  "jsx_self_closing_element"
-                                                  "jsx_expression")))
-                                       "$"))
-                   (sentence ,(regexp-opt
+                   (list ,(js--regexp-opt-symbol
+                           (append typescript-ts-mode--list-nodes
+                                   '("jsx_element"
+                                     "jsx_self_closing_element"
+                                     "jsx_expression"))))
+                   (sentence ,(js--regexp-opt-symbol
                                (append typescript-ts-mode--sentence-nodes
-                                       '("jsx_element"
-                                         "jsx_self_closing_element"))))
-                   (text ,(regexp-opt '("comment"
-                                        "template_string"))
-                         'symbols))))
+                                       '("jsx_opening_element"
+                                         "jsx_attribute"
+                                         "jsx_closing_element"))))
+                   (text ,(js--regexp-opt-symbol '("comment"
+                                                   "template_string"))))))
 
     ;; Font-lock.
     (setq-local treesit-font-lock-settings