]> git.eshelyaron.com Git - emacs.git/commitdiff
Add treesit-add-font-lock-rules
authorYuan Fu <casouri@gmail.com>
Sat, 20 Apr 2024 07:42:25 +0000 (00:42 -0700)
committerEshel Yaron <me@eshelyaron.com>
Mon, 22 Apr 2024 18:36:35 +0000 (20:36 +0200)
This function should help users customize font-lock rules.

* lisp/treesit.el (treesit-add-font-lock-rules): New function.

(cherry picked from commit bf5755aa91905a376e4ac9fedde6a645486e1589)

etc/NEWS
lisp/treesit.el

index 549bbe019265be2d9e674da189b90dd521d50ec4..be9e7dfbf9faa17fe46b15b72fdf660e864c40c3 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2689,7 +2689,16 @@ parsers with that tag.  Note that passing nil as tag doesn't mean return
 all parsers, but rather "all parsers with no tags".
 
 +++
-*** New function 'treesit-parser-changed-ranges' which returns buffer regions that are affected by the last buffer edits
+*** New function 'treesit-parser-changed-ranges'.
+
+This function returns buffer regions that are affected by the last
+buffer edits.
+
+*** New function 'treesit-add-font-lock-rules'.
+
+This function helps user to add custom font-lock rules to a tree-sitter
+major mode.
+
 
 \f
 * Changes in Emacs 30.1 on Non-Free Operating Systems
index 4c9cf5a36e7e693151349b5012fd8049df1bdb64..e55e04e53b3f81db4df3673c8354bdeec687b021 100644 (file)
@@ -817,6 +817,17 @@ OVERRIDE is the override flag for this query.  Its value can be
 t, nil, append, prepend, keep.  See more in
 `treesit-font-lock-rules'.")
 
+(defsubst treesit--font-lock-setting-feature (setting)
+  "Reutrn the feature of SETTING.
+SETTING should be a setting in `treesit-font-lock-settings'."
+  (nth 2 setting))
+
+(defsubst treesit--font-lock-setting-enable (setting)
+  "Return enabled SETTING."
+  (let ((new-setting (copy-tree setting)))
+    (setf (nth 1 new-setting) t)
+    new-setting))
+
 (defun treesit--font-lock-level-setter (sym val)
   "Custom setter for `treesit-font-lock-level'.
 Set the default value of SYM to VAL, recompute fontification
@@ -1095,6 +1106,43 @@ and leave settings for other languages unchanged."
                        ((memq feature remove-list) nil)
                        (t current-value))))))
 
+(defun treesit-add-font-lock-rules (rules &optional how feature)
+  "Add font-lock RULES to the current buffer
+
+RULES should be the return value of `treesit-font-lock-rules'.  RULES
+will be enabled and added to `treesit-font-lock-settings'.
+
+HOW can be either :before or :after.  If HOW is :before, prepend RULES
+before all other existing font-lock rules in
+`treesit-font-lock-settings'; if :after or omitted, append RULES after
+all existing rules.
+
+If FEATURE is non-nil, add RULES before/after rules for FEATURE.  See
+docstring of `treesit-font-lock-rules' for what is a feature."
+  (let ((rules (seq-map #'treesit--font-lock-setting-enable rules))
+        (feature-idx
+         (when feature
+           (cl-position-if
+            (lambda (setting)
+              (eq (treesit--font-lock-setting-feature setting) feature))
+            treesit-font-lock-settings))))
+    (pcase (cons how feature)
+      ((or '(:after . nil) '(nil . nil))
+       (setq treesit-font-lock-settings
+             (append treesit-font-lock-settings rules)))
+      ('(:before . nil)
+       (setq treesit-font-lock-settings
+             (append rules treesit-font-lock-settings)))
+      (`(:after . ,_feature)
+       (setf (nthcdr (1+ feature-idx) treesit-font-lock-settings)
+             (append rules
+                     (nthcdr (1+ feature-idx)
+                             treesit-font-lock-settings))))
+      (`(:before . ,_feature)
+       (setf (nthcdr feature-idx treesit-font-lock-settings)
+             (append rules
+                     (nthcdr feature-idx treesit-font-lock-settings)))))))
+
 (defun treesit-fontify-with-override
     (start end face override &optional bound-start bound-end)
   "Apply FACE to the region between START and END.