Developing major modes with tree-sitter
This section covers some general guidelines on developing tree-sitter integration for a major mode.
A major mode supporting tree-sitter features should roughly follow this pattern:
(define-derived-mode woomy-mode prog-mode "Woomy"
"A mode for Woomy programming language."
(when (treesit-ready-p 'woomy)
(setq-local treesit-variables ...)
...
(treesit-major-mode-setup)))
treesit-ready-p automatically emits a warning if conditions for enabling tree-sitter aren’t met.
If a tree-sitter major mode shares setup with its “native” counterpart, one can create a “base mode” that contains the common setup, like this:
(define-derived-mode woomy--base-mode prog-mode "Woomy" "An internal mode for Woomy programming language." (common-setup) ...)
(define-derived-mode woomy-mode woomy--base-mode "Woomy" "A mode for Woomy programming language." (native-setup) ...)
(define-derived-mode woomy-ts-mode woomy--base-mode "Woomy"
"A mode for Woomy programming language."
(when (treesit-ready-p 'woomy)
(setq-local treesit-variables ...)
...
(treesit-major-mode-setup)))
- Function: treesit-ready-p language &optional quiet
-
This function checks for conditions for activating tree-sitter. It checks whether Emacs was built with tree-sitter, whether the buffer’s size is not too large for tree-sitter to handle, and whether the grammar for language is available on the system (see Tree-sitter Language Grammar).
This function emits a warning if tree-sitter cannot be activated. If quiet is
message, the warning is turned into a message; if quiet ist, no warning or message is displayed.If all the necessary conditions are met, this function returns non-
nil; otherwise it returnsnil.
- Function: treesit-major-mode-setup
-
This function activates some tree-sitter features for a major mode.
Currently, it sets up the following features:
- If
treesit-font-lock-settings(see Parser-based Font Lock) is non-nil, it sets up fontification. - If either
treesit-simple-indent-rulesortreesit-indent-function(see Parser-based Indentation) is non-nil, it sets up indentation. - If
treesit-defun-type-regexpis non-nil, it sets up navigation functions forbeginning-of-defunandend-of-defun. See Moving over Balanced Expressions. - If
treesit-defun-name-functionis non-nil, it sets up add-log functions used byadd-log-current-defun. - If
treesit-simple-imenu-settings(see Imenu) is non-nil, it sets up Imenu. - If
treesit-outline-predicate(see Outline Minor Mode) is non-nil, it sets up Outline minor mode. - If
sexpand/orsentenceare defined intreesit-thing-settings(see User-defined “Things” and Navigation), it enables navigation commands that move, respectively, by sexps and sentences by defining variables such asforward-sexp-functionandforward-sentence-function.
- If
For more information on these built-in tree-sitter features, see Parser-based Font Lock, see Parser-based Indentation, and see Moving over Balanced Expressions.
For supporting mixing of multiple languages in a major mode, see Parsing Text in Multiple Languages.
Besides beginning-of-defun and end-of-defun, Emacs provides some additional functions for working with defuns: treesit-defun-at-point returns the defun node at point, and treesit-defun-name returns the name of a defun node.
- Function: treesit-defun-at-point
-
This function returns the defun node at point, or
nilif none is found. It respectstreesit-defun-tactic: if its value istop-level, this function returns the top-level defun, and if its value isnested, it returns the immediate enclosing defun.This function requires
treesit-defun-type-regexpto work. If it isnil, this function simply returnsnil.
- Function: treesit-defun-name node
-
This function returns the defun name of node. It returns
nilif there is no defun name for node, or if node is not a defun node, or if node isnil.Depending on the language and major mode, the defun names are names like function name, class name, struct name, etc.
If
treesit-defun-name-functionisnil, this function always returnsnil.
- Variable: treesit-defun-name-function
If non-
nil, this variable’s value should be a function that is called with a node as its argument, and returns the defun name of the node. The function should have the same semantics astreesit-defun-name: if the node is not a defun node, or the node is a defun node but doesn’t have a name, or the node isnil, it should returnnil.
Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Tree_002dsitter-Major-Modes.html