;; -*- lexical-binding: t; -*-
-(defvar -languages `((python-ts-mode
- ((:langs . python)
- (:file-ext . ,(rx ".py"))
- (:interpreter . "python")))
- (rust-ts-mode
- ((:langs . rust)
- (:file-ext . ,(rx ".rs"))))
- (bash-ts-mode
- ((:langs . bash)
- (:file-ext . ,(rx ".sh"))
- (:interpreter . "bash")))
- (c-ts-mode
- ((:langs . c)
- (:file-ext . ,(rx ".c"))))
- (c++-ts-mode
- ((:langs . c++)
- (:file-ext . ,(rx (or ".c++" ".cpp" ".cxx"
- ".h++" ".hpp" ".hxx")))))
- (c-or-c++-ts-mode
- ((:langs . (c c++))
- (:file-ext . ,(rx ".h"))))
- (toml-ts-mode
- ((:langs . toml)
- (:file-ext . ,(rx ".toml"))))))
-
-(defun -ready-quiet-p (language)
- (treesit-ready-p language t))
-
-(cl-defun -load-language? (&key ts-mode
- required-languages
- file-extension
- interpreter?)
- (let ((ready? (if (listp required-languages)
- (seq-every-p '-ready-quiet-p required-languages)
- (-ready-quiet-p required-languages))))
- (when ready?
- (add-to-list 'auto-mode-alist (cons file-extension ts-mode))
- (when interpreter?
- (add-to-list 'interpreter-mode-alist (cons interpreter? ts-mode))))))
-
-(seq-map (lambda (item)
- (-load-language?
- :ts-mode (car item)
- :required-languages (alist-get :langs (cadr item))
- :file-extension (alist-get :file-ext (cadr item))
- :interpreter? (alist-get :interpreter (cadr item))))
- -languages)
+;; This script is a quick workaround for setting up treesitter modes.
+;; Hopefully this won't be needed for long but it works for now!
+;;
+;; This just runs through the list of modes below, checks if the
+;; required treesitter parsers are installed, and if so,
+;; sets up auto-mode-alist and interpreter-mode-alist
+;; to open the respective source files with the treesitter
+;; mode for that language.
+;;
+;; To use, you should just add the modes and other info to the list
+;; below, and then "require" this file in your init.
+;; The messages that get generated by this script may be burried
+;; by other startup messages, so it may not appear to have done
+;; anything!
+;;
+;; To test if it works, visit a file such as "x.py", then run
+;; "M-x describe-mode". There should be some info about
+;; the current major mode that looks like this:
+;;
+;; "The major mode is Python mode defined in python.el:
+;; Major mode for editing Python files, using tree-sitter library."
+
+(defvar -quiet? nil
+ "Suppress messages when setting up treesitter modes.")
+
+(defvar -modes `((python-ts-mode
+ ((:parsers . python)
+ (:file-ext . ,(rx ".py"))
+ (:interpreters . ("python" "python3"))))
+ (rust-ts-mode
+ ((:parsers . rust)
+ (:file-ext . ,(rx ".rs"))))
+ (bash-ts-mode
+ ((:parsers . bash)
+ (:file-ext . ,(rx ".sh"))
+ (:interpreters . ("bash" "sh" "openrc-run"))))
+ (c-ts-mode
+ ((:parsers . c)
+ (:file-ext . ,(rx ".c"))))
+ (c++-ts-mode
+ ((:parsers . cpp)
+ (:file-ext . ,(rx (or ".c++" ".cpp" ".cxx"
+ ".h++" ".hpp" ".hxx")))))
+ (c-or-c++-ts-mode
+ ((:parsers . (c c++))
+ (:file-ext . ,(rx ".h"))))
+ (toml-ts-mode
+ ((:parsers . toml)
+ (:file-ext . ,(rx ".toml")))))
+ "Treesitter modes and some information required to set them up.
+
+Parsers are the treesitter packages that need to be installed to
+use the associated mode. python-ts-mode requires the python treesitter
+parser package to be installed for example.
+
+File extension is for example .py for python scripts. Some
+modes like c++-ts-mode are associated with a few
+extensions, and c-or-c++-mode is associated with .h
+because the extension is ambiguous.
+
+Interpreters are used to associate certain shebangs with the treesitter
+mode. Files that start with '#!/usr/bin/env python' for example will
+be associated with python-ts-mode if 'python' is included in the
+interpreters list.")
+
+(defun -ready-quiet? (parser)
+ (treesit-ready-p parser t))
+
+(cl-defun -setup-mode? (&key ts-mode
+ required-parsers
+ file-extensions
+ interpreters)
+ (when (seq-every-p '-ready-quiet? (ensure-list required-parsers))
+ (add-to-list 'auto-mode-alist (cons file-extensions ts-mode))
+ (when interpreters
+ (seq-each (lambda (interpreter)
+ (add-to-list 'interpreter-mode-alist (cons interpreter ts-mode)))
+ (ensure-list interpreters)))
+ t))
+
+(seq-each (lambda (mode)
+ (when (and (-setup-mode?
+ :ts-mode (car mode)
+ :required-parsers (alist-get :parsers (cadr mode))
+ :file-extensions (alist-get :file-ext (cadr mode))
+ :interpreters (alist-get :interpreters (cadr mode)))
+ (not -quiet?))
+ (message "Setup treesitter mode %s" (car mode))))
+ -modes)
(provide 'init-treesit-setup-available-languages)