Install new toggle scheme for tree-sitter
Basically we now have treesit-mode and global-treesit-mode. Major modes set major-mode-backend-function which treesit-mode calls to activate/deactivate tree-sitter. js.el needs a bit explanation: I'm so sorry for messing up the history, but basically now js-mode and js-json-mode should be exactly the same as before any tree-sitter change was introduced, sans some initialization code that are moved to js(-json)--backend-toggle. js-mode and js-json-mode now just sets major-mode-backend-function and initialize with js(-json)--backend-toggle. * lisp/treesit.el (treesit-mode-inhibit-message): New option. (treesit-can-enable-p): Remove function. (major-mode-backend-function) (treesit-remapped-major-mode-alist): New variables. (treesit-mode) (global-treesit-mode): New minor modes. (global-treesit-mode--turn-on) (treesit-ready-p): New functions. * lisp/progmodes/python.el: Remove option. (python--backend-toggle): New function. (python-mode): Remove the if-form, all the initialization code are moved to python--backend-toggle, python-mode now just sets major-mode-backend-function and initialize with python--backend-toggle. * lisp/progmodes/js.el (js--treesit-can-enable-p) (js--json-treesit-can-enable-p) (js--treesit-enable) (js--json-treesit-enable): Remove functions. (js--backend-toggle) (js-json--backend-toggle): New function. * lisp/progmodes/ts-mode.el (ts-mode): Use treesit-ready-p.
This commit is contained in:
parent
851a8f65e9
commit
17b65f5292
4 changed files with 238 additions and 177 deletions
|
@ -3639,28 +3639,39 @@ ARG is the same as in `end-of-defun."
|
|||
js--treesit-defun-type-regexp 'end))
|
||||
(setq arg (1- arg))))))
|
||||
|
||||
(defun js--treesit-can-enable-p ()
|
||||
(if (and js-use-tree-sitter
|
||||
(treesit-can-enable-p)
|
||||
(treesit-language-available-p 'javascript))
|
||||
t
|
||||
(message "Cannot enable Tree Sitter for JavaScript.")
|
||||
nil))
|
||||
(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)
|
||||
|
||||
(defun js--treesit-enable ()
|
||||
(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)
|
||||
|
||||
(setq-local beginning-of-defun-function #'js--treesit-beginning-of-defun)
|
||||
(setq-local end-of-defun-function #'js--treesit-end-of-defun)
|
||||
(setq-local font-lock-keywords-only t)
|
||||
(setq-local treesit-font-lock-settings js--treesit-settings)
|
||||
(setq-local treesit-font-lock-feature-list '((basic)))
|
||||
|
||||
(setq-local font-lock-keywords-only t)
|
||||
(setq-local treesit-font-lock-settings js--treesit-settings)
|
||||
(setq-local treesit-font-lock-feature-list '((basic)))
|
||||
(add-hook 'which-func-functions #'js-treesit-current-defun nil t)
|
||||
|
||||
(add-hook 'which-func-functions #'js-treesit-current-defun nil t)
|
||||
(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)
|
||||
|
||||
(treesit-font-lock-enable))
|
||||
(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
|
||||
|
||||
|
@ -3668,98 +3679,79 @@ ARG is the same as in `end-of-defun."
|
|||
(define-derived-mode js-mode prog-mode "JavaScript"
|
||||
"Major mode for editing JavaScript."
|
||||
:group 'js
|
||||
;; Ensure all CC Mode "lang variables" are set to valid values.
|
||||
(c-init-language-vars js-mode)
|
||||
(setq-local open-paren-in-column-0-is-defun-start nil)
|
||||
(setq-local syntax-propertize-function #'js-syntax-propertize)
|
||||
(add-hook 'syntax-propertize-extend-region-functions
|
||||
#'syntax-propertize-multiline 'append 'local)
|
||||
(add-hook 'syntax-propertize-extend-region-functions
|
||||
#'js--syntax-propertize-extend-region 'append 'local)
|
||||
(setq-local prettify-symbols-alist js--prettify-symbols-alist)
|
||||
|
||||
(setq-local parse-sexp-ignore-comments t)
|
||||
(setq-local which-func-imenu-joiner-function #'js--which-func-joiner)
|
||||
|
||||
;; Comments
|
||||
(setq-local comment-start "// ")
|
||||
(setq-local comment-start-skip "\\(?://+\\|/\\*+\\)\\s *")
|
||||
(setq-local comment-end "")
|
||||
|
||||
(if (js--treesit-can-enable-p)
|
||||
(js--treesit-enable)
|
||||
;; 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)
|
||||
(add-hook 'syntax-propertize-extend-region-functions
|
||||
#'js--syntax-propertize-extend-region 'append 'local)
|
||||
(setq-local prettify-symbols-alist js--prettify-symbols-alist)
|
||||
;; Parse cache
|
||||
(add-hook 'before-change-functions #'js--flush-caches t t)
|
||||
|
||||
(setq-local parse-sexp-ignore-comments t)
|
||||
(setq-local which-func-imenu-joiner-function #'js--which-func-joiner)
|
||||
;; Frameworks
|
||||
(js--update-quick-match-re)
|
||||
|
||||
(setq-local fill-paragraph-function #'js-fill-paragraph)
|
||||
(setq-local normal-auto-fill-function #'js-do-auto-fill)
|
||||
;; Syntax extensions
|
||||
(unless (js-jsx--detect-and-enable)
|
||||
(add-hook 'after-change-functions #'js-jsx--detect-after-change nil t))
|
||||
(js-use-syntactic-mode-name)
|
||||
|
||||
;; Parse cache
|
||||
(add-hook 'before-change-functions #'js--flush-caches t t)
|
||||
;; 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 comment-line-break-function #'c-indent-new-comment-line)
|
||||
(setq-local comment-multi-line t)
|
||||
(setq-local electric-indent-chars
|
||||
(append "{}():;," electric-indent-chars)) ;FIXME: js2-mode adds "[]*".
|
||||
(setq-local electric-layout-rules
|
||||
'((?\; . after) (?\{ . after) (?\} . before)))
|
||||
|
||||
;; Frameworks
|
||||
(js--update-quick-match-re)
|
||||
(setq-local fill-paragraph-function #'js-fill-paragraph)
|
||||
(setq-local normal-auto-fill-function #'js-do-auto-fill)
|
||||
|
||||
;; Syntax extensions
|
||||
(unless (js-jsx--detect-and-enable)
|
||||
(add-hook 'after-change-functions #'js-jsx--detect-after-change nil t))
|
||||
(js-use-syntactic-mode-name)
|
||||
(let ((c-buffer-is-cc-mode t))
|
||||
;; FIXME: These are normally set by `c-basic-common-init'. Should
|
||||
;; we call it instead? (Bug#6071)
|
||||
(make-local-variable 'paragraph-start)
|
||||
(make-local-variable 'paragraph-separate)
|
||||
(make-local-variable 'paragraph-ignore-fill-prefix)
|
||||
(make-local-variable 'adaptive-fill-mode)
|
||||
(make-local-variable 'adaptive-fill-regexp)
|
||||
;; While the full CC Mode style system is not yet in use, set the
|
||||
;; pertinent style variables manually.
|
||||
(c-initialize-builtin-style)
|
||||
(let ((style (cc-choose-style-for-mode 'js-mode c-default-style)))
|
||||
(c-set-style style))
|
||||
(setq c-block-comment-prefix "* "
|
||||
c-comment-prefix-regexp "//+\\|\\**")
|
||||
(c-setup-paragraph-variables))
|
||||
|
||||
;; Imenu
|
||||
(setq imenu-case-fold-search nil)
|
||||
(setq imenu-create-index-function #'js--imenu-create-index)
|
||||
;; Important to fontify the whole buffer syntactically! If we don't,
|
||||
;; then we might have regular expression literals that aren't marked
|
||||
;; as strings, which will screw up parse-partial-sexp, scan-lists,
|
||||
;; etc. and produce maddening "unbalanced parenthesis" errors.
|
||||
;; When we attempt to find the error and scroll to the portion of
|
||||
;; the buffer containing the problem, JIT-lock will apply the
|
||||
;; correct syntax to the regular expression literal and the problem
|
||||
;; 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))
|
||||
|
||||
;; 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 comment-line-break-function #'c-indent-new-comment-line)
|
||||
(setq-local comment-multi-line t)
|
||||
(setq-local electric-indent-chars
|
||||
(append "{}():;," electric-indent-chars)) ;FIXME: js2-mode adds "[]*".
|
||||
(setq-local electric-layout-rules
|
||||
'((?\; . after) (?\{ . after) (?\} . before)))
|
||||
|
||||
(let ((c-buffer-is-cc-mode t))
|
||||
;; FIXME: These are normally set by `c-basic-common-init'. Should
|
||||
;; we call it instead? (Bug#6071)
|
||||
(make-local-variable 'paragraph-start)
|
||||
(make-local-variable 'paragraph-separate)
|
||||
(make-local-variable 'paragraph-ignore-fill-prefix)
|
||||
(make-local-variable 'adaptive-fill-mode)
|
||||
(make-local-variable 'adaptive-fill-regexp)
|
||||
;; While the full CC Mode style system is not yet in use, set the
|
||||
;; pertinent style variables manually.
|
||||
(c-initialize-builtin-style)
|
||||
(let ((style (cc-choose-style-for-mode 'js-mode c-default-style)))
|
||||
(c-set-style style))
|
||||
(setq c-block-comment-prefix "* "
|
||||
c-comment-prefix-regexp "//+\\|\\**")
|
||||
(c-setup-paragraph-variables))
|
||||
|
||||
;; Important to fontify the whole buffer syntactically! If we don't,
|
||||
;; then we might have regular expression literals that aren't marked
|
||||
;; as strings, which will screw up parse-partial-sexp, scan-lists,
|
||||
;; etc. and produce maddening "unbalanced parenthesis" errors.
|
||||
;; When we attempt to find the error and scroll to the portion of
|
||||
;; the buffer containing the problem, JIT-lock will apply the
|
||||
;; correct syntax to the regular expression literal and the problem
|
||||
;; 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))
|
||||
))
|
||||
|
||||
(defcustom js-json-use-tree-sitter nil
|
||||
"If non-nil, `js-json-mode' tries to use tree-sitter.
|
||||
Currently `js-json-mode' uses tree-sitter for font-locking and
|
||||
indentation."
|
||||
:version "29.1"
|
||||
:type 'boolean
|
||||
:safe 'booleanp)
|
||||
(js--backend-toggle 'elisp nil)
|
||||
(setq-local major-mode-backend-function #'js--backend-toggle))
|
||||
|
||||
(defvar js--json-treesit-settings
|
||||
(treesit-font-lock-rules
|
||||
|
@ -3791,37 +3783,29 @@ indentation."
|
|||
((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)
|
||||
|
||||
(defun js--json-treesit-can-enable-p ()
|
||||
(if (and js-json-use-tree-sitter
|
||||
(treesit-can-enable-p)
|
||||
(treesit-language-available-p 'json))
|
||||
t
|
||||
(error "Cannot enable Tree Sitter for JSON.")
|
||||
nil))
|
||||
|
||||
|
||||
(defun js--json-treesit-enable ()
|
||||
(setq-local treesit-simple-indent-rules js--json-treesit-indent-rules)
|
||||
(setq-local indent-line-function #'treesit-indent)
|
||||
|
||||
(setq-local beginning-of-defun-function #'ignore)
|
||||
(setq-local end-of-defun-function #'ignore)
|
||||
|
||||
(setq-local font-lock-defaults '(nil t))
|
||||
(setq-local treesit-font-lock-settings js--json-treesit-settings)
|
||||
|
||||
(treesit-font-lock-enable))
|
||||
|
||||
(setq-local font-lock-keywords-only t)
|
||||
(setq-local treesit-font-lock-settings js--json-treesit-settings)
|
||||
(treesit-font-lock-enable))
|
||||
;; Elisp.
|
||||
((eq backend 'elisp)
|
||||
(js--backend-toggle 'elisp nil))))
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode js-json-mode js-mode "JSON"
|
||||
(if (js--json-treesit-can-enable-p)
|
||||
(js--json-treesit-enable)
|
||||
(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 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))
|
||||
|
||||
;; Since we made JSX support available and automatically-enabled in
|
||||
;; the base `js-mode' (for ease of use), now `js-jsx-mode' simply
|
||||
|
@ -3848,11 +3832,9 @@ could set `js-jsx-syntax' to t in your init file, or in a
|
|||
`js-jsx-enable' in `js-mode-hook'. You may be better served by
|
||||
one of the aforementioned options instead of using this mode."
|
||||
:group 'js
|
||||
(if (js--treesit-can-enable-p)
|
||||
(js--treesit-enable)
|
||||
(js-jsx-enable)
|
||||
(setq-local comment-region-function #'js-jsx--comment-region)
|
||||
(js-use-syntactic-mode-name)))
|
||||
(js-jsx-enable)
|
||||
(setq-local comment-region-function #'js-jsx--comment-region)
|
||||
(js-use-syntactic-mode-name))
|
||||
|
||||
(defun js-jsx--comment-region (beg end &optional arg)
|
||||
(if (or (js-jsx--context)
|
||||
|
|
|
@ -286,13 +286,6 @@
|
|||
:version "24.3"
|
||||
:link '(emacs-commentary-link "python"))
|
||||
|
||||
(defcustom python-use-tree-sitter nil
|
||||
"If non-nil, `python-mode' tries to use tree-sitter.
|
||||
Currently `python-mode' uses tree-sitter for font-locking, imenu,
|
||||
and movement functions."
|
||||
:type 'boolean
|
||||
:version "29.1")
|
||||
|
||||
(defcustom python-interpreter "python"
|
||||
"Python interpreter for noninteractive use.
|
||||
To customize the Python shell, modify `python-shell-interpreter'
|
||||
|
@ -6382,6 +6375,32 @@ Add import for undefined name `%s' (empty to skip): "
|
|||
(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'."
|
||||
(if (and (eq backend 'treesit) (treesit-ready-p warn 'python))
|
||||
(progn
|
||||
(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))
|
||||
(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.
|
||||
|
@ -6398,22 +6417,9 @@ Add import for undefined name `%s' (empty to skip): "
|
|||
|
||||
(setq-local forward-sexp-function python-forward-sexp-function)
|
||||
|
||||
(if (and python-use-tree-sitter
|
||||
(treesit-can-enable-p))
|
||||
(progn
|
||||
(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 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))))
|
||||
(python--backend-toggle 'elisp nil)
|
||||
|
||||
(setq-local major-mode-backend-function #'python--backend-toggle)
|
||||
|
||||
(setq-local syntax-propertize-function
|
||||
python-syntax-propertize-function)
|
||||
|
@ -6442,22 +6448,9 @@ Add import for undefined name `%s' (empty to skip): "
|
|||
(add-hook 'post-self-insert-hook
|
||||
#'python-indent-post-self-insert-function 'append 'local)
|
||||
|
||||
(if (and python-use-tree-sitter
|
||||
(treesit-can-enable-p))
|
||||
(setq-local imenu-create-index-function
|
||||
#'python-imenu-treesit-create-index)
|
||||
(setq-local imenu-create-index-function
|
||||
#'python-imenu-create-index))
|
||||
|
||||
(setq-local add-log-current-defun-function
|
||||
#'python-info-current-defun)
|
||||
|
||||
(if (and python-use-tree-sitter
|
||||
(treesit-can-enable-p))
|
||||
(add-hook 'which-func-functions
|
||||
#'python-info-treesit-current-defun nil t)
|
||||
(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
|
||||
|
|
|
@ -338,8 +338,7 @@ ARG is the same as in `end-of-defun."
|
|||
:syntax-table ts-mode--syntax-table
|
||||
|
||||
(cond
|
||||
((and (treesit-can-enable-p)
|
||||
(treesit-language-available-p 'tsx))
|
||||
((treesit-ready-p nil 'tsx)
|
||||
;; Comments
|
||||
(setq-local comment-start "// ")
|
||||
(setq-local comment-start-skip "\\(?://+\\|/\\*+\\)\\s *")
|
||||
|
@ -351,15 +350,13 @@ ARG is the same as in `end-of-defun."
|
|||
(setq-local beginning-of-defun-function #'ts-mode--beginning-of-defun)
|
||||
(setq-local end-of-defun-function #'ts-mode--end-of-defun)
|
||||
|
||||
(unless font-lock-defaults
|
||||
(setq font-lock-defaults '(nil t)))
|
||||
|
||||
(setq font-lock-keywords-only t)
|
||||
(setq-local treesit-font-lock-settings ts-mode--settings)
|
||||
|
||||
(setq treesit-font-lock-feature-list '((basic)))
|
||||
(treesit-font-lock-enable))
|
||||
(t
|
||||
(message "Tree sitter for TypeScript isn't available, defaulting to js-mode")
|
||||
(message "Tree-sitter for TypeScript isn't available, falling back to `js-mode'")
|
||||
(js-mode))))
|
||||
|
||||
(provide 'ts-mode)
|
||||
|
|
101
lisp/treesit.el
101
lisp/treesit.el
|
@ -45,14 +45,103 @@
|
|||
: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")
|
||||
|
||||
(defun treesit-can-enable-p ()
|
||||
"Return non-nil if current buffer can activate tree-sitter.
|
||||
Currently this function checks whether tree-sitter is available
|
||||
and the buffer size."
|
||||
(and (treesit-available-p)
|
||||
(< (buffer-size) treesit-max-buffer-size)))
|
||||
(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 'languages
|
||||
(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
|
||||
:group 'languages
|
||||
: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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue