tree-sitter-hl-mode
provides a richer set of faces than font-lock-mode
. For example, function definitions are highlighted with tree-sitter-hl-face:function
, while function calls are highlighted with tree-sitter-hl-face:function.call
. However, for compatibility with existing themes, the default values for most of these faces inherit from built-in font-lock faces.
If you want to leverage the full power of Tree-sitter’s syntax highlighting approach, you should customize these faces.
By default, when the highlighting query associates a node with CAPTURE-NAME
, it will be highlighted with the face tree-sitter-hl-face:CAPTURE-NAME
. This behavior can be changed by customizing the variable tree-sitter-hl-face-mapping-function
.
;; Don't highlight strings, in any language.
(add-function :before-while tree-sitter-hl-face-mapping-function
(lambda (capture-name)
(not (string= capture-name "string"))))
;; Highlight only keywords in Python.
(add-hook 'python-mode-hook
(lambda ()
(add-function :before-while (local 'tree-sitter-hl-face-mapping-function)
(lambda (capture-name)
(string= capture-name "keyword")))))
;; Highlight Python docstrings with a different face.
(add-hook 'python-mode-hook
(lambda ()
(add-function :before-until (local 'tree-sitter-hl-face-mapping-function)
(lambda (capture-name)
(pcase capture-name
("doc" 'font-lock-comment-face))))))
You can use the function tree-sitter-hl-add-patterns
to add custom highlighting patterns for a specific language, or in a buffer. These patterns will be prioritized over patterns defined by major modes or language bundles (tree-sitter-hl-default-patterns
). Below are some examples:
Language-specific patterns:
;; Highlight Python's single-quoted strings as constants.
(tree-sitter-hl-add-patterns 'python
[((string) @constant
(.match? @constant "^'"))])
Buffer-local patterns:
;; Map @rust.unsafe.use capture to a custom face.
(add-function :before-until tree-sitter-hl-face-mapping-function
(lambda (capture-name)
(pcase capture-name
("rust.unsafe.use" 'my-dangerous-code-pattern-face))))
;; Add highlighting patterns for @rust.unsafe.use.
(add-hook 'rust-mode-hook
(lambda ()
(tree-sitter-hl-add-patterns nil
[(unsafe_block) @rust.unsafe.use
(impl_item "unsafe") @rust.unsafe.use])))
Project-specific patterns (through .dir-locals.el
):
;; Highlight DEFUN macros (in Emacs's C source).
((c-mode . ((tree-sitter-hl--extra-patterns-list
[((call_expression
function: (identifier) @keyword
arguments: (argument_list
(string_literal) @function))
(.eq? @keyword "DEFUN"))]))))
When a node matches multiple patterns in a highlighting query, earlier patterns are prioritized.
;; More specific patterns should be written earlier.
((lifetime (identifier) @type.builtin)
(.eq? @type.builtin "static"))
(lifetime (identifier) @label)