js-mode "\\(@[[:alpha:]]+\\>\\|$\\)")
;;; Tree sitter integration
-(defcustom js-use-tree-sitter nil
- "If non-nil, `js-mode' tries to use tree-sitter.
-Currently `js-mode' uses tree-sitter for font-locking,
-indentation, which-function and movement functions."
- :version "29.1"
- :type 'boolean
- :safe 'booleanp)
(defun js--treesit-backward-up-list ()
(lambda (_node _parent _bol &rest _)
do (setq node (treesit-node-parent node))
finally return (string-join name-list "."))))
-(defvar js--treesit-defun-type-regexp
- (rx (or "class_declaration"
- "method_definition"
- "function_declaration"
- "lexical_declaration"))
- "Regular expression that matches type of defun nodes.
-Used in `js--treesit-beginning-of-defun' and friends.")
-
-(defun js--treesit-beginning-of-defun (&optional arg)
- "Tree-sitter `beginning-of-defun' function.
-ARG is the same as in `beginning-of-defun."
- (let ((arg (or arg 1)))
- (if (> arg 0)
- ;; Go backward.
- (while (and (> arg 0)
- (treesit-search-forward-goto
- js--treesit-defun-type-regexp 'start nil t))
- (setq arg (1- arg)))
- ;; Go forward.
- (while (and (< arg 0)
- (treesit-search-forward-goto
- js--treesit-defun-type-regexp 'start))
- (setq arg (1+ arg))))))
-
-(defun js--treesit-end-of-defun (&optional arg)
- "Tree-sitter `end-of-defun' function.
-ARG is the same as in `end-of-defun."
- (let ((arg (or arg 1)))
- (if (< arg 0)
- ;; Go backward.
- (while (and (< arg 0)
- (treesit-search-forward-goto
- js--treesit-defun-type-regexp 'end nil t))
- (setq arg (1+ arg)))
- ;; Go forward.
- (while (and (> arg 0)
- (treesit-search-forward-goto
- js--treesit-defun-type-regexp 'end))
- (setq arg (1- arg))))))
-
-(defun js--backend-toggle (backend warn)
- "Toggle backend for `js-mode'.
-For BACKEND and WARN see `treesit-mode-function'."
- (cond
- ;; Tree-sitter.
- ((and (eq backend 'treesit) (treesit-ready-p warn 'javascript))
- (setq-local treesit-simple-indent-rules js--treesit-indent-rules)
- (setq-local indent-line-function #'treesit-indent)
-
- (setq-local beginning-of-defun-function #'js--treesit-beginning-of-defun)
- (setq-local end-of-defun-function #'js--treesit-end-of-defun)
-
- (add-hook 'which-func-functions #'js-treesit-current-defun nil t)
-
- (setq-local font-lock-keywords-only t)
- (setq-local treesit-font-lock-settings js--treesit-font-lock-settings)
- (setq-local treesit-font-lock-feature-list '((minimal) (moderate) (full)))
- (treesit-font-lock-enable))
- ;; Elisp.
- ((eq backend 'elisp)
- (setq-local indent-line-function #'js-indent-line)
- (setq-local beginning-of-defun-function #'js-beginning-of-defun)
- (setq-local end-of-defun-function #'js-end-of-defun)
-
- (setq-local font-lock-defaults
- (list js--font-lock-keywords nil nil nil nil
- '(font-lock-syntactic-face-function
- . js-font-lock-syntactic-face-function)))
-
- ;; Imenu
- (setq imenu-case-fold-search nil)
- (setq imenu-create-index-function #'js--imenu-create-index))))
-
;;; Main Function
;;;###autoload
:group 'js
;; Ensure all CC Mode "lang variables" are set to valid values.
(c-init-language-vars js-mode)
+ (setq-local indent-line-function #'js-indent-line)
+ (setq-local beginning-of-defun-function #'js-beginning-of-defun)
+ (setq-local end-of-defun-function #'js-end-of-defun)
(setq-local open-paren-in-column-0-is-defun-start nil)
+ (setq-local font-lock-defaults
+ (list js--font-lock-keywords nil nil nil nil
+ '(font-lock-syntactic-face-function
+ . js-font-lock-syntactic-face-function)))
(setq-local syntax-propertize-function #'js-syntax-propertize)
(add-hook 'syntax-propertize-extend-region-functions
#'syntax-propertize-multiline 'append 'local)
(setq-local comment-start "// ")
(setq-local comment-start-skip "\\(?://+\\|/\\*+\\)\\s *")
(setq-local comment-end "")
+ (setq-local fill-paragraph-function #'js-fill-paragraph)
+ (setq-local normal-auto-fill-function #'js-do-auto-fill)
;; Parse cache
(add-hook 'before-change-functions #'js--flush-caches t t)
(add-hook 'after-change-functions #'js-jsx--detect-after-change nil t))
(js-use-syntactic-mode-name)
+ ;; Imenu
+ (setq imenu-case-fold-search nil)
+ (setq imenu-create-index-function #'js--imenu-create-index)
+
;; for filling, pretend we're cc-mode
(c-foreign-init-lit-pos-cache)
(add-hook 'before-change-functions #'c-foreign-truncate-lit-pos-cache nil t)
(setq-local electric-layout-rules
'((?\; . after) (?\{ . after) (?\} . before)))
- (setq-local fill-paragraph-function #'js-fill-paragraph)
- (setq-local normal-auto-fill-function #'js-do-auto-fill)
-
(let ((c-buffer-is-cc-mode t))
;; FIXME: These are normally set by `c-basic-common-init'. Should
;; we call it instead? (Bug#6071)
;; will mysteriously disappear.
;; FIXME: We should instead do this fontification lazily by adding
;; calls to syntax-propertize wherever it's really needed.
- ;; (syntax-propertize (point-max))
-
- (js--backend-toggle 'elisp nil)
- (setq-local major-mode-backend-function #'js--backend-toggle))
+ ;;(syntax-propertize (point-max))
+
+ ;; Tree-sitter support.
+ (setq-local treesit-mode-supported t)
+ (setq-local treesit-required-languages '(javascript))
+ (setq-local treesit-simple-indent-rules js--treesit-indent-rules)
+ (setq-local treesit-defun-type-regexp
+ (rx (or "class_declaration"
+ "method_definition"
+ "function_declaration"
+ "lexical_declaration")))
+ (setq-local treesit-font-lock-settings js--treesit-font-lock-settings)
+ (setq-local treesit-font-lock-feature-list '((minimal) (moderate) (full))))
(defvar js-json--treesit-font-lock-settings
(treesit-font-lock-rules
((parent-is "object") parent-bol ,js-indent-level)
)))
-(defun js--json-backend-toggle (backend warn)
- "Toggle backend for `json-mode'.
-For BACKEND and WARN see `treesit-mode-function'."
- (cond
- ;; Tree-sitter.
- ((and (eq backend 'treesit) (treesit-ready-p warn 'json))
- (setq-local treesit-simple-indent-rules js--json-treesit-indent-rules)
- (setq-local indent-line-function #'treesit-indent)
-
- (setq-local font-lock-keywords-only t)
- (setq-local treesit-font-lock-settings js-json--treesit-font-lock-settings)
- (treesit-font-lock-enable))
- ;; Elisp.
- ((eq backend 'elisp)
- (js--backend-toggle 'elisp nil))))
-
;;;###autoload
(define-derived-mode js-json-mode js-mode "JSON"
(setq-local js-enabled-frameworks nil)
;; Speed up `syntax-ppss': JSON files can be big but can't hold
;; regexp matchers nor #! thingies (and `js-enabled-frameworks' is nil).
(setq-local syntax-propertize-function #'ignore)
- (setq-local major-mode-backend-function #'js--json-backend-toggle))
+
+ ;; Tree-sitter support.
+ (setq-local treesit-mode-supported t)
+ (setq-local treesit-required-languages '(json))
+ (setq-local treesit-simple-indent-rules js--json-treesit-indent-rules)
+ (setq-local treesit-font-lock-settings js-json--treesit-font-lock-settings))
;; Since we made JSX support available and automatically-enabled in
;; the base `js-mode' (for ease of use), now `js-jsx-mode' simply
(defvar electric-indent-inhibit)
(defvar prettify-symbols-alist)
-(defun python--backend-toggle (backend warn)
- "Toggle backend for `python-mode'.
-BACKEND and WARN are explained in `treesit-mode-function'."
- (cond
- ;; Tree-sitter.
- ((and (eq backend 'treesit) (treesit-ready-p warn 'python))
- (setq-local font-lock-keywords-only t)
- (setq-local treesit-font-lock-feature-list
- '((basic) (moderate) (elaborate)))
- (setq-local treesit-font-lock-settings
- python--treesit-settings)
- (treesit-font-lock-enable)
- (setq-local imenu-create-index-function
- #'python-imenu-treesit-create-index)
- (add-hook 'which-func-functions
- #'python-info-treesit-current-defun nil t))
- ;; Elisp.
- ((eq backend 'elisp)
- (setq-local font-lock-defaults
- `(,python-font-lock-keywords
- nil nil nil nil
- (font-lock-syntactic-face-function
- . python-font-lock-syntactic-face-function)
- (font-lock-extend-after-change-region-function
- . python-font-lock-extend-region)))
- (setq-local imenu-create-index-function
- #'python-imenu-create-index)
- (add-hook 'which-func-functions #'python-info-current-defun nil t))))
-
;;;###autoload
(define-derived-mode python-mode prog-mode "Python"
"Major mode for editing Python files.
(setq-local forward-sexp-function python-forward-sexp-function)
- (python--backend-toggle 'elisp nil)
-
- (setq-local major-mode-backend-function #'python--backend-toggle)
+ (setq-local font-lock-defaults
+ `(,python-font-lock-keywords
+ nil nil nil nil
+ (font-lock-syntactic-face-function
+ . python-font-lock-syntactic-face-function)))
(setq-local syntax-propertize-function
python-syntax-propertize-function)
(add-hook 'post-self-insert-hook
#'python-indent-post-self-insert-function 'append 'local)
+ (setq-local imenu-create-index-function
+ #'python-imenu-create-index)
+
(setq-local add-log-current-defun-function
#'python-info-current-defun)
+ (add-hook 'which-func-functions #'python-info-current-defun nil t)
+
(setq-local skeleton-further-elements
'((abbrev-mode nil)
(< '(backward-delete-char-untabify (min python-indent-offset
(with-no-warnings
;; suppress warnings about eldoc-documentation-function being obsolete
- (if (null eldoc-documentation-function)
- ;; Emacs<25
- (setq-local eldoc-documentation-function #'python-eldoc-function)
- (if (boundp 'eldoc-documentation-functions)
- (add-hook 'eldoc-documentation-functions #'python-eldoc-function nil t)
- (add-function :before-until (local 'eldoc-documentation-function)
- #'python-eldoc-function))))
+ (if (null eldoc-documentation-function)
+ ;; Emacs<25
+ (setq-local eldoc-documentation-function #'python-eldoc-function)
+ (if (boundp 'eldoc-documentation-functions)
+ (add-hook 'eldoc-documentation-functions #'python-eldoc-function nil t)
+ (add-function :before-until (local 'eldoc-documentation-function)
+ #'python-eldoc-function))))
(add-to-list
'hs-special-modes-alist
(when python-indent-guess-indent-offset
(python-indent-guess-indent-offset))
- (add-hook 'flymake-diagnostic-functions #'python-flymake nil t))
+ (add-hook 'flymake-diagnostic-functions #'python-flymake nil t)
+
+ (setq-local treesit-mode-supported t)
+ (setq-local treesit-required-languages '(python))
+ (setq-local treesit-font-lock-feature-list
+ '((basic) (moderate) (elaborate)))
+ (setq-local treesit-font-lock-settings python--treesit-settings)
+ (setq-local treesit-imenu-function
+ #'python-imenu-treesit-create-index))
;;; Completion predicates for M-x
;; Commands that only make sense when editing Python code
(string) @font-lock-string-face
- (template_string) @ts-mode--fontify-template-string
+ (template_string) @js--fontify-template-string
(template_substitution ["${" "}"] @font-lock-builtin-face)
(comment) @font-lock-comment-face)
(jsx_attribute (property_identifier) @font-lock-constant-face)))
"Tree-sitter font-lock settings.")
-(defun ts-mode--fontify-template-string (beg end node)
- "Fontify template string but not substitution inside it.
-BEG, END, NODE refers to the template_string node."
- (ignore end)
- ;; Stolen from `js--fontify-template-string'
- (let ((child (treesit-node-child node 0)))
- (while child
- (if (equal (treesit-node-type child) "template_substitution")
- (put-text-property beg (treesit-node-start child)
- 'face 'font-lock-string-face)
- (put-text-property beg (treesit-node-end child)
- 'face 'font-lock-string-face))
- (setq beg (treesit-node-end child)
- child (treesit-node-next-sibling child)))))
-
-(defvar ts-mode--defun-type-regexp
- (rx (or "class_declaration"
- "method_definition"
- "function_declaration"
- "lexical_declaration"))
- "Regular expression that matches type of defun nodes.
-Used in `ts-mode--beginning-of-defun' and friends.")
-
-(defun ts-mode--beginning-of-defun (&optional arg)
- "Tree-sitter `beginning-of-defun' function.
-ARG is the same as in `beginning-of-defun."
- (let ((arg (or arg 1)))
- (if (> arg 0)
- ;; Go backward.
- (while (and (> arg 0)
- (treesit-search-forward-goto
- ts-mode--defun-type-regexp 'start nil t))
- (setq arg (1- arg)))
- ;; Go forward.
- (while (and (< arg 0)
- (treesit-search-forward-goto
- ts-mode--defun-type-regexp 'start))
- (setq arg (1+ arg))))))
-
-(defun ts-mode--end-of-defun (&optional arg)
- "Tree-sitter `end-of-defun' function.
-ARG is the same as in `end-of-defun."
- (let ((arg (or arg 1)))
- (if (< arg 0)
- ;; Go backward.
- (while (and (< arg 0)
- (treesit-search-forward-goto
- ts-mode--defun-type-regexp 'end nil t))
- (setq arg (1+ arg)))
- ;; Go forward.
- (while (and (> arg 0)
- (treesit-search-forward-goto
- ts-mode--defun-type-regexp 'end))
- (setq arg (1- arg))))))
-
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.ts\\'" . ts-mode))
:group 'typescript
:syntax-table ts-mode--syntax-table
+ ;; Treesit-mode.
+ (setq-local treesit-mode-supported t)
+ (setq-local treesit-required-languages '(tsx))
+ ;; Comments.
+ (setq-local comment-start "// ")
+ (setq-local comment-start-skip "\\(?://+\\|/\\*+\\)\\s *")
+ (setq-local comment-end "")
+ ;; Indent.
+ (setq-local treesit-simple-indent-rules ts-mode--indent-rules)
+ ;; Navigation.
+ (setq-local treesit-defun-type-regexp
+ (rx (or "class_declaration"
+ "method_definition"
+ "function_declaration"
+ "lexical_declaration")))
+ ;; Font-lock.
+ (setq-local treesit-font-lock-settings ts-mode--font-lock-settings)
+ (setq-local treesit-font-lock-feature-list '((minimal) (moderate) (full)))
+
(cond
- ((treesit-ready-p nil 'tsx)
- ;; Comments
- (setq-local comment-start "// ")
- (setq-local comment-start-skip "\\(?://+\\|/\\*+\\)\\s *")
- (setq-local comment-end "")
-
- (setq-local treesit-simple-indent-rules ts-mode--indent-rules)
- (setq-local indent-line-function #'treesit-indent)
-
- (setq-local beginning-of-defun-function #'ts-mode--beginning-of-defun)
- (setq-local end-of-defun-function #'ts-mode--end-of-defun)
-
- (setq font-lock-keywords-only t)
- (setq-local treesit-font-lock-settings ts-mode--font-lock-settings)
- (setq treesit-font-lock-feature-list '((minimal) (moderate) (full)))
- (treesit-font-lock-enable))
+ ((treesit-ready-p '(tsx))
+ (treesit-mode))
(t
- (message "Tree-sitter for TypeScript isn't available, falling back to `js-mode'")
- (js-mode))))
+ (js-mode)
+ (message "Tree-sitter for TypeScript isn't available, falling back to `js-mode'"))))
(provide 'ts-mode)
(require 'cl-seq)
(require 'font-lock)
-;;; Activating tree-sitter
+;;; Custom options
;; Tree-sitter always appear as treesit in symbols.
(defgroup treesit nil
:type 'integer
:version "29.1")
-(defcustom treesit-mode-inhibit-message nil
- "If non-nil, don't print message when tree-sitter can't activate."
- :type 'boolean
- :version "29.1")
-
(declare-function treesit-available-p "treesit.c")
-(defvar-local major-mode-backend-function nil
- "A function that toggles the \"backend\" for a major mode.
-
-The function is passed two argument BACKEND and WARN. BACKEND is
-a symbol representing the backend we want to activate. Currently
-it can be `treesit' or `elisp'.
-
-If WARN is non-nil, display a warning if tree-sitter can't
-activate, if WARN is nil, just print an message and don't display
-warning.")
-
-;;;###autoload
-(define-minor-mode treesit-mode
- "Activate tree-sitter to power major-mode features.
-
-This mode is merely a SUGGESTION of turning on tree-sitter,
-actual activation of tree-sitter functionalities depends on
-whether the major mode supports tree-sitter, availability of
-specific tree-sitter language definition, etc."
- :version "29.1"
- :group 'treesit
- (when major-mode-backend-function
- (funcall major-mode-backend-function
- (if treesit-mode 'treesit 'elisp)
- (eq this-command 'treesit-mode))))
-
-(defvar treesit-remapped-major-mode-alist nil
- "A list like `major-mode-remap-alist'.
-
-When major modes activate tree-sitter by switching to another
-major mode and `global-treesit-mode' is on, they add an
-entry (MODE . NEW-MODE) to `major-mode-remap-alist', so next time
-Emacs uses NEW-MODE directly.
-
-These remaps should be removed when `global-treesit-mode' is
-turned off, so we record each (MODE . NEW-MODE) in this variable.")
-
-;;;###autoload
-(define-globalized-minor-mode global-treesit-mode treesit-mode
- global-treesit-mode--turn-on
- :version "29.1"
- :group 'treesit
- :predicate t
- (when (not global-treesit-mode)
- (dolist (map treesit-remapped-major-mode-alist)
- (setq major-mode-remap-alist
- (remove map major-mode-remap-alist)))))
-
-(defun global-treesit-mode--turn-on ()
- "Function used to determine whether to turn on `treesit-mode'.
-Called in every buffer if `global-treesit-mode' is on."
- (treesit-mode))
-
-(defun treesit-ready-p (warn &rest languages)
- "Check that tree-sitter is ready to be used.
-
-If tree-sitter is not ready and WARN is nil-nil, emit a warning;
-if WARN is nil, print a message. But if
-`treesit-mode-inhibit-message' is non-nil, don't even print the
-message.
-
-LANGUAGES are languages we want check for availability."
- (let (msg)
- ;; Check for each condition and set MSG.
- (catch 'term
- (when (not (treesit-available-p))
- (setq msg "tree-sitter library is not built with Emacs")
- (throw 'term nil))
- (when (> (buffer-size) treesit-max-buffer-size)
- (setq msg "buffer larger than `treesit-max-buffer-size'")
- (throw 'term nil))
- (dolist (lang languages)
- (pcase-let ((`(,available . ,err)
- (treesit-language-available-p lang t)))
- (when (not available)
- (setq msg (format "language definition for %s is unavailable (%s): %s"
- lang (nth 0 err)
- (string-join
- (mapcar (lambda (x) (format "%s" x))
- (cdr err))
- " ")))
- (throw 'term nil)))))
- ;; Decide if all conditions met and whether emit a warning.
- (if (not msg)
- t
- (setq msg (concat "Cannot activate tree-sitter, because " msg))
- (if warn
- (display-warning 'treesit msg)
- (unless treesit-mode-inhibit-message
- (message "%s" msg)))
- nil)))
-
;;; Parser API supplement
(defun treesit-parse-string (string language)
(let ((font-lock-unfontify-region-function #'ignore))
(funcall #'font-lock-default-fontify-region start end loudly)))
-(defun treesit-font-lock-enable ()
- "Enable tree-sitter font-locking for the current buffer."
- (treesit-font-lock-recompute-features)
- (setq-local font-lock-fontify-region-function
- #'treesit-font-lock-fontify-region)
- ;; If we don't set `font-lock-defaults' to some non-nil value,
- ;; font-lock doesn't enable properly (`font-lock-mode-internal'
- ;; doesn't run). See `font-lock-specified-p'.
- (when (null font-lock-defaults)
- (setq font-lock-defaults '(nil)))
- (font-lock-mode 1))
-
;;; Indent
(defvar treesit--indent-verbose nil
(goto-char start))
node))
+;;; Navigation
+
+(defvar-local treesit-defun-type-regexp nil
+ "A regexp that matches the node type of defun nodes.
+For example, \"(function|class)_definition\".
+
+This is used by `treesit-beginning-of-defun' and friends. Bind
+it buffer-locally and `treesit-mode' will use it for navigating
+defun's.")
+
+(defun treesit-beginning-of-defun (&optional arg)
+ "Tree-sitter `beginning-of-defun' function.
+ARG is the same as in `beginning-of-defun."
+ (let ((arg (or arg 1)))
+ (if (> arg 0)
+ ;; Go backward.
+ (while (and (> arg 0)
+ (treesit-search-forward-goto
+ treesit-defun-type-regexp 'start nil t))
+ (setq arg (1- arg)))
+ ;; Go forward.
+ (while (and (< arg 0)
+ (treesit-search-forward-goto
+ treesit-defun-type-regexp 'start))
+ (setq arg (1+ arg))))))
+
+(defun treesit-end-of-defun ()
+ "Tree-sitter `end-of-defun' function."
+ (treesit-search-forward-goto treesit-defun-type-regexp 'end))
+
+;;; Imenu
+
+(defvar-local treesit-imenu-function nil
+ "Tree-sitter version of `imenu-create-index-function'.
+
+Set this variable to a function and `treesit-mode' will bind it
+to `imenu-create-index-function'.")
+
+;;; Activating tree-sitter
+
+(defvar-local treesit-mode-supported nil
+ "Set this variable to t to indicate support for `treesit-mode'.")
+
+(defvar-local treesit-required-languages nil
+ "A list of languages this major mode need for tree-sitter.")
+
+(defun treesit-ready-p (languages &optional report)
+ "Check that tree-sitter is ready to be used.
+
+If tree-sitter is not ready and REPORT non-nil, emit a warning or
+message. Emit a warning if REPORT is `warn', message if REPORT
+is `message'.
+
+LANGUAGES is a list of languages we want check for availability."
+ (let (msg)
+ ;; Check for each condition and set MSG.
+ (catch 'term
+ (when (not treesit-mode-supported)
+ (setq msg "this major mode doesn't support it")
+ (throw 'term nil))
+ (when (not (treesit-available-p))
+ (setq msg "tree-sitter library is not built with Emacs")
+ (throw 'term nil))
+ (when (> (buffer-size) treesit-max-buffer-size)
+ (setq msg "buffer larger than `treesit-max-buffer-size'")
+ (throw 'term nil))
+ (dolist (lang languages)
+ (pcase-let ((`(,available . ,err)
+ (treesit-language-available-p lang t)))
+ (when (not available)
+ (setq msg (format "language definition for %s is unavailable (%s): %s"
+ lang (nth 0 err)
+ (string-join
+ (mapcar (lambda (x) (format "%s" x))
+ (cdr err))
+ " ")))
+ (throw 'term nil)))))
+ ;; Decide if all conditions met and whether emit a warning.
+ (if (not msg)
+ t
+ (setq msg (concat "Cannot activate tree-sitter, because " msg))
+ (pcase report
+ ('warn (display-warning 'treesit msg))
+ ('message (message "%s" msg)))
+ nil)))
+
+(defvar-local treesit--local-variable-backup nil
+ "An alist of (VAR . VALUE) that backs up pre-treesit-mode values.")
+
+(defun treesit--backup-local-variable (variable value &optional restore)
+ "Backup VARIABLE's value and set it to VALUE.
+If RESTORE is non-nil, ignore VALUE and restore the backup (if
+there is any)."
+ (if restore
+ (when-let ((value (alist-get variable
+ treesit--local-variable-backup)))
+ (set variable value))
+ ;; Set.
+ (make-variable-buffer-local variable)
+ (setf (alist-get variable treesit--local-variable-backup)
+ (symbol-value variable))
+ (set variable value)))
+
+;;;###autoload
+(define-minor-mode treesit-mode
+ "Activate tree-sitter to power major-mode features.
+
+This mode is merely a SUGGESTION of turning on tree-sitter,
+actual activation of tree-sitter functionalities depends on
+whether the major mode supports tree-sitter, availability of
+specific tree-sitter language definition, etc."
+ :version "29.1"
+ :group 'treesit
+ (if treesit-mode
+ (when (treesit-ready-p treesit-required-languages 'warn)
+ ;; Font-lock.
+ (setq-local treesit--local-variable-backup nil)
+ ;; NOTE: If anyone other than the major mode added stuff to
+ ;; `font-lock-keywords', they would need to re-add them after
+ ;; `treesit-mode' turns on.
+ (when treesit-font-lock-settings
+ (treesit--backup-local-variable 'font-lock-keywords-only t)
+ (treesit--backup-local-variable 'font-lock-keywords nil)
+ (treesit--backup-local-variable
+ 'font-lock-fontify-region-function
+ #'treesit-font-lock-fontify-region)
+ (treesit-font-lock-recompute-features))
+ ;; Indent.
+ (when treesit-simple-indent-rules
+ (treesit--backup-local-variable
+ 'indent-line-function #'treesit-indent))
+ ;; Navigation.
+ (when treesit-defun-type-regexp
+ (treesit--backup-local-variable
+ 'beginning-of-defun-function #'treesit-beginning-of-defun)
+ (treesit--backup-local-variable
+ 'end-of-defun-function #'treesit-end-of-defun))
+ ;; Imenu.
+ (when treesit-imenu-function
+ (treesit--backup-local-variable
+ 'imenu-create-index-function treesit-imenu-function)))
+ ;; Font-lock.
+ (treesit--backup-local-variable 'font-lock-keywords nil t)
+ (treesit--backup-local-variable 'font-lock-keywords-only nil t)
+ (treesit--backup-local-variable
+ 'font-lock-fontify-region-function nil t)
+ ;; Indent.
+ (treesit--backup-local-variable 'indent-line-function nil t)
+ ;; Navigation.
+ (treesit--backup-local-variable 'beginning-of-defun-function nil t)
+ (treesit--backup-local-variable 'end-of-defun-function nil t)
+ ;; Imenu.
+ (treesit--backup-local-variable 'imenu-create-index-function nil t)
+ ))
+
+(defun global-treesit-mode--turn-on ()
+ "Function used to determine whether to turn on `treesit-mode'.
+Called in every buffer if `global-treesit-mode' is on."
+ ;; Check tree-sitter readiness and don't emit warnings.
+ (when (and treesit-mode-supported
+ (treesit-ready-p treesit-required-languages))
+ (treesit-mode)))
+
+;;;###autoload
+(define-globalized-minor-mode global-treesit-mode treesit-mode
+ global-treesit-mode--turn-on
+ :version "29.1"
+ :group 'treesit
+ :predicate t
+ nil)
+
;;; Debugging
(defvar-local treesit--inspect-name nil