78 lines
3.5 KiB
EmacsLisp
78 lines
3.5 KiB
EmacsLisp
|
;;; init-treesitter.el --- Enable Treesitter-based major modes -*- lexical-binding: t -*-
|
|||
|
;;; Commentary:
|
|||
|
;;; Code:
|
|||
|
|
|||
|
;; You can download per-architecture pre-compiled release from
|
|||
|
;; https://github.com/emacs-tree-sitter/tree-sitter-langs Rename
|
|||
|
;; contained grammars to add prefix "libtree-sitter-", place in
|
|||
|
;; ~/.emacs.d/tree-sitter.
|
|||
|
;;
|
|||
|
;; Nix users can pre-install all grammars alongside their Emacs, see
|
|||
|
;; https://github.com/nix-community/emacs-overlay/issues/341
|
|||
|
;;
|
|||
|
;; Note that grammar files from different sources can be differently
|
|||
|
;; named and configured, so there could be different results. Some
|
|||
|
;; common remappings are included below.
|
|||
|
|
|||
|
|
|||
|
;;; Enable built-in and pre-installed TS modes if the grammars are available
|
|||
|
|
|||
|
(defun sanityinc/auto-configure-treesitter ()
|
|||
|
"Find and configure installed grammars, remap to matching -ts-modes if present.
|
|||
|
Return a list of languages seen along the way."
|
|||
|
(let ((grammar-name-to-emacs-lang '(("c-sharp" . "csharp")
|
|||
|
("cpp" . "c++")
|
|||
|
("gomod" . "go-mod")
|
|||
|
("javascript" . "js")))
|
|||
|
seen-grammars)
|
|||
|
(dolist (dir (cons (expand-file-name "tree-sitter" user-emacs-directory)
|
|||
|
treesit-extra-load-path))
|
|||
|
(when (file-directory-p dir)
|
|||
|
(dolist (file (directory-files dir))
|
|||
|
(let ((fname (file-name-sans-extension (file-name-nondirectory file))))
|
|||
|
(when (string-match "libtree-sitter-\\(.*\\)" fname)
|
|||
|
(let* ((file-lang (match-string 1 fname))
|
|||
|
(emacs-lang (or (cdr (assoc-string file-lang grammar-name-to-emacs-lang)) file-lang)))
|
|||
|
;; Override library if its filename doesn't match the Emacs name
|
|||
|
(unless (or (memq (intern emacs-lang) seen-grammars)
|
|||
|
(string-equal file-lang emacs-lang))
|
|||
|
(let ((libname (concat "tree_sitter_" (replace-regexp-in-string "-" "_" file-lang))))
|
|||
|
(add-to-list 'treesit-load-name-override-list
|
|||
|
(list (intern emacs-lang) fname libname))))
|
|||
|
;; If there's a corresponding -ts mode, remap the standard mode to it
|
|||
|
(let ((ts-mode-name (intern (concat emacs-lang "-ts-mode")))
|
|||
|
(regular-mode-name (intern (concat emacs-lang "-mode"))))
|
|||
|
(when (fboundp ts-mode-name)
|
|||
|
(message "init-treesitter: using %s in place of %s" ts-mode-name regular-mode-name)
|
|||
|
(add-to-list 'major-mode-remap-alist
|
|||
|
(cons regular-mode-name ts-mode-name))))
|
|||
|
;; Remember we saw this language so we don't squash its config when we
|
|||
|
;; find another lib later in the treesit load path
|
|||
|
(push (intern emacs-lang) seen-grammars)))))))
|
|||
|
seen-grammars))
|
|||
|
|
|||
|
(sanityinc/auto-configure-treesitter)
|
|||
|
|
|||
|
|
|||
|
;;; Support remapping of additional libraries
|
|||
|
|
|||
|
(defun sanityinc/remap-ts-mode (non-ts-mode ts-mode grammar)
|
|||
|
"Explicitly remap NON-TS-MODE to TS-MODE if GRAMMAR is available."
|
|||
|
(when (and (fboundp 'treesit-ready-p)
|
|||
|
(treesit-ready-p grammar t)
|
|||
|
(fboundp ts-mode))
|
|||
|
(add-to-list 'major-mode-remap-alist (cons non-ts-mode ts-mode))))
|
|||
|
|
|||
|
;; When there's js-ts-mode, we also prefer it to js2-mode
|
|||
|
(sanityinc/remap-ts-mode 'js2-mode 'js-ts-mode 'javascript)
|
|||
|
(sanityinc/remap-ts-mode 'clojurescript-mode 'clojurescript-ts-mode 'clojure)
|
|||
|
|
|||
|
|
|||
|
;; Default
|
|||
|
(setq treesit-font-lock-level 4)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
(provide 'init-treesitter)
|
|||
|
;;; init-treesitter.el ends here
|