Hi Philip, Many thanks for this feedback, which I've incorporated (except that I've shied away from trying to optimize the function auctex-cont-latexmk--format-log-buffer, whose code is taken from an AUCTeX function that has proven reliable over the decades). The updated code is available at https://github.com/ultronozm/auctex-cont-latexmk.el. I copy below the patch that I've applied on top of your patch (attaching as well, just in case gmail messes up the formatting). Any further comments or feedback on this or the other packages would of course be very helpful. Paul diff --git a/auctex-cont-latexmk.el b/auctex-cont-latexmk.el index 6019767..29be6b0 100644 --- a/auctex-cont-latexmk.el +++ b/auctex-cont-latexmk.el @@ -64,6 +64,7 @@ (append TeX-error-description-list TeX-error-description-list-local))) (alist-get message error-alist nil nil #'string-match-p))) + (defun auctex-cont-latexmk-help-at-point () "Display the AUCTeX help for the error at point." (interactive) @@ -77,7 +78,7 @@ The arguments are as in `TeX-error-list'. Return either nil or a triple (ERROR-P DESCRIPTION (BEG . END)), where ERROR-P is non-nil if it is an error rather than a warning." (or - (and-let* + (when-let* (((not ignore)) ((stringp file)) ((or (not bad-box) TeX-debug-bad-boxes)) @@ -131,8 +132,6 @@ Adapted from `TeX-format-filter'." (while (not (bobp)) (end-of-line 0) (when (and (<= 79 (current-column) 80) - ;; I was imagining if this could be replaced by a clever regular expression like - ;; (not (looking-back (rx "." point (syntax word)) (line-beginning-position))) (not (memq (char-after (1+ (point))) '(?\n ?\())) (not (and (eq (char-before) ?.) (char-after (1+ (point))) @@ -153,12 +152,14 @@ Adapted from `TeX-format-filter'." Return a list of triples as in the docstring of `auctex-cont-latexmk-process-item'." (mapcan - (lambda (item) - (and-let* ((item (apply #'auctex-cont-latexmk-process-item item))) + (lambda (err) + (when-let ((item (apply #'auctex-cont-latexmk-process-item err))) (list item))) (auctex-cont-latexmk--error-list (TeX-master-output-file "log")))) + (defvar-local auctex-cont-latexmk--report-fn nil "Function provided by Flymake for reporting diagnostics.") + (defvar-local auctex-cont-latexmk-force-enable nil "Whether to enable the Flymake backend unconditionally. This is non-nil if we should enable the Flymake backend independent of @@ -198,38 +199,37 @@ Flymake report function to propagate to indirect buffers." (setq auctex-cont-latexmk--report-fn nil)) ;;; Continuous Compilation + (defcustom auctex-cont-latexmk-command - '("latexmk -pvc -shell-escape -pdf -view=none -e " ;is it safe to have "shell-escape" in by default? + '("latexmk -pvc -pdf -view=none -e " ("$pdflatex=q/pdflatex %O -synctex=1 -interaction=nonstopmode %S/")) "Command to compile LaTeX documents. This is a list consisting of strings or lists of strings. It is -compiled to a single string by concatenating the strings and quoting the -lists, using system-specific quotes. To produce the compilation -command, it is combined with an additional option to output build files -to a directory (if `TeX-output-dir' is set) and the name of the master -file." +compiled to a single string by + + - concatenating the strings, and + + - concatenating the contents of each list and quoting the result as a +shell argument. + +To produce the compilation command, the result is combined with an +additional option to output build files to a directory (if +`TeX-output-dir' is set) and the name of the master file." :type '(repeat (choice string (repeat string)))) (defun auctex-cont-latexmk--compilation-command () "Return the command used to compile the current LaTeX document." - (let ((quote - ;; I am surprised to see that this is necessary, but I don't - ;; know the background. does `shell-quote-argument' quote - ;; incorrectly? A comment explaining what is going on would - ;; be nice. - (if (memq system-type '(ms-dos windows-nt)) - "\"" - "'"))) - (concat - (mapconcat (lambda (item) - (if (listp item) - (concat quote (mapconcat #'identity item) quote) - item)) - auctex-cont-latexmk-command) - (when TeX-output-dir - (concat " -outdir=" (shell-quote-argument TeX-output-dir))) - " " - (shell-quote-argument (TeX-master-file "tex"))))) + (concat + (mapconcat + (lambda (item) + (if (listp item) + (shell-quote-argument (mapconcat #'identity item)) + item)) + auctex-cont-latexmk-command) + (when TeX-output-dir + (concat " -outdir=" (shell-quote-argument TeX-output-dir))) + " " + (shell-quote-argument (TeX-master-file "tex")))) (defun auctex-cont-latexmk--compilation-buffer-name () "Return the name of the buffer used for LaTeX compilation." @@ -258,7 +258,13 @@ file." This is the case if the current buffer is not modified, the current buffer is a file, the current buffer has a log file, the log file is newer than the current buffer, and the current latexmk compilation is -either in a watching state or has not updated recently." +either in a watching state or has not updated recently. + +The reason we check if the latexmk has not been updated recently is +because it seems that on Windows, the latexmk script doesn't always +display the most recent message. I haven't been able to debug why this +is the case. Checking that the compilation has not been updated +recently serves as a workaround." (when-let* ((file (or buffer-file-name (buffer-file-name (buffer-base-buffer)))) (log-file (TeX-master-output-file "log"))) @@ -266,9 +272,12 @@ either in a watching state or has not updated recently." (when-let ((buf auctex-cont-latexmk--compilation-buffer)) (with-current-buffer buf (or - (search-forward-regexp - (rx (literal auctex-cont-latexmk--watching-str) (? ?\n) eos) - nil t) + (progn + (goto-char (point-max)) + (forward-line -1) + (re-search-forward + (rx (literal auctex-cont-latexmk--watching-str) (? ?\n) eos) + nil t)) (and (or auctex-cont-latexmk--last-update-time (time-less-p (time-subtract (current-time) @@ -308,12 +317,8 @@ empty, except when NOKILL is non-nil." (when (null auctex-cont-latexmk--subscribed-buffers) (setq done t))) (when done - (let ((process (get-buffer-process comp-buf))) - (when (process-live-p process) - (interrupt-process process) - (sit-for 0.1) ;isn't this racy? or is that not a problem? - (delete-process process)) - (unless nokill + (unless nokill + (let ((kill-buffer-query-functions nil)) ; don't ask to kill process (kill-buffer comp-buf))))))) (defvar-local auctex-cont-latexmk--disable-function nil @@ -387,8 +392,9 @@ Saved and restored by `auctex-cont-latexmk-toggle'.") (defcustom auctex-cont-latexmk-retained-flymake-backends '(eglot-flymake-backend) "Flymake backends to retain when enabling `auctex-cont-latexmk-mode'." - :type 'boolean) ;I don't think the type is right - (defun auctex-cont-latexmk-turn-on () + :type '(repeat symbol)) + +(defun auctex-cont-latexmk-turn-on () "Enable `auctex-cont-latexmk-mode' and set up Flymake." (interactive) (auctex-cont-latexmk-mode 1) @@ -421,10 +427,9 @@ Saved and restored by `auctex-cont-latexmk-toggle'.") (defun auctex-cont-latexmk-toggle () "Toggle `auctex-cont-latexmk-mode' and its Flymake backend." (interactive) - (cond (auctex-cont-latexmk-mode ;isn't this more of a `if'-place? - (auctex-cont-latexmk-turn-off)) - (t - (auctex-cont-latexmk-turn-on)))) + (if auctex-cont-latexmk-mode + (auctex-cont-latexmk-turn-off) + (auctex-cont-latexmk-turn-on))) (provide 'auctex-cont-latexmk) ;;; auctex-cont-latexmk.el ends here