]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve treesit settings for {json,html,toml,yaml}-ts-mode (bug#73404)
authorJuri Linkov <juri@linkov.net>
Sun, 9 Feb 2025 17:54:02 +0000 (19:54 +0200)
committerEshel Yaron <me@eshelyaron.com>
Mon, 10 Feb 2025 20:56:06 +0000 (21:56 +0100)
* lisp/progmodes/json-ts-mode.el (json-ts-mode): Add 'list' thing
to 'treesit-thing-settings'.
(json-ts-mode): Disable outlines.

* lisp/textmodes/html-ts-mode.el (html-ts-mode--defun-name):
Get a grandchild 'tag_name' from 'element' that was already
defined by 'treesit-defun-type-regexp'.
(html-ts-mode--outline-predicate): New function.
(html-ts-mode): Add "comment" to the 'list' thing
in 'treesit-thing-settings'.  Use "tag_name" and "attribute"
in 'sentence' to conform to sentence navigating arguments
in other ts-modes.  Remove unnecessary heading
from 'treesit-simple-imenu-settings' and use "element"
supported by 'html-ts-mode--defun-name'.
Set 'treesit-outline-predicate' to 'html-ts-mode--outline-predicate'.

* lisp/textmodes/toml-ts-mode.el (toml-ts-mode):
Add 'treesit-thing-settings'.

* lisp/textmodes/yaml-ts-mode.el (yaml-ts-mode--defun-name)
(yaml-ts-mode--outline-predicate): New functions.
(yaml-ts-mode): Set 'treesit-defun-type-regexp',
'treesit-defun-name-function', 'treesit-defun-tactic'.
Add 'sentence' to 'treesit-thing-settings'.
Set 'treesit-simple-imenu-settings' and 'treesit-outline-predicate'.
Use 'kill-local-variable' for 'forward-sexp-function'
and 'show-paren-data-function' instead of resetting their value.

* lisp/treesit.el (treesit-outline-search): Check for the thing
before the end of the line to support such case when the thing
fits on the current line and ends before the end of the line
such as e.g. '<h1>...</h1>' in html-ts-mode.
(treesit-hs-find-next-block, treesit-hs-inside-comment-p):
Use anchors for "\\`comment\\'" (bug#75609).

(cherry picked from commit e9d17e41971c887675d52e1dcee21978d4247130)

lisp/progmodes/json-ts-mode.el
lisp/textmodes/html-ts-mode.el
lisp/textmodes/toml-ts-mode.el
lisp/textmodes/yaml-ts-mode.el
lisp/treesit.el

index f26ba9e8d63d4434e99ca44a0998a2ba8988194e..1b8f033e97ad1d4fb9d26bd254fe25505ebcbab5 100644 (file)
@@ -152,6 +152,7 @@ Return nil if there is no name or if NODE is not a defun node."
 
   (setq-local treesit-thing-settings
               `((json
+                 (list ,(rx (or "object" "array")))
                  (sentence "pair"))))
 
   ;; Font-lock.
@@ -165,7 +166,12 @@ Return nil if there is no name or if NODE is not a defun node."
   (setq-local treesit-simple-imenu-settings
               '((nil "\\`pair\\'" nil nil)))
 
-  (treesit-major-mode-setup))
+  (treesit-major-mode-setup)
+
+  ;; Disable outlines since they are created for 'pair' from
+  ;; 'treesit-simple-imenu-settings' almost on every line:
+  (kill-local-variable 'outline-search-function)
+  (kill-local-variable 'outline-level))
 
 (derived-mode-add-parents 'json-ts-mode '(json-mode))
 
index dad49b7ed4ccf86bbf3c5aa4c9decdb75f006649..7e6c3e0b7d1e57ad4c23dd433b02907722b945fc 100644 (file)
 (defun html-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."
-  (when (equal (treesit-node-type node) "tag_name")
-    (treesit-node-text node t)))
+  (when (string-match-p "element" (treesit-node-type node))
+    (treesit-node-text
+     (treesit-search-subtree node "\\`tag_name\\'" nil nil 2)
+     t)))
+
+(defun html-ts-mode--outline-predicate (node)
+  "Limit outlines to a few most meaningful elements."
+  (let ((name (html-ts-mode--defun-name node)))
+    (and name (string-match-p
+               (rx bos (or "html" "head" "script" "style"
+                           "body" (and "h" (any "1-6"))
+                           "ol" "ul" "table")
+                   eos)
+               name))))
 
 ;;;###autoload
 (define-derived-mode html-ts-mode html-mode "HTML"
@@ -108,7 +120,6 @@ Return nil if there is no name or if NODE is not a defun node."
 
   ;; Navigation.
   (setq-local treesit-defun-type-regexp "element")
-
   (setq-local treesit-defun-name-function #'html-ts-mode--defun-name)
 
   (setq-local treesit-thing-settings
@@ -117,8 +128,12 @@ Return nil if there is no name or if NODE is not a defun node."
                                       "text"
                                       "attribute"
                                       "value")))
-                 (list ,(regexp-opt '("element")) 'symbols)
-                 (sentence "tag")
+                 (list ,(rx (or
+                             ;; Also match script_element and style_element
+                             "element"
+                             ;; HTML comments have the element syntax
+                             "comment")))
+                 (sentence ,(rx (and bos (or "tag_name" "attribute") eos)))
                  (text ,(regexp-opt '("comment" "text"))))))
 
   ;; Font-lock.
@@ -130,10 +145,10 @@ Return nil if there is no name or if NODE is not a defun node."
 
   ;; Imenu.
   (setq-local treesit-simple-imenu-settings
-              '(("Element" "\\`tag_name\\'" nil nil)))
+              '((nil "element" nil nil)))
 
   ;; Outline minor mode.
-  (setq-local treesit-outline-predicate "\\`element\\'")
+  (setq-local treesit-outline-predicate #'html-ts-mode--outline-predicate)
   ;; `html-ts-mode' inherits from `html-mode' that sets
   ;; regexp-based outline variables.  So need to restore
   ;; the default values of outline variables to be able
index 759995590f65badbee9aadefcfa3588f0058d37a..3b55fe7706a686e3ff2714acdceefd4239410284 100644 (file)
@@ -137,6 +137,14 @@ Return nil if there is no name or if NODE is not a defun node."
     (setq-local treesit-defun-type-regexp
                 (rx (or "table" "table_array_element")))
     (setq-local treesit-defun-name-function #'toml-ts-mode--defun-name)
+    (setq-local treesit-thing-settings
+                `((toml
+                   (list
+                    ,(rx bos (or "array" "inline_table") eos))
+                   (sentence
+                    ,(rx bos (or "pair") eos))
+                   (text
+                    ,(rx bos (or "comment") eos)))))
 
     ;; Font-lock.
     (setq-local treesit-font-lock-settings toml-ts-mode--font-lock-settings)
index defef096aa6395116addaf0eaf5f9e7d0878175e..7a5132634cacc27b4b8567487566f4cc31c6d8dd 100644 (file)
@@ -141,6 +141,19 @@ boundaries.  JUSTIFY is passed to `fill-paragraph'."
           (fill-region start-marker end justify))
         t))))
 
+(defun yaml-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."
+  (when (equal (treesit-node-type node) "block_mapping_pair")
+    (treesit-node-text (treesit-node-child-by-field-name
+                        node "key")
+                       t)))
+
+(defun yaml-ts-mode--outline-predicate (node)
+  "Limit outlines to top-level mappings."
+  (when (equal (treesit-node-type node) "block_mapping_pair")
+    (not (treesit-parent-until node treesit-outline-predicate))))
+
 ;;;###autoload
 (define-derived-mode yaml-ts-mode text-mode "YAML"
   "Major mode for editing YAML, powered by tree-sitter."
@@ -168,11 +181,21 @@ boundaries.  JUSTIFY is passed to `fill-paragraph'."
     (setq-local fill-paragraph-function #'yaml-ts-mode--fill-paragraph)
 
     ;; Navigation.
+    (setq-local treesit-defun-type-regexp "block_mapping_pair")
+    (setq-local treesit-defun-name-function #'yaml-ts-mode--defun-name)
+    (setq-local treesit-defun-tactic 'top-level)
+
     (setq-local treesit-thing-settings
                 `((yaml
-                   (list ,(regexp-opt '("block_mapping_pair"
-                                        "flow_sequence"))
-                         'symbols))))
+                   (list ,(rx (or "block_mapping_pair" "flow_sequence")))
+                   (sentence ,"block_mapping_pair"))))
+
+    ;; Imenu.
+    (setq-local treesit-simple-imenu-settings
+                '((nil "\\`block_mapping_pair\\'" nil nil)))
+
+    ;; Outline minor mode.
+    (setq-local treesit-outline-predicate #'yaml-ts-mode--outline-predicate)
 
     (treesit-major-mode-setup)
 
@@ -181,8 +204,8 @@ boundaries.  JUSTIFY is passed to `fill-paragraph'."
     ;; with `C-M-f', `C-M-b' neither adapt to 'show-paren-mode'
     ;; that is problematic in languages without explicit
     ;; opening/closing nodes.
-    (setq-local forward-sexp-function nil)
-    (setq-local show-paren-data-function 'show-paren--default)))
+    (kill-local-variable 'forward-sexp-function)
+    (kill-local-variable 'show-paren-data-function)))
 
 (derived-mode-add-parents 'yaml-ts-mode '(yaml-mode))
 
index d4ffb7188d889f9c92310c768df7b4636f7bddbb..e29f757d36a52103cc461b82fbd6035b5e413e01 100644 (file)
@@ -3505,7 +3505,7 @@ when a major mode sets it.")
 For BOUND, MOVE, BACKWARD, LOOKING-AT, see the descriptions in
 `outline-search-function'."
   (if looking-at
-      (when-let* ((node (or (treesit-thing-at (pos-eol) treesit-outline-predicate)
+      (when-let* ((node (or (treesit-thing-at (1- (pos-eol)) treesit-outline-predicate)
                             (treesit-thing-at (pos-bol) treesit-outline-predicate)))
                   (start (treesit-node-start node)))
         (eq (pos-bol) (save-excursion (goto-char start) (pos-bol))))
@@ -3579,7 +3579,7 @@ For BOUND, MOVE, BACKWARD, LOOKING-AT, see the descriptions in
   (let* ((comment-pred
           (when comments
             (if (treesit-thing-defined-p 'comment (treesit-language-at (point)))
-                'comment "comment")))
+                'comment "\\`comment\\'")))
          (pred (if comment-pred (append '(or list) (list comment-pred)) 'list))
          ;; `treesit-navigate-thing' can't find a thing at bobp,
          ;; so use `treesit-thing-at' to match at bobp.
@@ -3614,7 +3614,7 @@ For BOUND, MOVE, BACKWARD, LOOKING-AT, see the descriptions in
   "Tree-sitter implementation of `hs-inside-comment-p-func'."
   (let* ((comment-pred
           (if (treesit-thing-defined-p 'comment (treesit-language-at (point)))
-              'comment "comment"))
+              'comment "\\`comment\\'"))
          (thing (or (treesit-thing-at (point) comment-pred)
                     (unless (bobp)
                       (treesit-thing-at (1- (point)) comment-pred)))))