branch: externals/auctex-cont-latexmk
commit 2762ee8084f202bcadd7dbad6988039b98315bf1
Author: Paul Nelson <ultr...@gmail.com>
Commit: Paul Nelson <ultr...@gmail.com>

    polish
---
 README.org         |   2 +
 czm-tex-compile.el | 189 +++++++++++++++++++++++------------------------------
 2 files changed, 85 insertions(+), 106 deletions(-)

diff --git a/README.org b/README.org
index 17c37c7d9b..089d385feb 100644
--- a/README.org
+++ b/README.org
@@ -17,4 +17,6 @@ You can tweak underlying the =latexmk= command via =M-x 
customize-variable czm-t
 
 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" for 
=czm-tex-compile-mode= akin to =czm-tex-compile-toggle=.
 
+The way the Flymake backend works, it will update only when the latexmk 
process reaches a "watching for changes" state and the buffer is unmodified.  
The workflow to have errors and warnings reported is to save the file and wait 
a few seconds without editing.
+
 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 t 
[...]
diff --git a/czm-tex-compile.el b/czm-tex-compile.el
index 72d6db3a0a..11259d5647 100644
--- a/czm-tex-compile.el
+++ b/czm-tex-compile.el
@@ -3,7 +3,7 @@
 ;; Copyright (C) 2023  Paul D. Nelson
 
 ;; Author: Paul D. Nelson <nelson.paul.da...@gmail.com>
-;; Version: 0.0
+;; Version: 0.1
 ;; URL: https://github.com/ultronozm/czm-tex-compile.el
 ;; Package-Requires: ((emacs "29.1") (auctex))
 ;; Keywords: tex
@@ -24,9 +24,9 @@
 ;;; Commentary:
 
 ;; 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.
+;; via latexmk, reporting errors via `flymake'.  Customize the
+;; variable `czm-tex-compile-command' to change the command used to
+;; compile the document.
 ;;
 ;; My use-package declaration:
 ;;
@@ -49,83 +49,90 @@
   "Command to compile LaTeX documents."
   :type 'string)
 
-(defvar-local czm-tex-compile-process nil
+(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)
+(defvar-local czm-tex-compile--report-fn nil
+  "Function provided by Flymake for reporting diagnostics.")
+
+(defvar-local czm-tex-compile--log-watch-timer nil
+  "Timer for reporting changes to the log file.")
+
+(defvar-local czm-tex-compile--compilation-buffer-name nil
+  "Name of the buffer used for LaTeX compilation.")
 
 ;;;###autoload
 (define-minor-mode czm-tex-compile-mode
   "If enabled, run LaTeX compilation on the current buffer."
-  :lighter " TexC"
+  :lighter nil
   (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)
+        (when (process-live-p czm-tex-compile--process)
+          (interrupt-process czm-tex-compile--process)
           (sit-for 0.1)
-          (delete-process czm-tex-compile-process))
-        (setq czm-tex-compile--compilation-buffer-name (concat 
"*czm-tex-compile-" name "*"))
+          (delete-process czm-tex-compile--process))
+        (setq czm-tex-compile--compilation-buffer-name (concat 
"*czm-tex-compile-" (expand-file-name name)
+                                                               "*"))
         (let ((command (concat czm-tex-compile-command " " name ".tex")))
-          (setq czm-tex-compile-process
+          (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))
+        (add-hook 'flymake-diagnostic-functions #'czm-tex-compile-flymake nil 
t)
+        (when czm-tex-compile--log-watch-timer
+          (cancel-timer czm-tex-compile--log-watch-timer)
+          (setq czm-tex-compile--log-watch-timer nil))
+        (setq czm-tex-compile--log-watch-timer
+              (run-with-timer 1 1 #'czm-tex-compile-report-if-fresh)))
     (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))))
+    (when czm-tex-compile--report-fn
+      (setq czm-tex-compile--report-fn nil))))
+
+(defvar-local czm-tex-compile--old-flymake-diagnostic-functions nil
+  "Value of `flymake-diagnostic-functions' before calling 
`czm-tex-compile-toggle'.")
 
 ;;;###autoload
 (defun czm-tex-compile-toggle ()
-  "Toggle `czm-tex-compile-mode', and also `flymake'."
+  "Toggle `czm-tex-compile-mode', and also `flymake-mode'."
   (interactive)
   (if czm-tex-compile-mode
       (progn
         (czm-tex-compile-mode 0)
         (flymake-mode 0)
-        (czm-tex-compile-relax-flymake-backends)
+        (setq-local flymake-diagnostic-functions
+                    czm-tex-compile--old-flymake-diagnostic-functions)
         (message "czm-tex-compile-mode and flymake-mode disabled"))
     (czm-tex-compile-mode 1)
-    (czm-tex-compile-restrict-flymake-backends)
+    (setq czm-tex-compile--old-flymake-diagnostic-functions 
flymake-diagnostic-functions)
+    (setq-local flymake-diagnostic-functions '(czm-tex-compile-flymake t))
     (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)
+  "Kill the LaTeX compilation process associated with the buffer.
+Also kill the timer for watching the log file."
+  (when (process-live-p czm-tex-compile--process)
+    (interrupt-process czm-tex-compile--process)
     (sit-for 0.1)
-    (delete-process czm-tex-compile-process))
+    (delete-process czm-tex-compile--process))
   (when (get-buffer czm-tex-compile--compilation-buffer-name)
-    (kill-buffer czm-tex-compile--compilation-buffer-name)))
+    (kill-buffer czm-tex-compile--compilation-buffer-name))
+  (when czm-tex-compile--log-watch-timer
+    (cancel-timer czm-tex-compile--log-watch-timer)
+    (setq czm-tex-compile--log-watch-timer nil)))
 
 (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."
+  "Process log file for current LaTeX document.
+Returns a list of triples (ERROR-P DESCRIPTION REGION), where
+ERROR-P is non-nil if the error is an error rather than a
+warning, DESCRIPTION is what you'd expect, and REGION is a cons
+cell (BEG . END) indicating where the error happens."
   (let* ((current-buf (current-buffer))
          (tex-file (buffer-file-name))
                (log-file (concat (file-name-sans-extension tex-file)
@@ -152,7 +159,8 @@
                      (lambda (item)
                        (let* ((error-p (eq (nth 0 item)
                                            'error))
-                              (description-raw (nth (if error-p 3 5) item))
+                              (description-raw (nth (if error-p 3 5)
+                                                    item))
                               (description (if error-p description-raw
                                              (substring description-raw
                                                         0
@@ -198,23 +206,8 @@
                      filtered)))
         stuff))))
 
-(defun czm-tex-compile--fresh-p ()
-  "Return non-nil if logged errors should apply to current buffer.
-This is the case if the current buffer is not modified, the
-current buffer is a file, the current buffer has a log file, and
-the log file is newer than the current buffer."
-  (when-let* ((file (buffer-file-name))
-              (log-file (concat (file-name-sans-extension file)
-                                ".log")))
-    (and
-     (not (buffer-modified-p))
-     (file-exists-p file)
-     (file-exists-p log-file)
-     (time-less-p (nth 5 (file-attributes file))
-                  (nth 5 (file-attributes log-file))))))
-
 (defun czm-tex-compile-report (report-fn)
-  "Call REPORT-FN if the current buffer is fresh."
+  "Report errors from log file to flymake backend REPORT-FN."
   (let* ((log-data (czm-tex-compile-process-log))
          (diags (mapcar
                  (lambda (datum)
@@ -232,59 +225,43 @@ the log file is newer than the current buffer."
     (funcall report-fn diags)
     t))
 
+(defconst czm-tex-compile--watching-str "=== Watching for updated files. Use 
ctrl/C to stop ..."
+  "String indicating that latexmk is watching for updated files.")
+
+(defun czm-tex-compile--fresh-p ()
+  "Return non-nil if logged errors should apply to current buffer.
+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 in a \"Watching\" state."
+  (when-let* ((file (buffer-file-name))
+              (log-file (concat (file-name-sans-extension file)
+                                ".log")))
+    (and
+     (when-let ((buf (get-buffer czm-tex-compile--compilation-buffer-name)))
+       (with-current-buffer buf
+         (goto-char (point-max))
+         (forward-line -1)
+         (equal (buffer-substring (point) (line-end-position))
+                czm-tex-compile--watching-str)))
+     (not (buffer-modified-p))
+     (file-exists-p file)
+     (file-exists-p log-file)
+     (time-less-p (nth 5 (file-attributes file))
+                  (nth 5 (file-attributes log-file))))))
+
 (defun czm-tex-compile-report-if-fresh ()
   "Call REPORT-FN if the current buffer is fresh."
-  (when (and czm-tex-compile-report-fn
+  (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))
-
-(defun czm-tex-compile-log-change-handler (event)
-  "Handle EVENT from log watcher.
-If EVENT is `changed', then run `czm-tex-compile-log-timer-fn'
-one second from now, so that the log has enough time to fully
-update."
-  (when (eq (nth 1 event)
-            'changed)
-    (when czm-tex-compile-log-watch-timer
-      (cancel-timer czm-tex-compile-log-watch-timer))
-    (setq czm-tex-compile-log-watch-timer
-          (run-with-timer 1 1 #'czm-tex-compile-log-timer-fn))))
-
-(require 'filenotify)
+    (czm-tex-compile-report czm-tex-compile--report-fn)))
 
 (defun czm-tex-compile-flymake (report-fn &rest _args)
   "Flymake backend for LaTeX based on latexmk.
-REPORT-FN is the function called to report diagnostics.
-ARGS are the keyword-value pairs concerning edits"
+Save REPORT-FN in a local variable, called by
+`czm-tex-compile--log-watch-timer' to report diagnostics."
   (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-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-local flymake-diagnostic-functions '(czm-tex-compile-flymake 
LaTeX-flymake t)))
-
-
+    (setq czm-tex-compile--report-fn report-fn)))
 
 (provide 'czm-tex-compile)
 ;;; czm-tex-compile.el ends here

Reply via email to