branch: elpa/typst-ts-mode
commit c059a85f9ab658662895d53eef53ace0f70088ca
Author: Ziqi Yang <mr.ziqiy...@gmail.com>
Commit: Ziqi Yang <mr.ziqiy...@gmail.com>

    feat: add preview command and fix after-compile hook issue
---
 typst-ts-mode.el | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 83 insertions(+), 8 deletions(-)

diff --git a/typst-ts-mode.el b/typst-ts-mode.el
index d8c5ca66ab..02de48cf0e 100644
--- a/typst-ts-mode.el
+++ b/typst-ts-mode.el
@@ -52,13 +52,24 @@
 
 (defcustom typst-ts-mode-compile-options ""
   "User defined compile options for `typst-ts-mode-compile'.
-The compile options will be passed to the `typst compile' sub-command."
+The compile options will be passed to the end of
+`<typst-executable> compile <current-file>' command."
   :type 'string
   :group 'typst-ts)
 
+(defvar typst-ts-mode-before-compile-hook nil
+  "Hook runs after compile.")
+
+(defvar typst-ts-mode-after-compile-hook nil
+  "Hook runs after compile.
+Note the requirement of this hook is the same as 
`compilation-finish-functions'.
+Also note that this hook runs with typst buffer(the buffer you are editing) as
+the current buffer.")
+
 (defcustom typst-ts-mode-watch-options ""
   "User defined compile options for `typst-ts-mode-watch'.
-The compile options will be passed to the `typst watch' sub-command."
+The compile options will be passed to the
+`<typst-executable> watch <current-file>' sub-command."
   :type 'string
   :group 'typst-ts)
 
@@ -72,6 +83,12 @@ The compile options will be passed to the `typst watch' 
sub-command."
   :type 'string
   :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.")
+
 (defcustom typst-ts-markup-header-same-height nil
   "Whether to make header face in markup context share the same height."
   :type 'boolean
@@ -490,27 +507,83 @@ TYPES."
   "Generate name of NODE for displaying in Imenu."
   (treesit-node-text node))
 
+(defun typst-ts-mode-compile--compilation-finish-function (cur-buffer)
+  "For `typst-ts-mode-after-compile-hook' and `compilation-finish-functions'.
+CUR-BUFFER: original typst buffer, in case user set
+`display-buffer-alist' option for compilation buffer to switch to compilation
+buffer before compilation."
+  (lambda (compilation-buffer msg)
+    (unwind-protect
+        (with-current-buffer cur-buffer
+          (run-hook-with-args 'typst-ts-mode-after-compile-hook 
compilation-buffer msg))
+      (remove-hook 'compilation-finish-functions
+                   (typst-ts-mode-compile--compilation-finish-function 
cur-buffer)))))
+
 ;;;###autoload
 (defun typst-ts-mode-compile ()
-  "Compile current typst file to pdf."
+  "Compile current typst file."
   (interactive)
+  (run-hooks typst-ts-mode-before-compile-hook)
+
+  ;; The reason to take such a awkward solution is that 
`compilation-finish-functions'
+  ;; should be a global variable and also its functions. It doesn't work if we
+  ;; define them inside a let binding.
+  (add-hook 'compilation-finish-functions
+            (typst-ts-mode-compile--compilation-finish-function 
(current-buffer)))
   (compile compile-command))
 
+;;;###autoload
+(defun typst-ts-mode-preview (file)
+  "Open the result compile file.
+FILE: file path for the result compile file."
+  (interactive (list (concat (file-name-base buffer-file-name) ".pdf")))
+  (browse-url-of-file file))
+
+(defun typst-ts-mode-compile-and-preview--compilation-finish-function 
(cur-buffer)
+  "For `typst-ts-mode-compile-and-preview' and `compilation-finish-functions'.
+CUR-BUFFER: original typst buffer, in case user set
+`display-buffer-alist' option for compilation buffer to switch to compilation
+buffer before compilation."
+  (lambda (_b _msg)
+    (unwind-protect
+        (with-current-buffer cur-buffer
+          (call-interactively #'typst-ts-mode-preview))
+      (remove-hook 'compilation-finish-functions
+                   
(typst-ts-mode-compile-and-preview--compilation-finish-function cur-buffer)))))
+
+(defun typst-ts-mode-compile-and-preview ()
+  "Compile & Preview.
+Assuming the compile output file name is in default style."
+  (interactive)
+  ;; use a local variable version of `compilation-finish-functions' to shadow
+  ;; global version doesn't work
+  (add-hook 'compilation-finish-functions
+            (typst-ts-mode-compile-and-preview--compilation-finish-function
+             (current-buffer)))
+  (typst-ts-mode-compile))
+
+;;;###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)))
+           typst-ts-mode-watch-options))
+  (message "Start Watch :3"))
 
+;;;###autoload
 (defun typst-ts-mode-watch-stop ()
   "Stop watch process."
   (interactive)
-  (delete-process typst-ts-mode-watch-process-name))
+  (delete-process typst-ts-mode-watch-process-name)
+  (run-hooks typst-ts-mode-after-watch-hook)
+  (message "Stop Watch :‑."))
 
+;;;###autoload
 (defun typst-ts-mode-watch-toggle ()
   "Toggle watch process."
   (interactive)
@@ -520,8 +593,10 @@ TYPES."
 
 (defvar typst-ts-mode-map
   (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "C-c C-c") #'typst-ts-mode-compile)
-    (define-key map (kbd "C-c C-x") #'typst-ts-mode-watch-toggle)
+    (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 p") #'typst-ts-mode-preview)
     map))
 
 ;;;###autoload
@@ -565,6 +640,7 @@ TYPES."
                  typst-ts-mode--imenu-name-function)
                 ("Headings" "^heading$" nil 
typst-ts-mode--imenu-name-function)))
 
+  ;; Compile Command
   (setq-local compile-command
               (format "%s compile %s %s"
                       typst-ts-mode-executable-location
@@ -573,7 +649,6 @@ TYPES."
 
   (treesit-major-mode-setup))
 
-;; TODO check consistence with typst-mode
 ;;;###autoload
 (add-to-list 'auto-mode-alist '("\\.typ\\'" . typst-ts-mode))
 

Reply via email to