(when-let* ((query (treesit-generic-mode-font-lock-query lang)))
(setq-local treesit-font-lock-settings
- (treesit-font-lock-rules
- :language lang
- :feature 'highlights
- query))
- (setq-local treesit-font-lock-feature-list '((highlights))))))
+ (append treesit-font-lock-settings
+ (treesit-font-lock-rules
+ :language lang
+ :feature 'highlights
+ query)))
+ (setq-local treesit-font-lock-feature-list
+ (treesit-merge-font-lock-feature-list
+ treesit-font-lock-feature-list
+ '((highlights)))))))
;;; Generic font-lock handling
(setq-local comment-start "# ")
(setq-local comment-end ""))
+(define-treesit-generic-mode liquid-generic-ts-mode
+ "Tree-sitter generic mode for Liquid templates."
+ :lang 'liquid
+ :source "https://github.com/hankthetank27/tree-sitter-liquid"
+ :auto-mode "\\.liquid\\'"
+ :name "Liquid"
+ :parent mhtml-ts-mode
+
+ (setq-local treesit-range-settings
+ (append treesit-range-settings
+ (treesit-range-rules
+ :embed 'html
+ :host 'liquid
+ '(((template_content) @cap)))))
+
+ (setq-local treesit-thing-settings
+ (append treesit-thing-settings
+ `((liquid (sexp (not ,(rx bos "program" eos)))
+ (list ,(rx bos (or "range"
+ "if_statement"
+ "for_loop_statement"
+ "case_statement"
+ "unless_statement"
+ "capture_statement"
+ "form_statement"
+ "tablerow_statement"
+ "paginate_statement")
+ eos))))))
+
+ (setq-local treesit-aggregated-outline-predicate
+ (append treesit-aggregated-outline-predicate
+ `((liquid . ,(rx bos (or "if_statement"
+ "for_loop_statement")
+ eos)))))
+
+ (when (treesit-ready-p 'yaml t)
+ (defvar yaml-ts-mode--font-lock-settings)
+ (require 'yaml-ts-mode)
+ (setq-local treesit-range-settings
+ (append treesit-range-settings
+ (treesit-range-rules
+ :embed 'yaml
+ :host 'liquid
+ :local t
+ '(((front_matter) @cap)))))
+ (setq-local treesit-font-lock-settings
+ (append treesit-font-lock-settings
+ yaml-ts-mode--font-lock-settings))))
+
+(defvar alpinejs-generic-ts-attr-regexp
+ (rx bos (or "x-" ":" "@"))
+ "Regexp for HTML attributes handled by Alpine.js")
+
+(defun alpinejs-generic-ts-attr-not-match (node)
+ (not (string-match-p alpinejs-generic-ts-attr-regexp
+ (treesit-node-text node t))))
+
+(defun alpinejs-generic-ts-setup ()
+ "Tree-sitter generic setup for Alpine.js framework.
+It uses JavaScript highlighting inside a limited set of HTML attributes.
+Intended to be used in combination with such major modes as
+`mhtml-ts-mode' and `liquid-generic-ts-mode'. For example:
+
+\(add-hook \\='mhtml-ts-mode-hook \\='alpinejs-generic-ts-setup)
+\(add-hook \\='liquid-generic-ts-mode-hook \\='alpinejs-generic-ts-setup)"
+
+ ;; Use JavaScript highlighting for Alpinejs HTML attributes
+ (setq-local treesit-range-settings
+ (append treesit-range-settings
+ (treesit-range-rules
+ :embed 'javascript
+ :host 'html
+ :local t
+ `((attribute
+ (attribute_name) @_name
+ (:match ,alpinejs-generic-ts-attr-regexp @_name)
+ (quoted_attribute_value
+ (attribute_value) @cap))))))
+
+ ;; Highlight only non-Alpinejs HTML attributes
+ (setq-local treesit-font-lock-settings
+ (treesit-replace-font-lock-feature-settings
+ (treesit-font-lock-rules
+ :language 'html
+ :override t
+ :feature 'string
+ `((attribute
+ (attribute_name) @_name
+ (:pred alpinejs-generic-ts-attr-not-match @_name)
+ (quoted_attribute_value) @font-lock-string-face)))
+ treesit-font-lock-settings))
+
+ ;; Highlight only quotes for Alpinejs HTML attributes
+ (setq-local treesit-font-lock-settings
+ (append treesit-font-lock-settings
+ (treesit-font-lock-rules
+ :language 'html
+ :override t
+ :feature 'string
+ `((attribute
+ (attribute_name) @_name
+ (:match ,alpinejs-generic-ts-attr-regexp @_name)
+ (quoted_attribute_value "\"" @font-lock-string-face))))))
+
+ (treesit-major-mode-setup))
+
(provide 'treesit-x)
;;; treesit-x.el ends here
Return a value suitable for `treesit-font-lock-settings'"
(let ((result nil))
(dolist (new-setting new-settings)
- (let ((new-feature (treesit-font-lock-setting-feature new-setting)))
- (dolist (setting settings)
- (let ((feature (treesit-font-lock-setting-feature setting)))
- (if (eq new-feature feature)
- (push new-setting result)
- (push setting result))))))
+ (let ((new-feature (treesit-font-lock-setting-feature new-setting))
+ (new-lang (treesit-query-language
+ (treesit-font-lock-setting-query new-setting))))
+ (dolist (setting settings)
+ (let ((feature (treesit-font-lock-setting-feature setting))
+ (lang (treesit-query-language
+ (treesit-font-lock-setting-query setting))))
+ (if (and (eq new-lang lang) (eq new-feature feature))
+ (push new-setting result)
+ (push setting result))))))
(nreverse result)))
(defun treesit-add-font-lock-rules (rules &optional how feature)
;; 1ms in xdisp.c, and 0.3ms in a small C file (for typing a single
;; character), not worth it. --yuan
(dolist (setting treesit-font-lock-settings)
- (let* ((query (nth 0 setting))
- (enable (nth 1 setting))
- (override (nth 3 setting))
+ (let* ((query (treesit-font-lock-setting-query setting))
+ (enable (treesit-font-lock-setting-enable setting))
+ (override (treesit-font-lock-setting-override setting))
(language (treesit-query-language query))
(root-nodes (cl-remove-if-not
(lambda (node)