branch: elpa/typst-ts-mode commit 364d32c37de591191a98a3e521e64df6aebe88e2 Author: Huan Nguyen <nguyenthieuh...@gmail.com> Commit: Huan Nguyen <nguyenthieuh...@gmail.com>
refactor: Typst watch is now a minor mode. --- typst-ts-mode.el | 140 +------------------------------------------------ typst-ts-watch-mode.el | 139 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 138 deletions(-) diff --git a/typst-ts-mode.el b/typst-ts-mode.el index 3a4c95f474..113458ed36 100644 --- a/typst-ts-mode.el +++ b/typst-ts-mode.el @@ -36,6 +36,7 @@ (require 'typst-ts-embedding-lang-settings) (require 'typst-ts-utils) (require 'typst-ts-faces) +(require 'typst-ts-watch-mode) (defgroup typst-ts nil "Tree Sitter enabled Typst Writing." @@ -109,53 +110,6 @@ the current buffer." :type 'hook :group 'typst-ts) -(defcustom typst-ts-mode-watch-options "" - "User defined compile options for `typst-ts-mode-watch'. -The compile options will be passed to the -`<typst-executable> watch <current-file>' sub-command." - :type 'string - :group 'typst-ts) - -(defcustom typst-ts-mode-watch-modeline-indicator-enable t - "Whether to enable mode line indicator for typst watch." - :type 'boolean - :group 'typst-ts) - -(defcustom typst-ts-mode-watch-modeline-indicator "[Watch]" - "Modeline indicator for typst watch." - :type 'string - :group 'typst-ts) - -(defcustom typst-ts-mode-watch-process-name "*Typst-Watch*" - "Process name for `typst watch' sub-command." - :type 'string - :group 'typst-ts) - -(defcustom typst-ts-mode-watch-process-buffer-name "*Typst-Watch*" - "Process buffer name for `typst watch' sub-command." - :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.") - -(defvar typst-ts-mode-after-watch-hook nil - "Hook runs after compile.") - ;; ============================================================================== ;; TODO typst has three modes (namely 'markup', 'code' and 'math') ;; Currently only add common settings to syntax table @@ -973,96 +927,6 @@ 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" (+ blank) "┌─ " - (+ not-newline) ":" ; file - (+ num) ":" ; start-line - (+ num) "\n" ; start-col - (+ (+ (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))))))) - -;;;###autoload -(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) - (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) - ;; add mode line indicator - (when typst-ts-mode-watch-modeline-indicator-enable - (push - (propertize typst-ts-mode-watch-modeline-indicator 'face 'typst-ts-watch-modeline-indicator-face) - global-mode-string)) - (message "Start Watch :3")) - -;;;###autoload -(defun typst-ts-mode-watch-stop () - "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) - (when window - (delete-window window))) - (run-hooks typst-ts-mode-after-watch-hook) - ;; remove mode line indicator - (when typst-ts-mode-watch-modeline-indicator-enable - (setq global-mode-string (remove typst-ts-mode-watch-modeline-indicator global-mode-string))) - (message "Stop Watch :‑.")) - -;;;###autoload -(defun typst-ts-mode-watch-toggle () - "Toggle watch process." - (interactive) - (if (get-process typst-ts-mode-watch-process-name) - (typst-ts-mode-watch-stop) - (typst-ts-mode-watch))) - (defvar typst-ts-compilation-mode-error (cons (rx bol "error:" (+ not-newline) "\n" (+ blank) "┌─ " (group (+ not-newline)) ":" ;; file @@ -1166,7 +1030,7 @@ PROC: process; OUTPUT: new output from PROC." (let ((map (make-sparse-keymap))) (define-key map (kbd "C-c C-c c") #'typst-ts-mode-compile-and-preview) (define-key map (kbd "C-c C-c C") #'typst-ts-mode-compile) - (define-key map (kbd "C-c C-c w") #'typst-ts-mode-watch-toggle) + (define-key map (kbd "C-c C-c w") #'typst-ts-watch-mode) (define-key map (kbd "C-c C-c p") #'typst-ts-mode-preview) (define-key map (kbd "M-<left>") #'typst-ts-mode-heading-decrease) (define-key map (kbd "M-<right>") #'typst-ts-mode-heading-increase) diff --git a/typst-ts-watch-mode.el b/typst-ts-watch-mode.el new file mode 100644 index 0000000000..a6c4d9385e --- /dev/null +++ b/typst-ts-watch-mode.el @@ -0,0 +1,139 @@ +;;; typst-ts-watch-mode.el --- Watch typst file -*- lexical-binding: t; -*- +;; Copyright (C) 2023 Meow King <mr.meowk...@anche.no> + +;; This file is NOT part of Emacs. +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: Minor mode for watching(hot compile) current typst file. + +;; + +;;; Code: + +(define-minor-mode typst-ts-watch-mode + "Watch(hot compile) current typst file." + :lighter " [Watch]" + :group 'typst-ts-watch + (if typst-ts-watch-mode + (typst-ts-watch-start) + (typst-ts-watch-stop))) + +(defcustom typst-ts-watch-options "" + "User defined compile options for `typst-ts-watch'. +The compile options will be passed to the +`<typst-executable> watch <current-file>' sub-command." + :type 'string) + +(defcustom typst-ts-watch-process-name "*Typst-Watch*" + "Process name for `typst watch' sub-command." + :type 'string) + +(defcustom typst-ts-watch-process-buffer-name "*Typst-Watch*" + "Process buffer name for `typst watch' sub-command." + :type 'string) + +(defcustom typst-ts-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) + +(defcustom typst-ts-display-watch-process-buffer-parameters + `(display-buffer-at-bottom + (window-height . fit-window-to-buffer)) + "Display buffer parameters." + :type 'symbol) + +(defvar typst-ts-before-watch-hook nil + "Hook runs before compile.") + +(defvar typst-ts-after-watch-hook nil + "Hook runs after compile.") + +(defun typst-ts--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" (+ blank) "┌─ " + (+ not-newline) ":" ; file + (+ num) ":" ; start-line + (+ num) "\n" ; start-col + (+ (+ (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-display-watch-process-bufer-automatically window) + (delete-window window)) + (insert res-output) + (goto-char (point-min)) + (when typst-ts-display-watch-process-bufer-automatically + (typst-ts-watch-display-buffer))))))) + +;;;###autoload +(defun typst-ts-watch-display-buffer () + "Display typst watch process buffer." + (interactive) + (if (not (buffer-live-p (get-buffer typst-ts-watch-process-buffer-name))) + (user-error "The typst watch process buffer %s is not alive!" typst-ts-watch-process-buffer-name) + (display-buffer + typst-ts-watch-process-buffer-name + typst-ts-display-watch-process-buffer-parameters))) + +;;;###autoload +(defun typst-ts-watch-start () + "Watch(hot compile) current typst file." + (interactive) + (run-hooks typst-ts-before-watch-hook) + (with-current-buffer (get-buffer-create typst-ts-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-watch-process-name typst-ts-watch-process-buffer-name + (format "%s watch %s %s" + typst-ts-mode-executable-location + (file-name-nondirectory buffer-file-name) + typst-ts-watch-options)) + 'typst-ts--watch-process-filter) + (message "Start Watch :3")) + +;;;###autoload +(defun typst-ts-watch-stop () + "Stop watch process." + (interactive) + (delete-process typst-ts-watch-process-name) + ;; delete associated watch process buffer and window + (let ((window (get-buffer-window typst-ts-watch-process-buffer-name))) + (kill-buffer typst-ts-watch-process-buffer-name) + (when window + (delete-window window))) + (run-hooks typst-ts-after-watch-hook) + (message "Stop Watch :‑.")) + +(provide 'typst-ts-watch-mode) +;;; typst-ts-watch-mode.el ends here