]> git.eshelyaron.com Git - emacs.git/commitdiff
Add jsdoc support to js-ts-mode
authorDamien Cassou <damien@cassou.me>
Fri, 14 Jun 2024 08:46:42 +0000 (10:46 +0200)
committerEshel Yaron <me@eshelyaron.com>
Mon, 24 Jun 2024 07:16:34 +0000 (09:16 +0200)
* 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

index f5629ff8fbe0ebb48212432885ac9feb40c089d2..529b31669ed421dbb445961b72e3a7d0c2899e03 100644 (file)
@@ -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