summaryrefslogtreecommitdiff
path: root/.config/emacs/modules/mm-treesit.el
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-10-16 22:04:33 +0200
committerThomas Voss <mail@thomasvoss.com> 2024-10-16 22:04:33 +0200
commit0ee7fa9c382ae30295f0b8d88457f7856c7ff800 (patch)
tree6b5a0cf01fa0bfa4d01b0134b268f5d993055c0b /.config/emacs/modules/mm-treesit.el
parentd452ae1347b3711bc0a7ac80cfa2c37d9d63836e (diff)
emacs: Overhaul configuration completely
Diffstat (limited to '.config/emacs/modules/mm-treesit.el')
-rw-r--r--.config/emacs/modules/mm-treesit.el140
1 files changed, 140 insertions, 0 deletions
diff --git a/.config/emacs/modules/mm-treesit.el b/.config/emacs/modules/mm-treesit.el
new file mode 100644
index 0000000..75e679f
--- /dev/null
+++ b/.config/emacs/modules/mm-treesit.el
@@ -0,0 +1,140 @@
+;;; mm-treesit.el --- Tree-Sitter configuration -*- lexical-binding: t; -*-
+
+(unless (treesit-available-p)
+ (error "Tree-Sitter is not available."))
+
+
+;;; Tree-Sitter Variables
+
+(defvar mm-treesit-language-remap-alist
+ '((cpp . c++)
+ (gomod . go-mod)
+ (javascript . js)
+ (vim . vimscript))
+ "TODO")
+
+(setopt treesit-font-lock-level 4)
+(setopt treesit-language-source-alist
+ '((c "https://github.com/tree-sitter/tree-sitter-c")
+ (cpp "https://github.com/tree-sitter/tree-sitter-cpp")
+ (css "https://github.com/tree-sitter/tree-sitter-css")
+ (go "https://github.com/tree-sitter/tree-sitter-go")
+ (gomod "https://github.com/camdencheek/tree-sitter-go-mod")
+ (gsp "git://git.thomasvoss.com/tree-sitter-gsp.git")
+ (html "https://github.com/tree-sitter/tree-sitter-html")
+ (javascript "https://github.com/tree-sitter/tree-sitter-javascript")
+ (python "https://github.com/tree-sitter/tree-sitter-python")
+ (typescript "https://github.com/tree-sitter/tree-sitter-typescript"
+ "master" "typescript/src")
+ (vim "https://github.com/tree-sitter-grammars/tree-sitter-vim")
+ (vue "https://github.com/ikatyang/tree-sitter-vue")))
+
+
+;;; Install Missing Parsers
+
+(defun mm-treesit-sync-sources ()
+ "Sync Tree-Sitter parsers.
+Reinstall the Tree-Sitter parsers specified by
+ `treesit-language-source-alist'."
+ (interactive)
+ (let ((total (length treesit-language-source-alist))
+ (count 0)
+ (work treesit-language-source-alist)
+ (processors-to-use (max 1 (1- (num-processors)))))
+ (while work
+ (let ((specs (seq-take work processors-to-use)))
+ (dolist (spec specs)
+ (async-start
+ `(lambda ()
+ ,(async-inject-variables "\\`treesit-language-source-alist\\'")
+ (treesit-install-language-grammar ',(car spec)))
+ (lambda (_)
+ (setq count (1+ count))
+ (message "Done syncing Tree-Sitter grammar for `%s' [%d/%d]"
+ (car spec) count total))))
+ (setq work (seq-drop work processors-to-use))))))
+
+(thread-last
+ (mapcar #'car treesit-language-source-alist)
+ (seq-remove #'treesit-language-available-p)
+ (mapc #'treesit-install-language-grammar))
+
+
+;;; Install Additional TS Modes
+
+(use-package gsp-ts-mode
+ :vc (:url "https://git.thomasvoss.com/gsp-ts-mode"
+ :branch "master"
+ :rev :newest
+ :vc-backend Git)
+ :ensure t)
+
+;; NOTE: This package doesn’t autoload its ‘auto-mode-alist’ entries
+(use-package vimscript-ts-mode
+ :ensure t
+ :mode (rx (or (seq (? (or ?. ?_)) (? ?g) "vimrc")
+ ".vim"
+ ".exrc")
+ eos))
+
+;; NOTE: This package doesn’t autoload its ‘auto-mode-alist’ entries
+(use-package vue-ts-mode
+ :vc (:url "https://github.com/8uff3r/vue-ts-mode.git"
+ :branch "main"
+ :rev :newest
+ :vc-backend Git)
+ :ensure t
+ :mode "\\.vue\\'")
+
+
+;;; Prefer Tree-Sitter Modes
+
+;; NOTE: ‘go-ts-mode’ already adds itself to ‘auto-mode-alist’ but it
+;; isn’t autoloaded as of 2024-09-29 so we need to do it ourselves
+;; anyway. Same goes for ‘typescript-ts-mode’.
+(defvar mm-treesit-language-file-name-alist
+ '((go . "\\.go\\'")
+ (go-mod . "/go\\.mod\\'")
+ (typescript . "\\.ts\\'"))
+ "Alist mapping languages to their associated file-names.
+This alist is a set of pairs of the form (LANG . REGEXP) where LANG is
+the symbol corresponding to a major mode with the ‘-ts-mode’ suffix
+removed. REGEXP is a regular expression matching filenames for which
+the associated language’s major-mode should be enabled.
+
+This alist is used to configure `auto-mode-alist'.")
+
+(dolist (spec treesit-language-source-alist)
+ (let* ((lang (car spec))
+ (lang (alist-get lang mm-treesit-language-remap-alist lang))
+ (symbol-name (symbol-name lang))
+ (name-mode (intern (concat symbol-name "-mode")))
+ (name-ts-mode (intern (concat symbol-name "-ts-mode"))))
+ ;; If ‘name-ts-mode’ is already in ‘auto-mode-alist’ then we don’t
+ ;; need to do anything, however if that’s not the case then if
+ ;; ‘name-ts-mode’ and ‘name-mode’ are both bound we do a simple
+ ;; remap. If the above is not true then we lookup the extensions in
+ ;; ‘mm-treesit-language-file-name-alist’.
+ (cond
+ ((not (fboundp name-ts-mode))
+ (warn "`%s' is missing." name-ts-mode))
+ ((rassq name-ts-mode auto-mode-alist)
+ nil)
+ ((fboundp name-mode)
+ (add-to-list 'major-mode-remap-alist (cons name-mode name-ts-mode)))
+ (t ; (and (fboundp name-ts-mode) (not (fboundp name-mode)))
+ (if-let ((file-regexp
+ (alist-get lang mm-treesit-language-file-name-alist)))
+ (add-to-list 'auto-mode-alist (cons file-regexp name-ts-mode))
+ (warn "Unable to determine the extension for `%s'." name-ts-mode))))))
+
+
+;;; Hack For C23
+
+(advice-add #'c-ts-mode--keywords :filter-return
+ (defun mm-c-ts-mode-add-constexpr (keywords)
+ ;; NOTE: We can’t add ‘typeof’ until it’s added to the TS grammar
+ ;; https://github.com/tree-sitter/tree-sitter-c/issues/236
+ (append keywords '("constexpr"))))
+
+(provide 'mm-treesit)