Improve treesit settings for {json,html,toml,yaml}-ts-mode (bug#73404)
* 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).
This commit is contained in:
parent
7e60ceeccb
commit
e9d17e4197
5 changed files with 68 additions and 16 deletions
|
@ -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))
|
||||
|
||||
|
|
|
@ -90,8 +90,20 @@
|
|||
(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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -3512,7 +3512,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))))
|
||||
|
@ -3586,7 +3586,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.
|
||||
|
@ -3621,7 +3621,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)))))
|
||||
|
|
Loading…
Add table
Reference in a new issue