branch: elpa/typst-ts-mode
commit 208aa360d89a7016554913877fbc18e326dc5878
Author: Meow King <[email protected]>
Commit: Meow King <[email protected]>
feat: almost done, have some bugs
can dynamic loading embedding languages and embedding python works fine, but
rust and some other languages like `json` will cause the whole file
rendering
weird. Use `(typst-ts-els-merge-lang 'rust)` to test.
---
typst-ts-embedding-lang-settings.el | 173 +++++++++++-------------------------
typst-ts-mode.el | 30 ++++---
2 files changed, 70 insertions(+), 133 deletions(-)
diff --git a/typst-ts-embedding-lang-settings.el
b/typst-ts-embedding-lang-settings.el
index cde20a4e81..3c6cbf4288 100644
--- a/typst-ts-embedding-lang-settings.el
+++ b/typst-ts-embedding-lang-settings.el
@@ -24,6 +24,13 @@
;;; Code:
(require 'treesit)
+(defcustom typst-ts-highlight-raw-block-langs-not-in-settings nil
+ "Whether to highlight raw block of language that is not in settings.
+The cost for setting up these languages is usually higher than those
+languages in settings."
+ :type 'boolean
+ :group 'typst-ts)
+
(defvar typst-ts-embedding-lang-settings
'((python . (:feature
python
@@ -80,84 +87,19 @@
(let ((settings (alist-get lang typst-ts-embedding-lang-settings)))
(if settings
(typst-ts-els-merge-settings settings)
- (signal 'lang-no-in-settings '(lang)))))
-
-(defun typst-ts-els--try-get-variable--try-name (prefixes postfixes)
- (let (variable)
- (catch 'exit
- (cl-loop for prefix in prefixes
- for postfix in postfixes
- do
- (ignore-errors
- (setq variable (intern (concat prefix postfix)))
- (throw 'exit (eval variable)))))))
-
-(defun typst-ts-els--try-get-fls--try-name (_lang prefixes)
- (typst-ts-els--try-get-variable--try-name
- prefixes
- '("--font-lock-settings" "-font-lock-settings")))
-
-(defun typst-ts-els--try-get-ir--try-name (_lang prefixes)
- (typst-ts-els--try-get-variable--try-name
- prefixes
- '("--indent-rules" "-indent-rules")))
-
-(defvar typst-ts-els--try-get-feature-name-list
- '("-ts-mode" "-mode" "")
- "Used by `typset-ts-els--try-require-feature'.")
-
-(defvar typst-ts-els--try-variable-prefix-list
- '("-ts-mode" "-ts" "")
- "Used by `typset-ts-els--try-require-feature'.")
-
-(defvar typst-ts-els--try-get-fls--func-list
- '(typst-ts-els--try-get-fls--try-name)
- "TODO documentation.")
-
-(defvar typst-ts-els--try-get-ir--func-list
- '(typst-ts-els--try-get-ir--try-name)
- "TODO documentation.")
-
-(defun typst-ts-els--try-require-feature (lang)
- "Try to require feature for LANG.
-If success, then return the feature symbol, else nil."
- (let (feature)
- (catch 'exit
- (dolist (elem typst-ts-els--try-get-feature-name-list)
- (setq feature
- (intern (concat (symbol-name lang) elem)))
- (ignore-errors
- (require feature)
- (throw 'exit feature))))))
-
-(defun typst-ts-els--try-get-variable-value (lang prefixes func-list)
- "Try to get value of a variable specified for LANG.
-The variable is like font lock settings or indentation rules. It is specified
-by FUNC-LIST.
-Return nil if cannot get.
-PREFIXES: a list of variable name prefix.
-FUNC-LIST: functions to be called to get the variable value."
- (let (value)
- (catch 'exit
- (dolist (func func-list)
- (ignore-errors
- (setq value (funcall func lang prefixes))
- (when value
- (throw 'exit value)))))))
-
-(defun typst-ts-els--try-get-font-lock-settings (lang prefixes)
- (typst-ts-els--try-get-variable-value
- lang prefixes typst-ts-els--try-get-fls--func-list))
-
-(defun typst-ts-els--try-get-indentation-rules (lang prefixes)
- (typst-ts-els--try-get-variable-value
- lang prefixes typst-ts-els--try-get-ir--func-list))
-
-;; NOTE this operation is high cost
-(defun typst-ts-els--try-get-ts-feature-list (mode)
+ (error "Language %s not in settings" lang))))
+
+(defun typst-ts-els--try-get-ts-settings (mode)
(with-temp-buffer
+ (setq-local delay-mode-hooks t) ; don't run hooks associated with MODE
(funcall mode)
- treesit-font-lock-feature-list))
+ (list
+ :treesit-font-lock-settings
+ treesit-font-lock-settings
+ :treesit-simple-indent-rules
+ treesit-simple-indent-rules
+ :treesit-font-lock-feature-list
+ treesit-font-lock-feature-list)))
(defvar-local typst-ts-els--include-languages
'(typst)
@@ -166,55 +108,45 @@ FUNC-LIST: functions to be called to get the variable
value."
(defun typst-ts-els-include-dynamically (_ranges _parser)
"Include language setting dynamically.
Use this function as one notifier of `treesit-parser-notifiers'."
- (let ((parsers (treesit-parser-list))
- lang
- feature prefixes font-lock-settings indentation-rules ts-feature-list)
- (unless (eq (length parsers) (length typst-ts-els--include-languages))
- (dolist (parser parsers)
- (setq lang (treesit-parser-language parser))
+ (let ((parser-langs (mapcar #'treesit-parser-language (treesit-parser-list)))
+ lang-ts-mode settings)
+ (unless (eq (length parser-langs) (length typst-ts-els--include-languages))
+ (dolist (lang parser-langs)
(unless (member lang typst-ts-els--include-languages)
(unwind-protect
(condition-case _err
;; first try loading settings from configuration
- (typst-ts-els-merge-lang lang)
+ (progn
+ (typst-ts-els-merge-lang lang)
+ (message "Load %s language settings from configuration."
lang))
(error
- ;; if not found or encountering error during loading,
- ;; then guess variables to load
- (catch 'exit
- (ignore-errors
- ;; require feature
- (setq feature (typst-ts-els--try-require-feature lang))
- (unless feature
- (throw 'exit "no feature found"))
-
- (setq prefixes
- (cl-loop for postfix in
typst-ts-els--try-variable-prefix-list
- collect (concat (symbol-name lang)
postfix)))
-
- ;; merge font lock settings
- (setq font-lock-settings
- (typst-ts-els--try-get-font-lock-settings lang
prefixes))
- (setq treesit-font-lock-settings
- (append treesit-font-lock-settings
- font-lock-settings))
-
- ;; merge indent rules
- (setq indentation-rules
- (typst-ts-els--try-get-indentation-rules lang
prefixes))
- (setq treesit-simple-indent-rules
- (append treesit-simple-indent-rules
- indentation-rules))
-
- ;; merge ts feature lists
- (setq ts-feature-list
- (typst-ts-els--try-get-ts-feature-list
- (intern (concat (symbol-name lang) postfix))))
- (setq treesit-font-lock-feature-list
- (typst-ts-els--merge-features
- treesit-font-lock-feature-list
- ts-feature-list))
- ))))
- (add-to-list typst-ts-els--include-languages lang))
+ ;; if language not in setting or encounter error during
loading,
+ ;; then try your luck to load it
+ (condition-case err
+ (progn
+ (setq lang-ts-mode
+ (intern (concat (symbol-name lang) "-ts-mode")))
+ (setq settings
+ (typst-ts-els--try-get-ts-settings lang-ts-mode))
+
+ (setq treesit-font-lock-settings
+ (append treesit-font-lock-settings
+ (plist-get settings
:treesit-font-lock-settings)))
+
+ (setq treesit-simple-indent-rules
+ (append treesit-simple-indent-rules
+ (plist-get settings
:treesit-simple-indent-rules)))
+
+ (setq treesit-font-lock-feature-list
+ (typst-ts-els--merge-features
+ treesit-font-lock-feature-list
+ (plist-get settings
:treesit-font-lock-feature-list)))
+ (message "Getting %s language settings luckily
succeeded." lang))
+ (error
+ (message "Highlighting raw block error: \n%s"
+ (error-message-string err))))))
+ ;; whatever, we won't load that language again
+ (add-to-list 'typst-ts-els--include-languages lang))
)))))
(defun typst-ts-embedding-lang-settings-test ()
@@ -224,7 +156,6 @@ Use this function as one notifier of
`treesit-parser-notifiers'."
(typst-ts-els-merge-settings (cdr setting-entry)))
(message "No problem found!"))
-
(provide 'typst-ts-embedding-lang-settings)
;;; typst-ts-embedding-lang-settings.el ends here
diff --git a/typst-ts-mode.el b/typst-ts-mode.el
index baa09cdd5b..88a8852094 100644
--- a/typst-ts-mode.el
+++ b/typst-ts-mode.el
@@ -141,7 +141,7 @@ is eliminated."
:group 'typst-ts-faces)
(defcustom typst-ts-mode-raw-block-lang-list
- '(python) ; TODO
+ '(python rust) ; TODO
"Raw Block Lang List."
:type '(list symbol)
:group 'typst-ts)
@@ -999,11 +999,13 @@ See `treesit-language-at-point-function'."
(unless (treesit-ready-p 'typst)
(error "Tree-sitter for Typst isn't available"))
- (let ((parser (treesit-parser-create 'typst)))
- (when typst-ts-mode-highlight-raw-block
- (treesit-parser-add-notifier
- parser
- 'typst-ts-els-include-dynamically)))
+ (treesit-parser-create 'typst)
+
+ ;; (let ((parser (treesit-parser-create 'typst)))
+ ;; (when typst-ts-mode-highlight-raw-block
+ ;; (treesit-parser-add-notifier
+ ;; parser
+ ;; 'typst-ts-els-include-dynamically)))
;; Comments.
(typst-ts-mode-comment-setup)
@@ -1039,14 +1041,18 @@ See `treesit-language-at-point-function'."
(file-name-nondirectory buffer-file-name)
typst-ts-mode-compile-options))
- ;; use parser notifier to add font lock dynamically
- ;; TODO merge indentation rule
- ;; TODO merge font lock feature list
-
(setq-local treesit-language-at-point-function
'typst-ts-mode--language-at-point)
- (setq-local treesit-range-settings
- (typst-ts-mode--treesit-range-rules
typst-ts-mode-raw-block-lang-list))
+ ;; (setq-local treesit-range-settings
+ ;; (typst-ts-mode--treesit-range-rules '(python rust)))
+ ;; (setq-local treesit-range-settings
+ ;; (treesit-range-rules
+ ;; :host 'typst
+ ;; :embed 'rust
+ ;; ;; :local t
+ ;; '((raw_blck
+ ;; ;; lang: (_)
+ ;; (blob) @capture))))
;; Outline
(setq-local outline-regexp typst-ts-mode-outline-regexp)