aboutsummaryrefslogtreecommitdiff
path: root/modules/hugo-config.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-04-22 07:43:41 -0500
committerCraig Jennings <c@cjennings.net>2026-04-22 07:43:41 -0500
commitaa033b1ea9707dda78e9cb75dfe1b13b78db11b5 (patch)
tree16699e222053fb465947534d429ddbffdf55f0d6 /modules/hugo-config.el
parentde72468d1fe8e15354f398dc22d7469093e7ef65 (diff)
downloaddotemacs-aa033b1ea9707dda78e9cb75dfe1b13b78db11b5.tar.gz
dotemacs-aa033b1ea9707dda78e9cb75dfe1b13b78db11b5.zip
fix(hugo): defer browser until server ready, report crashes
Two gaps in cj/hugo-preview surfaced during manual testing. First, the browser opened one second after start-process returned. On any non-trivial site, Hugo takes several seconds to finish its initial build before it binds port 1313. The browser requested the page before the server existed and got ERR_CONNECTION_REFUSED. Replaced the fixed one-second run-at-time with a process filter that watches Hugo's output for "Web Server is available at" — the line Hugo prints once it has actually bound the port. The browser now opens at the right moment regardless of build time. The filter clears itself after firing so subsequent output does not re-open tabs. Second, if Hugo exited on its own (for example a template error in the theme), the preview command went silent with no indication that anything was wrong. Added a process sentinel that clears cj/hugo--preview-process on any exit and prints "hugo server crashed (exit N) — see *hugo-server* buffer" when the exit status is non-zero. User-initiated stops arrive as signal status and remain silent because cj/hugo-preview already prints its own stop message.
Diffstat (limited to 'modules/hugo-config.el')
-rw-r--r--modules/hugo-config.el43
1 files changed, 40 insertions, 3 deletions
diff --git a/modules/hugo-config.el b/modules/hugo-config.el
index 2f9f6428..1feaa452 100644
--- a/modules/hugo-config.el
+++ b/modules/hugo-config.el
@@ -162,9 +162,43 @@ Switches #+hugo_draft between true and false."
(defvar cj/hugo--preview-process nil
"Handle to the running hugo preview server, or nil.")
+(defun cj/hugo--preview-filter (proc output)
+ "Process filter for the hugo preview server.
+Appends OUTPUT to PROC's buffer and opens the browser the first time
+Hugo reports the server is ready. Hugo prints a line containing
+\"Web Server is available at\" once it has bound the port, so waiting
+for that string is more reliable than a fixed delay."
+ (when (buffer-live-p (process-buffer proc))
+ (with-current-buffer (process-buffer proc)
+ (let ((moving (= (point) (process-mark proc))))
+ (save-excursion
+ (goto-char (process-mark proc))
+ (insert output)
+ (set-marker (process-mark proc) (point)))
+ (when moving (goto-char (process-mark proc))))))
+ (when (and (process-live-p proc)
+ (string-match-p "Web Server is available at" output))
+ (browse-url "http://localhost:1313/")
+ (set-process-filter proc nil)))
+
+(defun cj/hugo--preview-sentinel (proc _event)
+ "Sentinel for the hugo preview server.
+Clears `cj/hugo--preview-process' on any exit and announces crashes.
+User-initiated stops arrive with status `signal' and are silent here
+because `cj/hugo-preview' already prints its own stop message."
+ (when (memq (process-status proc) '(exit signal))
+ (setq cj/hugo--preview-process nil)
+ (when (and (eq (process-status proc) 'exit)
+ (not (zerop (process-exit-status proc))))
+ (message "hugo server crashed (exit %d) — see *hugo-server* buffer"
+ (process-exit-status proc)))))
+
(defun cj/hugo-preview ()
"Toggle the `hugo server' preview.
-Start the server and open the browser if stopped; stop it if running."
+Start the server and open the browser if stopped; stop it if running.
+The browser opens only once Hugo has finished its initial build and is
+actually listening on the port. If Hugo exits on its own (for example
+a template error), the sentinel reports the failure."
(interactive)
(if (process-live-p cj/hugo--preview-process)
(progn
@@ -176,8 +210,11 @@ Start the server and open the browser if stopped; stop it if running."
(start-process "hugo-server" "*hugo-server*"
"hugo" "server" "-D"
"--noHTTPCache" "--disableFastRender"))
- (run-at-time "1 sec" nil #'browse-url "http://localhost:1313/")
- (message "hugo server starting — C-; h p again to stop"))))
+ (set-process-filter cj/hugo--preview-process
+ #'cj/hugo--preview-filter)
+ (set-process-sentinel cj/hugo--preview-process
+ #'cj/hugo--preview-sentinel)
+ (message "hugo server starting — browser will open when ready"))))
(declare-function magit-status-setup-buffer "magit-status")