branch: elpa/typst-ts-mode
commit 208aa360d89a7016554913877fbc18e326dc5878
Author: Meow King <mr.meowk...@anche.no>
Commit: Meow King <mr.meowk...@anche.no>

    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)

Reply via email to