From 8b7af795dacafeda3a2121b6fd48cb0e47877138 Mon Sep 17 00:00:00 2001 From: Damien Cassou Date: Fri, 14 Jun 2024 10:46:42 +0200 Subject: [PATCH] Add jsdoc support to js-ts-mode * lisp/progmodes/js.el (js--treesit-font-lock-settings): Add jsdoc font-lock settings. (js--treesit-jsdoc-beginning-regexp): New variable to match the beginning of a jsdoc block. (js-ts-mode): Add jsdoc support. Save the 'javascript parser to `treesit-primary-parser'. Configure `treesit-range-settings' to use a jsdoc parser within a JavaScript file. (js-ts-language-at-point): New function to return either 'jsdoc or 'javascript depending on where the point is. (cherry picked from commit 0edacf2aa7e53d0cec95bcaae4cd19e5389b70f8) --- lisp/progmodes/js.el | 54 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index f5629ff8fbe..529b31669ed 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -3634,7 +3634,32 @@ Check if a node type is available, then return the right indent rules." :language 'javascript :feature 'escape-sequence :override t - '((escape_sequence) @font-lock-escape-face)) + '((escape_sequence) @font-lock-escape-face) + + :language 'jsdoc + :override t + :feature 'keyword + '((tag_name) @font-lock-keyword-face) + + :language 'jsdoc + :override t + :feature 'bracket + '((["{" "}"]) @font-lock-bracket-face) + + :language 'jsdoc + :override t + :feature 'property + '((type) @font-lock-variable-use-face) + + :language 'jsdoc + :override t + :feature 'definition + '((identifier) @font-lock-variable-name-face) + + :language 'jsdoc + :override t + :feature 'comment + '((description) @font-lock-comment-face)) "Tree-sitter font-lock settings.") (defun js--fontify-template-string (node override start end &rest _) @@ -3857,6 +3882,9 @@ See `treesit-thing-settings' for more information.") "Nodes that designate sexps in JavaScript. See `treesit-thing-settings' for more information.") +(defvar js--treesit-jsdoc-beginning-regexp (rx bos "/**") + "Regular expression matching the beginning of a jsdoc block comment.") + ;;;###autoload (define-derived-mode js-ts-mode js-base-mode "JavaScript" "Major mode for editing JavaScript. @@ -3882,7 +3910,8 @@ See `treesit-thing-settings' for more information.") (setq-local syntax-propertize-function #'js-ts--syntax-propertize) ;; Tree-sitter setup. - (treesit-parser-create 'javascript) + (setq-local treesit-primary-parser (treesit-parser-create 'javascript)) + ;; Indent. (setq-local treesit-simple-indent-rules js--treesit-indent-rules) ;; Navigation. @@ -3909,6 +3938,16 @@ See `treesit-thing-settings' for more information.") ( assignment constant escape-sequence jsx number pattern string-interpolation) ( bracket delimiter function operator property))) + + (when (treesit-ready-p 'jsdoc t) + (setq-local treesit-range-settings + (treesit-range-rules + :embed 'jsdoc + :host 'javascript + `(((comment) @capture (:match ,js--treesit-jsdoc-beginning-regexp @capture)))))) + + (setq-local treesit-language-at-point-function #'js-ts-language-at-point) + ;; Imenu (setq-local treesit-simple-imenu-settings `(("Function" "\\`function_declaration\\'" nil nil) @@ -3950,6 +3989,17 @@ See `treesit-thing-settings' for more information.") (put-text-property ns (1+ ns) 'syntax-table syntax) (put-text-property (1- ne) ne 'syntax-table syntax))))) +(defun js-ts-language-at-point (point) + "Return the language at POINT." + (let ((node (treesit-node-at point 'javascript))) + (if (and (treesit-ready-p 'jsdoc) + (equal (treesit-node-type node) "comment") + (string-match-p + js--treesit-jsdoc-beginning-regexp + (treesit-node-text node))) + 'jsdoc + 'javascript))) + ;;;###autoload (define-derived-mode js-json-mode prog-mode "JSON" :syntax-table js-mode-syntax-table -- 2.39.2