branch: elpa/typst-ts-mode commit 01ef0d45b9b658de7f620401a155b4c9592897c2 Author: Ziqi Yang <mr.ziqiy...@gmail.com> Commit: Ziqi Yang <mr.ziqiy...@gmail.com>
feat: better functionality for typst watch process --- typst-ts-mode.el | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 96 insertions(+), 9 deletions(-) diff --git a/typst-ts-mode.el b/typst-ts-mode.el index 02de48cf0e..1571d933fb 100644 --- a/typst-ts-mode.el +++ b/typst-ts-mode.el @@ -28,6 +28,7 @@ ;;; Code: (require 'treesit) +(require 'compile) (defgroup typst-ts nil "Tree Sitter enabled Typst Writing." @@ -73,6 +74,7 @@ The compile options will be passed to the :type 'string :group 'typst-ts) + (defcustom typst-ts-mode-watch-process-name "*Typst-Watch*" "Process name for `typst watch' sub-command." :type 'string @@ -83,6 +85,20 @@ The compile options will be passed to the :type 'string :group 'typst-ts) +(defcustom typst-ts-mode-display-watch-process-bufer-automatically t + "Whether the typst watch process buffer should be displayed automatically. +This means the buffer will be displayed when error occurs, hide when error +is eliminated." + :type 'boolean + :group 'typst-ts) + +(defcustom typst-ts-mode-display-watch-process-buffer-parameters + `(display-buffer-at-bottom + (window-height . fit-window-to-buffer)) + "Display buffer parameters." + :type 'symbol + :group 'typst-ts) + (defvar typst-ts-mode-before-watch-hook nil "Hook runs after compile.") @@ -409,8 +425,6 @@ The compile options will be passed to the (attach ["^" "_"] @font-lock-operator-face) (align) @font-lock-operator-face))) - - (defconst typst-ts-mode--bracket-node-types '("block" "content" "group") "Bracket node types.") @@ -530,7 +544,12 @@ buffer before compilation." ;; define them inside a let binding. (add-hook 'compilation-finish-functions (typst-ts-mode-compile--compilation-finish-function (current-buffer))) - (compile compile-command)) + (compile + (format "%s compile %s %s" + typst-ts-mode-executable-location + (file-name-nondirectory buffer-file-name) + typst-ts-mode-compile-options) + 'typst-ts-compilation-mode)) ;;;###autoload (defun typst-ts-mode-preview (file) @@ -551,6 +570,7 @@ buffer before compilation." (remove-hook 'compilation-finish-functions (typst-ts-mode-compile-and-preview--compilation-finish-function cur-buffer))))) +;;;###autoload (defun typst-ts-mode-compile-and-preview () "Compile & Preview. Assuming the compile output file name is in default style." @@ -562,17 +582,64 @@ Assuming the compile output file name is in default style." (current-buffer))) (typst-ts-mode-compile)) +(defun typst-ts-mode--watch-process-filter (proc output) + "Filter the `typst watch' process output. +Only error will be transported to the process buffer. +See `(info \"(elisp) Filter Functions\")'. +PROC: process; OUTPUT: new output from PROC." + (when (buffer-live-p (process-buffer proc)) + (with-current-buffer (process-buffer proc) + (erase-buffer) + (let ((window (get-buffer-window)) + (re (rx bol "error:" (+ not-newline) "\n ┌─ " + (+ not-newline) ":" ;; file + (+ num) ":" ;; start-line + (+ num) "\n" + (+ (+ (or blank num)) "│" (* not-newline) "\n"))) + (next-match-start-pos 0) + res-output) + (while (string-match re output next-match-start-pos) + (setq res-output (concat + res-output + (when res-output "\n") + (substring output (match-beginning 0) (match-end 0))) + next-match-start-pos (match-end 0))) + ;; Insert the Error text + (if (not res-output) + (when (and typst-ts-mode-display-watch-process-bufer-automatically window) + (delete-window window)) + (insert res-output) + (goto-char (point-min)) + (when typst-ts-mode-display-watch-process-bufer-automatically + (typst-ts-mode-display-watch-buffer))))))) + +(defun typst-ts-mode-display-watch-buffer () + "Display typst watch process buffer." + (interactive) + (if (not (buffer-live-p (get-buffer typst-ts-mode-watch-process-buffer-name))) + (user-error "The typst watch process buffer %s is not alive!" typst-ts-mode-watch-process-buffer-name) + (display-buffer + typst-ts-mode-watch-process-buffer-name + typst-ts-mode-display-watch-process-buffer-parameters))) + ;;;###autoload (defun typst-ts-mode-watch () "Watch(hot compile) current typst file." (interactive) (run-hooks typst-ts-mode-before-watch-hook) - (start-process-shell-command - typst-ts-mode-watch-process-name typst-ts-mode-watch-process-buffer-name - (format "%s watch %s %s" - typst-ts-mode-executable-location - (file-name-nondirectory buffer-file-name) - typst-ts-mode-watch-options)) + (with-current-buffer (get-buffer-create typst-ts-mode-watch-process-buffer-name) + (erase-buffer) + (unless (eq major-mode 'typst-ts-compilation-mode) + (typst-ts-compilation-mode) + (read-only-mode -1))) + (set-process-filter + (start-process-shell-command + typst-ts-mode-watch-process-name typst-ts-mode-watch-process-buffer-name + (format "%s watch %s %s" + typst-ts-mode-executable-location + (file-name-nondirectory buffer-file-name) + typst-ts-mode-watch-options)) + 'typst-ts-mode--watch-process-filter) (message "Start Watch :3")) ;;;###autoload @@ -580,6 +647,10 @@ Assuming the compile output file name is in default style." "Stop watch process." (interactive) (delete-process typst-ts-mode-watch-process-name) + ;; delete associated watch process buffer and window + (let ((window (get-buffer-window typst-ts-mode-watch-process-buffer-name))) + (kill-buffer typst-ts-mode-watch-process-buffer-name) + (delete-window window)) (run-hooks typst-ts-mode-after-watch-hook) (message "Stop Watch :‑.")) @@ -591,6 +662,22 @@ Assuming the compile output file name is in default style." (typst-ts-mode-watch-stop) (typst-ts-mode-watch))) +(defvar typst-ts-compilation-mode-error + (cons (rx bol "error:" (+ not-newline) "\n ┌─ " + (group (+ not-newline)) ":" ;; file + (group (+ num)) ":" ;; start-line + (group (+ num)) "\n") ;; start-col + '(1 2 3)) + "Regexp for Error in compilation buffer.") + +(define-compilation-mode typst-ts-compilation-mode "Typst Compilation" + "Customized major mode for typst watch compilation." + (setq-local compilation-error-regexp-alist-alist nil) + (add-to-list 'compilation-error-regexp-alist-alist + (cons 'typst-error typst-ts-compilation-mode-error)) + (setq-local compilation-error-regexp-alist nil) + (add-to-list 'compilation-error-regexp-alist 'typst-error)) + (defvar typst-ts-mode-map (let ((map (make-sparse-keymap))) (define-key map (kbd "C-c C-c c") #'typst-ts-mode-compile-and-preview)