Function: treesit-major-mode-setup

treesit-major-mode-setup is a byte-compiled function defined in treesit.el.gz.

Signature

(treesit-major-mode-setup)

Documentation

Activate tree-sitter to power major-mode features.

If treesit-font-lock-settings is non-nil, set up fontification and enable font-lock-mode(var)/font-lock-mode(fun).

If treesit-simple-indent-rules is non-nil, set up indentation.

If treesit-defun-type-regexp is non-nil or defun is defined in treesit-thing-settings, set up beginning-of-defun-function, end-of-defun-function, and prog-fill-reindent-defun-function.

If treesit-defun-name-function is non-nil, set up add-log-current-defun.

If treesit-simple-imenu-settings or treesit-aggregated-simple-imenu-settings is non-nil, set up Imenu.

If either treesit-outline-predicate or treesit-simple-imenu-settings are non-nil, and Outline minor mode settings don't already exist, setup Outline minor mode.

If sexp, sentence are defined in treesit-thing-settings, enable tree-sitter navigation commands for them.

Make sure necessary parsers are created for the current buffer before calling this function.

View in manual

Probably introduced at or before Emacs version 30.1.

Source Code

;; Defined in /usr/src/emacs/lisp/treesit.el.gz
(defun treesit-major-mode-setup ()
  "Activate tree-sitter to power major-mode features.

If `treesit-font-lock-settings' is non-nil, set up fontification
and enable `font-lock-mode'.

If `treesit-simple-indent-rules' is non-nil, set up indentation.

If `treesit-defun-type-regexp' is non-nil or `defun' is defined
in `treesit-thing-settings', set up `beginning-of-defun-function',
`end-of-defun-function', and `prog-fill-reindent-defun-function'.

If `treesit-defun-name-function' is non-nil, set up
`add-log-current-defun'.

If `treesit-simple-imenu-settings' or
`treesit-aggregated-simple-imenu-settings' is non-nil, set up Imenu.

If either `treesit-outline-predicate' or `treesit-simple-imenu-settings'
are non-nil, and Outline minor mode settings don't already exist, setup
Outline minor mode.

If `sexp', `sentence' are defined in `treesit-thing-settings',
enable tree-sitter navigation commands for them.

Make sure necessary parsers are created for the current buffer
before calling this function."
  (unless treesit-primary-parser
    (setq treesit-primary-parser (treesit--guess-primary-parser)))
  ;; Font-lock.
  (when treesit-font-lock-settings
    ;; Functions like `treesit-font-lock-recompute-features' and
    ;; `treesit-validate-and-compile-font-lock-rules' modifies
    ;; `treesit-font-lock-settings' in-place, so make a copy to protect
    ;; the original variable defined in major mode code.
    (setq treesit-font-lock-settings (copy-tree treesit-font-lock-settings))
    ;; `font-lock-mode' wouldn't set up properly if
    ;; `font-lock-defaults' is nil, see `font-lock-specified-p'.
    (setq-local font-lock-defaults
                '( nil nil nil nil
                   (font-lock-fontify-syntactically-function
                    . treesit-font-lock-fontify-region)))
    (treesit-font-lock-recompute-features)
    (treesit-validate-and-compile-font-lock-rules treesit-font-lock-settings)
    (add-hook 'pre-redisplay-functions #'treesit--pre-redisplay 0 t))
  ;; Syntax
  (add-hook 'syntax-propertize-extend-region-functions
            #'treesit--pre-syntax-ppss 0 t)
  ;; Indent.
  (when treesit-simple-indent-rules
    (setq-local treesit-simple-indent-rules
                (treesit--indent-rules-optimize
                 treesit-simple-indent-rules)))
  ;; Enable indent if simple indent rules are set, or the major mode
  ;; sets a custom indent function.
  (when (or treesit-simple-indent-rules
            (and (not (eq treesit-indent-function #'treesit-simple-indent))
                 treesit-indent-function))
    (setq-local indent-line-function #'treesit-indent)
    (setq-local indent-region-function #'treesit-indent-region))
  ;; Navigation.
  (when (or treesit-defun-type-regexp
            (treesit-thing-defined-p 'defun nil))
    (keymap-set (current-local-map) "<remap> <beginning-of-defun>"
                #'treesit-beginning-of-defun)
    (keymap-set (current-local-map) "<remap> <end-of-defun>"
                #'treesit-end-of-defun)
    ;; `end-of-defun' will not work completely correctly in nested
    ;; defuns due to its implementation.  However, many lisp programs
    ;; use `beginning/end-of-defun', so we should still set
    ;; `beginning/end-of-defun-function' so they still mostly work.
    ;; This is also what `cc-mode' does: rebind user commands and set
    ;; the variables.  In future we should update `end-of-defun' to
    ;; work with nested defuns.
    (setq-local beginning-of-defun-function #'treesit-beginning-of-defun)
    (setq-local end-of-defun-function #'treesit-end-of-defun)
    (setq-local prog-fill-reindent-defun-function
                #'treesit-fill-reindent-defun))
  ;; Defun name.
  (when treesit-defun-name-function
    (setq-local add-log-current-defun-function
                #'treesit-add-log-current-defun))

  (setq-local transpose-sexps-function #'treesit-transpose-sexps)

  (when (treesit-thing-defined-p 'sexp nil)
    (setq-local forward-sexp-function #'treesit-forward-sexp))

  (when (treesit-thing-defined-p 'list nil)
    (setq-local forward-sexp-function #'treesit-forward-sexp-list)
    (setq-local forward-list-function #'treesit-forward-list)
    (setq-local down-list-function #'treesit-down-list)
    (setq-local up-list-function #'treesit-up-list)
    (setq-local show-paren-data-function #'treesit-show-paren-data)
    (setq-local hs-c-start-regexp nil
                hs-block-start-regexp nil
                hs-block-end-regexp #'treesit-hs-block-end
                hs-forward-sexp-function #'forward-list
                hs-find-block-beginning-function #'treesit-hs-find-block-beginning
                hs-find-next-block-function #'treesit-hs-find-next-block
                hs-looking-at-block-start-predicate #'treesit-hs-looking-at-block-start-p
                hs-inside-comment-predicate #'treesit-hs-inside-comment-p))

  (when (treesit-thing-defined-p 'sentence nil)
    (setq-local forward-sentence-function #'treesit-forward-sentence))

  (when (treesit-thing-defined-p 'comment nil)
    (setq-local forward-comment-function #'treesit-forward-comment))

  ;; Imenu.
  (when (or treesit-aggregated-simple-imenu-settings
            treesit-simple-imenu-settings)
    (setq-local imenu-create-index-function
                #'treesit-simple-imenu))

  ;; Outline minor mode.
  (when (and (or treesit-outline-predicate
                 treesit-aggregated-outline-predicate
                 treesit-simple-imenu-settings)
             (not (seq-some #'local-variable-p
                            '(outline-search-function
                              outline-regexp outline-level))))
    (unless (or treesit-outline-predicate
                treesit-aggregated-outline-predicate)
      (setq treesit-outline-predicate
            #'treesit-outline-predicate--from-imenu))
    (setq-local outline-search-function #'treesit-outline-search
                outline-level #'treesit-outline-level))

  ;; Remove existing local parsers.
  (dolist (ov (overlays-in (point-min) (point-max)))
    (let ((parser (overlay-get ov 'treesit-parser))
          (local-p (overlay-get ov 'treesit-parser-local-p)))
      (when (and parser local-p)
        (treesit-parser-delete parser))
      (delete-overlay ov))))