summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Wilken2023-10-13 17:23:29 +0200
committerTimo Wilken2023-10-30 17:30:41 +0100
commit1ce4deeb09d62769b9957c53ef28eafd38d3abb0 (patch)
treea6d70449838768ed101f760fa4c5b5a5d3260a48
parentbfd732d421c07c7c5e3633e675632dc17a27fc4e (diff)
Initial tree-sitter support in Emacs
-rw-r--r--tw/home.scm17
-rw-r--r--tw/home/files/emacs-init.el66
-rw-r--r--tw/home/files/emacs-packages/alidist-mode.el11
3 files changed, 62 insertions, 32 deletions
diff --git a/tw/home.scm b/tw/home.scm
index bfa9f5c5..6a394a62 100644
--- a/tw/home.scm
+++ b/tw/home.scm
@@ -29,7 +29,7 @@
llvm mail maths ncdu package-management password-utils pdf pretty-print
pulseaudio pv python python-build python-check python-xyz rsync shells
shellutils sqlite ssh syndication terminals tcl tex textutils tmux tls
- version-control video vim web web-browsers wm xfce xdisorg xorg)
+ tree-sitter version-control video vim web web-browsers wm xfce xdisorg xorg)
(define-public %common-packages
(list
@@ -347,7 +347,6 @@
emacs-flymake-collection
emacs-geiser emacs-geiser-guile
emacs-sly
- emacs-cmake-mode
emacs-gnuplot
emacs-graphviz-dot-mode
emacs-haskell-mode
@@ -357,7 +356,19 @@
emacs-puppet-mode
emacs-rec-mode
emacs-web-mode
- emacs-yaml-mode))
+ emacs-yaml-mode
+
+ ;; Tree sitter libraries, for Emacs' built-in X-ts-modes.
+ tree-sitter-bash
+ tree-sitter-c
+ tree-sitter-cmake
+ tree-sitter-cpp
+ tree-sitter-css
+ tree-sitter-dockerfile
+ tree-sitter-javascript
+ tree-sitter-json
+ tree-sitter-python
+ tree-sitter-ruby))
(define xfce4-screenshooter.conf
(mixed-text-file "xfce4-screenshooter.conf" "\
diff --git a/tw/home/files/emacs-init.el b/tw/home/files/emacs-init.el
index 03255351..de38e7a8 100644
--- a/tw/home/files/emacs-init.el
+++ b/tw/home/files/emacs-init.el
@@ -81,8 +81,8 @@ If CREATE is true and the resulting directory does not exist, create it."
;; Custom modes depending on file names.
(mapc (apply-partially #'add-to-list 'auto-mode-alist)
- `((,(rx (or bos "/") "PKGBUILD" eos) . sh-mode)
- (,(rx ".install" eos) . sh-mode)
+ `((,(rx (or bos "/") "PKGBUILD" eos) . bash-ts-mode)
+ (,(rx ".install" eos) . bash-ts-mode)
(,(rx (or bos "/") "COMMIT_EDITMSG" eos) . diff-mode) ; useful for `git commit -v'
(,(rx bos "/tmp/neomutt-") . mail-mode)
(,(rx ".eml" eos) . mail-mode)
@@ -316,7 +316,7 @@ If CREATE is true and the resulting directory does not exist, create it."
(use-package eglot
;; I have clang (for clangd) and python-lsp-server installed.
;; `:hook' adds `-mode' to the package name, but `eglot-mode' doesn't exist.
- :hook ((python-mode c-mode c++-mode) . eglot-ensure)
+ :hook ((python-mode python-ts-mode c-mode c++-mode c-or-c++-ts-mode) . eglot-ensure)
:commands (eglot)
:custom
(eglot-autoshutdown t "Shut down language servers after deleting their last associated buffer.")
@@ -325,23 +325,33 @@ If CREATE is true and the resulting directory does not exist, create it."
;; TODO: only run `tw/help-is-eldoc' if `eglot-managed-p' is true.
(add-hook 'eglot-managed-mode-hook #'tw/help-is-eldoc))
-;; Non-LSP language modes.
-
+;; Tree-sitter
;; TODO: Try any/all of the following new tree-sitter-based major modes.
;; Enable them using the following, replacing the relevant "old" major mode:
;; (add-to-list 'major-mode-remap-alist '(ruby-mode . ruby-ts-mode))
-;; New command 'c-or-c++-ts-mode'.
-;; New major mode 'python-ts-mode'.
;; New major mode 'css-ts-mode'.
;; New major mode 'json-ts-mode'.
-;; New major mode 'bash-ts-mode'.
;; New major mode 'dockerfile-ts-mode'.
-;; New major mode 'cmake-ts-mode'.
-;; New major mode 'toml-ts-mode'.
-;; New major mode 'yaml-ts-mode'.
;; New major mode 'ruby-ts-mode'.
-(use-package cmake-mode
+(mapc (lambda (dir)
+ (add-to-list 'treesit-extra-load-path (file-name-as-directory (expand-file-name dir))))
+ '("/run/current-system/profile/lib/tree-sitter"
+ "~/.guix-home/profile/lib/tree-sitter"
+ "~/.guix-profile/lib/tree-sitter"))
+
+(use-package treesit
+ :custom
+ (treesit-font-lock-level 4 "Enable Angry Fruit Salad mode."))
+
+(use-package c-ts-mode
+ :init
+ (add-to-list 'major-mode-remap-alist '(c-mode . c-ts-mode))
+ (add-to-list 'major-mode-remap-alist '(c++-mode . c++-ts-mode))
+ (add-to-list 'major-mode-remap-alist '(c-or-c++-mode . c-or-c++-ts-mode)))
+
+;; Non-LSP language modes.
+(use-package cmake-ts-mode
:mode (rx (or (: (or bos "/") "CMakeLists.txt") ".cmake") eos))
(use-package gnuplot
@@ -368,23 +378,29 @@ If CREATE is true and the resulting directory does not exist, create it."
(use-package python
:after (flymake-collection)
- :commands (python-mode)
- :mode (((rx ".py" (? (or ?\i ?\w)) eos) . python-mode)
- ((rx ".aurora" eos) . python-mode))
- ;; :flymake-hook would be better, but it fails with error: (void-variable
- ;; for). Somehow `cl-loop' is getting parsed wrong...
- ;; https://github.com/mohkale/flymake-collection#associating-checkers-with-major-modes
- :init (add-to-list 'flymake-collection-config
- '(python-mode
- flymake-collection-flake8
- flymake-collection-mypy
- (flymake-collection-pycodestyle :disabled t)
- flymake-collection-pylint)))
+ :commands (python-mode python-ts-mode)
+ :mode (((rx ".py" (? (or ?\i ?\w)) eos) . python-ts-mode)
+ ((rx ".aurora" eos) . python-ts-mode))
+ :flymake-hook
+ (python-ts-mode
+ flymake-collection-flake8
+ flymake-collection-mypy
+ (flymake-collection-pycodestyle :disabled t)
+ flymake-collection-pylint)
+ (python-mode
+ flymake-collection-flake8
+ flymake-collection-mypy
+ (flymake-collection-pycodestyle :disabled t)
+ flymake-collection-pylint))
(use-package rec-mode
:mode (rx ".rec" eos))
(use-package sh-script ; built-in
+ ;; Use `bash-ts-mode' instead of `sh-mode' if possible.
+ ;; `bash-ts-mode' falls back to `sh-mode' if necessary.
+ ;; Manually configuring :mode etc would be annoying, since there are a lot of entries.
+ :config (add-to-list 'major-mode-remap-alist '(sh-mode . bash-ts-mode))
:custom (sh-basic-offset 2 "Use 2 spaces for `sh-mode' indents."))
(use-package tcl
@@ -838,7 +854,7 @@ For use in `org-latex-classes'."
;; Lisp features
(use-package aggressive-indent
- :hook (scheme-mode emacs-lisp-mode common-lisp-mode sh-mode))
+ :hook (scheme-mode emacs-lisp-mode common-lisp-mode sh-mode bash-ts-mode))
(use-package inf-lisp
:custom
diff --git a/tw/home/files/emacs-packages/alidist-mode.el b/tw/home/files/emacs-packages/alidist-mode.el
index 5fb7af7d..94f1b9e9 100644
--- a/tw/home/files/emacs-packages/alidist-mode.el
+++ b/tw/home/files/emacs-packages/alidist-mode.el
@@ -127,6 +127,9 @@ It is stored in `alidist-mode--mmm-refresh-timer'."
(add-hook 'flymake-diagnostic-functions #'alidist-flymake nil t)
(flymake-mode))
+(define-derived-mode alidist-script-ts-mode bash-ts-mode "Script"
+ "A mode for scripts in alidist recipes, using tree-sitter.")
+
(define-derived-mode alidist-script-mode sh-mode "Script"
"A mode for scripts in alidist recipes with some default settings."
(sh-set-shell "bash"))
@@ -134,12 +137,12 @@ It is stored in `alidist-mode--mmm-refresh-timer'."
(mmm-add-group
'alidist-recipe
`((alidist-main-script
- :submode alidist-script-mode
+ :submode alidist-script-ts-mode
:face mmm-default-submode-face
:front ,(rx line-start "---\n")
:back ,(rx buffer-end))
(alidist-option-script
- :submode alidist-script-mode
+ :submode alidist-script-ts-mode
:face mmm-default-submode-face
;; Any *_recipe key with a multiline string value is probably a script.
:front ,(rx line-start (* whitespace)
@@ -153,9 +156,9 @@ It is stored in `alidist-mode--mmm-refresh-timer'."
(seq (* whitespace) (+ (any alnum ?\_)) ":"
(or line-end whitespace)))))))
-;; Make `mmm-mode' remember `sh-mode' indentation variables.
+;; Make `mmm-mode' remember `sh-mode'/`bash-ts-mode' indentation variables.
(cl-dolist (var sh-var-list)
- (cl-pushnew `(,var nil (sh-mode))
+ (cl-pushnew `(,var region (sh-mode bash-ts-mode))
mmm-save-local-variables :test 'equal))
(mmm-add-mode-ext-class 'alidist-mode nil 'alidist-recipe)