branch: externals/auctex-cont-latexmk
commit 549d8c06a7b581e1aefa42e730b2d29ca9e1c10f
Author: Paul Nelson <[email protected]>
Commit: Paul Nelson <[email protected]>
got it in decent working shape, modulo an occasional error
---
README.org | 13 ++--
czm-tex-compile.el | 209 +++++++++++++++++++++++++++++------------------------
2 files changed, 120 insertions(+), 102 deletions(-)
diff --git a/README.org b/README.org
index b7871545ad..95bdfe166e 100644
--- a/README.org
+++ b/README.org
@@ -2,22 +2,19 @@
#+author: Paul Nelson
* Overview
-This package provides convenience functions that support a LaTeX workflow
where =latexmk= continuously compiles the document in the background.
+This package provides a minor mode where
[[https://ctan.org/pkg/latexmk?lang=en][latexmk]] continuously compiles the
document in the background and the errors/warnings are reported via
[[https://www.gnu.org/software/emacs/manual/html_node/emacs/Flymake.html][Flymake]].
* Configuration
Download this repository, install using =M-x package-install-file= (or
package-vc-install, straight, elpaca, ...), and add something like the
following to your [[https://www.emacswiki.org/emacs/InitFile][init file]]:
#+begin_src elisp
(use-package czm-tex-compile
:bind
- ("C-c k" . czm-tex-compile)
- ("s-]" . czm-tex-compile-next-error)
- ("s-[" . czm-tex-compile-previous-error))
+ ("C-c k" . czm-tex-compile-toggle))
#+end_src
-Replace the keybindings with whatever you prefer (or delete them and just run
the commands via =M-x=).
+Replace the keybinding with whatever you prefer (or delete it and just run the
command via =M-x=).
-* Usage
+You can tweak underlying the =latexmk= command via =M-x customize-variable
czm-tex-compile-command=.
-- If you run =czm-tex-compile= in a TeX buffer visiting "foo.tex", it starts
an =eshell= buffer =*eshell-foo*= in the background that continuously compiles
the current document. Use =M-x customize-variable czm-tex-compile-command= to
customize the compilation command. If you run the same command again, then it
switches to the =eshell= buffer.
-- =czm-tex-compile-next-error= and =czm-tex-compile-previous-error= navigate
the error and warning messages encountered in the log file produced by
=latexmk=, jumping to the corresponding positions in the tex buffer.
+The command =czm-tex-compile-toggle= behaves the way that I prefer -- it
enables both =czm-tex-compile-mode= and =flymake-mode=, restricting the
backends for the latter to those coming from the former. Depending upon your
preferences, you may wish to write your own "wrapper" akin to
=czm-tex-compile-toggle= for =czm-tex-compile-mode=.
That's all. I prefer this workflow to the alternative in which one compiles
the document manually via =TeX-command-master= (=C-c C-c=) and navigates the
warning/error messages using =next-error= (=M-n=) and =previous-error (=M-p=).
It also gives a handy way to keep the .aux files up-to-date; I take advantage
of this feature in the packages
[[https://github.com/ultronozm/czm-preview.el][czm-preview.el]] and
[[https://github.com/ultronozm/czm-tex-fold.el][czm-tex-fold.el]] to annotate
th [...]
diff --git a/czm-tex-compile.el b/czm-tex-compile.el
index 13535a11f5..7c2a81c1f4 100644
--- a/czm-tex-compile.el
+++ b/czm-tex-compile.el
@@ -5,7 +5,7 @@
;; Author: Paul D. Nelson <[email protected]>
;; Version: 0.0
;; URL: https://github.com/ultronozm/czm-tex-compile.el
-;; Package-Requires: ((emacs "29.1"))
+;; Package-Requires: ((emacs "29.1") (auctex))
;; Keywords: tex
;; This program is free software; you can redistribute it and/or modify
@@ -23,83 +23,107 @@
;;; Commentary:
-;; This package provides convenience functions for compiling a LaTeX
-;; document continuously via latexmk and navigating the errors and
-;; warnings recorded in the log file. Customize the variable
-;; `czm-tex-compile-command' to change the command used to compile the
-;; document.
+;; This package provides a minor mode that compiles a LaTeX document
+;; via latexmk and reports errors and warnings to a `flymake' backend.
+;; Customize the variable `czm-tex-compile-command' to change the
+;; command used to compile the document.
;;
;; My use-package declaration:
;;
;; (use-package czm-tex-compile
-;; :vc (:url "https://github.com/ultronozm/czm-tex-compile.el.git"
-;; :rev :newest)
-;; :after latex
-;; :bind
-;; ("C-c k" . czm-tex-compile)
-;; ("s-]" . czm-tex-compile-next-error)
-;; ("s-[" . czm-tex-compile-previous-error))
+;; :elpaca (:host github :repo "ultronozm/czm-tex-compile.el"
+;; :depth nil)
+;; :bind
+;; ("C-c k" . czm-tex-compile-toggle))
;;; Code:
(require 'esh-mode)
+(defgroup czm-tex-compile nil
+ "Convenience functions for compiling LaTeX documents."
+ :group 'tex)
+
(defcustom czm-tex-compile-command
"latexmk -shell-escape -pvc -pdf -view=none -e '$pdflatex=q/pdflatex %O
-synctex=1 -interaction=nonstopmode %S/'"
"Command to compile LaTeX documents."
- :type 'string
- :group 'czm-tex-compile)
-
-(defun czm-tex-compile--kill-buffer-hook ()
- "Hook to kill the eshell buffer when the LaTeX buffer is killed."
- (when (string-match "\\([^\.]+\\)\.tex" (buffer-name))
- (let* ((name (match-string 1 (buffer-name)))
- (bufname (concat "*eshell-" name "*")))
- (when (get-buffer bufname)
- (let ((kill-buffer-query-functions '()))
- (with-current-buffer bufname
- (eshell-interrupt-process))
- (kill-buffer bufname))))))
+ :type 'string)
+
+(defvar-local czm-tex-compile-process nil
+ "Process running the LaTeX compilation.")
+
+(defvar-local czm-tex-compile-log-watch-descriptor nil)
+(defvar-local czm-tex-compile-report-fn nil)
+(defvar-local czm-tex-compile-log-watch-timer nil)
+(defvar-local czm-tex-compile--compilation-buffer-name nil)
;;;###autoload
-(defun czm-tex-compile ()
- "Compile the current LaTeX document in an eshell buffer.
-If the eshell buffer already exists, switch to it. Otherwise,
-create a new eshell buffer and compile the document in it. The
-eshell buffer is named *eshell-<name>*, where <name>.tex is the
-name of the current LaTeX file."
- (interactive)
- (when (string-match "\\([^\.]+\\)\.tex" (buffer-name))
- (let* ((name (match-string 1 (buffer-name)))
- (bufname (concat "*eshell-" name "*")))
- (czm-tex-compile-restrict-flymake-backends)
- ;; (czm-tex-compile-setup-flymake-backend)
- (if (get-buffer bufname)
- (switch-to-buffer bufname)
- (save-window-excursion
- (add-hook 'kill-buffer-hook #'czm-tex-compile--kill-buffer-hook)
- (eshell "new")
- (rename-buffer bufname)
- (insert (concat czm-tex-compile-command " " name ".tex"))
- (eshell-send-input))))))
-
-(defvar-local czm-tex-compile--log-state nil
- "Cons containing last navigation time and log file position.")
-
-;; maybe delete this?
-(defun czm-tex-compile--paragraph-as-line ()
- "Return the current paragraph as a single line.
-Used for navigating LaTeX warnings in the log file."
+(define-minor-mode czm-tex-compile-mode
+ "If enabled, run LaTeX compilation on the current buffer."
+ :lighter " TexC"
+ (if czm-tex-compile-mode
+ (let ((name (and (string-match "\\([^\.]+\\)\.tex" (buffer-name))
+ (match-string 1 (buffer-name)))))
+ (unless name
+ (user-error "Buffer name does not match expected pattern"))
+ (when (process-live-p czm-tex-compile-process)
+ (interrupt-process czm-tex-compile-process)
+ (sit-for 1)
+ (delete-process czm-tex-compile-process))
+ (setq czm-tex-compile--compilation-buffer-name (concat
"*czm-tex-compile-" name "*"))
+ (let ((command (concat czm-tex-compile-command " " name ".tex")))
+ (setq czm-tex-compile-process
+ (start-process-shell-command "czm-tex-compile"
czm-tex-compile--compilation-buffer-name
+ command)))
+ (add-hook 'kill-buffer-hook 'czm-tex-compile--kill-process nil t)
+ (add-hook 'flymake-diagnostic-functions #'czm-tex-compile-flymake nil
t))
+ (czm-tex-compile--kill-process)
+ (when czm-tex-compile-log-watch-descriptor
+ (file-notify-rm-watch czm-tex-compile-log-watch-descriptor)
+ (setq czm-tex-compile-log-watch-descriptor nil))
+ (when czm-tex-compile-log-watch-timer
+ (cancel-timer czm-tex-compile-log-watch-timer)
+ (setq czm-tex-compile-log-watch-timer nil))
+ (when czm-tex-compile-report-fn
+ (setq czm-tex-compile-report-fn nil))))
+
+;;;###autoload
+(defun czm-tex-compile-toggle ()
+ "Toggle `czm-tex-compile-mode', and also `flymake'."
(interactive)
- (let ((beg (point))
- (end (save-excursion
- (forward-paragraph)
- (point))))
- (replace-regexp-in-string "\n" "" (buffer-substring-no-properties beg
end))))
+ (if czm-tex-compile-mode
+ (progn
+ (czm-tex-compile-mode 0)
+ (flymake-mode 0)
+ (czm-tex-compile-relax-flymake-backends)
+ (message "czm-tex-compile-mode and flymake-mode disabled"))
+ (czm-tex-compile-mode 1)
+ (czm-tex-compile-restrict-flymake-backends)
+ (flymake-mode 1)
+ (message "czm-tex-compile-mode and flymake-mode enabled")))
+
+(defun czm-tex-compile--kill-process ()
+ "Kill the LaTeX compilation process associated with the buffer."
+ (when (process-live-p czm-tex-compile-process)
+ (interrupt-process czm-tex-compile-process)
+ (sit-for 1)
+ (delete-process czm-tex-compile-process))
+ (when (get-buffer czm-tex-compile--compilation-buffer-name)
+ (kill-buffer czm-tex-compile--compilation-buffer-name)))
(require 'tex)
+
+(defun testing ()
+ (interactive)
+ (while (re-search-forward "Warning:" nil t)
+ ;; make it all appear on one line
+ (end-of-line)
+ (while (not (looking-at "\n\n"))
+ (delete-char 1)
+ (end-of-line))))
+
(defun czm-tex-compile-process-log ()
"Process the log file for the current LaTeX document."
(let* ((current-buf (current-buffer))
@@ -108,6 +132,13 @@ Used for navigating LaTeX warnings in the log file."
".log")))
(with-temp-buffer
(insert-file-contents log-file)
+ (goto-char (point-min))
+ (while (re-search-forward "Warning:" nil t)
+ ;; make it all appear on one line
+ (end-of-line)
+ (while (not (looking-at "\n\n"))
+ (delete-char 1)
+ (end-of-line)))
(let* ((error-list (progn (TeX-parse-all-errors)
TeX-error-list))
(filtered (seq-filter
@@ -189,14 +220,11 @@ the log file is newer than the current buffer."
(lambda (datum)
(cl-destructuring-bind (error-p description region)
datum
- (flymake-make-diagnostic
- (current-buffer)
- (car region)
- (cdr region)
- (if error-p
- :error
- :warning)
- description)))
+ (flymake-make-diagnostic (current-buffer)
+ (car region)
+ (cdr region)
+ (if error-p :error :warning)
+ description)))
(seq-filter
(lambda (datum)
(not (null (nth 2 datum))))
@@ -204,20 +232,17 @@ the log file is newer than the current buffer."
(funcall report-fn diags)
t))
-(defun czm-tex-compile-report-if-fresh (report-fn)
+(defun czm-tex-compile-report-if-fresh ()
"Call REPORT-FN if the current buffer is fresh."
- (when (czm-tex-compile--fresh-p)
- (czm-tex-compile-report report-fn)))
-
-(defvar czm-tex-compile-log-watch-descriptor nil)
-(defvar czm-tex-compile-report-fn nil)
-(defvar czm-tex-compile-log-watch-timer nil)
+ (when (and czm-tex-compile-report-fn
+ (czm-tex-compile--fresh-p))
+ (czm-tex-compile-report czm-tex-compile-report-fn)))
(defun czm-tex-compile-log-timer-fn ()
"Call `czm-tex-compile-report-if-fresh' and cancels the timer."
(when czm-tex-compile-log-watch-timer
(cancel-timer czm-tex-compile-log-watch-timer))
- (czm-tex-compile-report-if-fresh czm-tex-compile-report-fn))
+ (czm-tex-compile-report-if-fresh))
(defun czm-tex-compile-log-change-handler (event)
"Handle EVENT from log watcher.
@@ -228,8 +253,8 @@ update."
'changed)
(when czm-tex-compile-log-watch-timer
(cancel-timer czm-tex-compile-log-watch-timer))
- (setq-local czm-tex-compile-log-watch-timer
- (run-with-timer 1 1 #'czm-tex-compile-log-timer-fn))))
+ (setq czm-tex-compile-log-watch-timer
+ (run-with-timer 1 1 #'czm-tex-compile-log-timer-fn))))
(require 'filenotify)
@@ -237,31 +262,27 @@ update."
"Flymake backend for LaTeX based on latexmk.
REPORT-FN is the function called to report diagnostics.
ARGS are the keyword-value pairs concerning edits"
- (czm-tex-compile-report-if-fresh report-fn)
- (setq-local czm-tex-compile-report-fn report-fn)
- (when czm-tex-compile-log-watch-descriptor
- (file-notify-rm-watch czm-tex-compile-log-watch-descriptor))
- (setq-local czm-tex-compile-log-watch-descriptor
- (file-notify-add-watch
- (concat (file-name-sans-extension (buffer-file-name))
- ".log")
- '(change)
- #'czm-tex-compile-log-change-handler)))
-
-(defun czm-tex-compile-setup-flymake-backend ()
- "Setup flymake backend."
- (add-hook 'flymake-diagnostic-functions #'czm-tex-compile-flymake
- nil t))
+ (when (czm-tex-compile-mode)
+ (setq czm-tex-compile-report-fn report-fn)
+ (czm-tex-compile-report-if-fresh)
+ (when czm-tex-compile-log-watch-descriptor
+ (file-notify-rm-watch czm-tex-compile-log-watch-descriptor))
+ (setq czm-tex-compile-log-watch-descriptor
+ (file-notify-add-watch
+ (concat (file-name-sans-extension (buffer-file-name))
+ ".log")
+ '(change)
+ #'czm-tex-compile-log-change-handler))))
(defun czm-tex-compile-restrict-flymake-backends ()
"Restrict flymake backends to `czm-tex-compile-flymake'."
(interactive)
- (setq flymake-diagnostic-functions '(czm-tex-compile-flymake t)))
+ (setq-local flymake-diagnostic-functions '(czm-tex-compile-flymake t)))
(defun czm-tex-compile-relax-flymake-backends ()
"Relax flymake backends to include `LaTeX-flymake'."
(interactive)
- (setq flymake-diagnostic-functions '(czm-tex-compile-flymake LaTeX-flymake
t)))
+ (setq-local flymake-diagnostic-functions '(czm-tex-compile-flymake
LaTeX-flymake t)))