diff options
| author | Craig Jennings <c@cjennings.net> | 2026-07-02 00:08:33 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-07-02 00:08:33 -0400 |
| commit | 821ec1e4d5f5e64ed54972960589ca5c8c41b9f9 (patch) | |
| tree | dad5e9b67a8f059b962d7070f42244f8d095a42f | |
| parent | 622a4d8c13a5037e064cf9caa3e917100f7f5cc9 (diff) | |
| download | dotemacs-821ec1e4d5f5e64ed54972960589ca5c8c41b9f9.tar.gz dotemacs-821ec1e4d5f5e64ed54972960589ca5c8c41b9f9.zip | |
feat(markdown): start the preview server from F2 when it's down
cj/markdown-preview now brings up the simple-httpd listener itself instead of signaling a user-error pointing at cj/markdown-preview-server-start. The two-command flow guarded against a surprise network listener, but the preview is the only reason the listener exists, so the guard was just an extra step. I kept the start command for manual use.
| -rw-r--r-- | modules/markdown-config.el | 18 | ||||
| -rw-r--r-- | tests/test-markdown-config-preview-autostart.el | 52 | ||||
| -rw-r--r-- | tests/test-markdown-config.el | 36 |
3 files changed, 93 insertions, 13 deletions
diff --git a/modules/markdown-config.el b/modules/markdown-config.el index cb37556f..d2cd7f86 100644 --- a/modules/markdown-config.el +++ b/modules/markdown-config.el @@ -40,6 +40,8 @@ ;;;; --------------------- WIP: Markdown-Preview --------------------- (declare-function imp--notify-clients "impatient-mode") +(declare-function httpd-running-p "simple-httpd") +(declare-function httpd-start "simple-httpd") (defun cj/markdown-preview-server-start () "Start the simple-httpd listener that serves the live markdown preview. @@ -49,16 +51,20 @@ Idempotent: re-running while the server is already up is a no-op." (httpd-start) (message "markdown preview server running on http://localhost:8080/imp")) +(defun cj/--markdown-preview-ensure-server () + "Start the markdown preview server unless it's already running." + (require 'simple-httpd) + (unless (httpd-running-p) + (cj/markdown-preview-server-start))) + ;; the filter to apply to markdown before impatient-mode pushes it to the server (defun cj/markdown-preview () "Open the current buffer as a live HTML preview at http://localhost:8080/imp. -The simple-httpd listener must already be running -- see -`cj/markdown-preview-server-start'. Starting a network listener as a -side effect of opening a preview is surprising, so the server start -lives in a separate command." +Starts the simple-httpd listener itself when it isn't already running +\(per the 2026-07-01 decision; the earlier separate-start design +signaled a `user-error' instead)." (interactive) - (unless (httpd-running-p) - (user-error "markdown preview server not running; run `M-x cj/markdown-preview-server-start' first")) + (cj/--markdown-preview-ensure-server) (impatient-mode 1) (setq imp-user-filter #'cj/markdown-html) (cl-incf imp-last-state) diff --git a/tests/test-markdown-config-preview-autostart.el b/tests/test-markdown-config-preview-autostart.el new file mode 100644 index 00000000..247c75d7 --- /dev/null +++ b/tests/test-markdown-config-preview-autostart.el @@ -0,0 +1,52 @@ +;;; test-markdown-config-preview-autostart.el --- preview server autostart -*- lexical-binding: t; -*- + +;;; Commentary: +;; Tests for `cj/--markdown-preview-ensure-server': F2 preview starts the +;; simple-httpd listener itself when it isn't running (per the 2026-07-01 +;; cj comment), and leaves a running server alone. simple-httpd isn't +;; installed in batch, so the tests provide a stub feature with the two +;; functions the helper touches. + +;;; Code: + +(require 'ert) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) + +(require 'markdown-config) + +;; Stand in for the elpa package: `require' in the helper becomes a +;; no-op. Tests mock httpd-running-p explicitly (works whether the +;; real simple-httpd or this stub is loaded), so the stub bodies never +;; matter. +(require 'cl-lib) +(unless (featurep 'simple-httpd) + (defun httpd-running-p () nil) + (defun httpd-start () nil) + (provide 'simple-httpd)) + +(ert-deftest test-markdown-config-ensure-server-starts-when-down () + "Normal: a stopped server gets started." + (let ((started nil)) + (cl-letf (((symbol-function 'httpd-running-p) (lambda () nil)) + ((symbol-function 'cj/markdown-preview-server-start) + (lambda () (setq started t)))) + (cj/--markdown-preview-ensure-server) + (should started)))) + +(ert-deftest test-markdown-config-ensure-server-noop-when-running () + "Boundary: a running server is left alone." + (let ((started nil)) + (cl-letf (((symbol-function 'httpd-running-p) (lambda () t)) + ((symbol-function 'cj/markdown-preview-server-start) + (lambda () (setq started t)))) + (cj/--markdown-preview-ensure-server) + (should-not started)))) + +(ert-deftest test-markdown-config-preview-no-longer-signals-user-error () + "Error-path regression: the old user-error on a stopped server is gone." + (should-not (string-match-p "user-error" + (format "%S" (symbol-function 'cj/markdown-preview))))) + +(provide 'test-markdown-config-preview-autostart) +;;; test-markdown-config-preview-autostart.el ends here diff --git a/tests/test-markdown-config.el b/tests/test-markdown-config.el index e079a8b4..ed3543bb 100644 --- a/tests/test-markdown-config.el +++ b/tests/test-markdown-config.el @@ -18,6 +18,14 @@ (require 'org) (require 'markdown-config) +;; simple-httpd (elpa) is absent under `make test'; stand in for it so +;; the preview path's (require 'simple-httpd) stays a no-op. Tests mock +;; httpd-running-p explicitly, so the stub bodies never matter. +(unless (featurep 'simple-httpd) + (defun httpd-running-p () nil) + (defun httpd-start () nil) + (provide 'simple-httpd)) + (ert-deftest test-markdown-config-registers-markdown-org-src-lang () "Normal: `markdown' shows up in `org-src-lang-modes' mapped to `markdown' so org-lint stops warning on `#+begin_src markdown' and @@ -70,14 +78,28 @@ plain HTTP." (should (string-match-p "<xmp" (buffer-string)))) (kill-buffer src)))) -;;; cj/markdown-preview (guard: refuse when the httpd listener is down) +;;; cj/markdown-preview (autostart: bring the httpd listener up when down) + +(defvar imp-user-filter) +(defvar imp-last-state) -(ert-deftest test-markdown-preview-errors-when-server-down () - "Error: `cj/markdown-preview' signals a user-error when the simple-httpd -listener is not running, rather than opening a preview against a dead server. -Also pins the rename off the bare `markdown-preview' that markdown-mode shadows." - (cl-letf (((symbol-function 'httpd-running-p) (lambda () nil))) - (should-error (cj/markdown-preview) :type 'user-error))) +(ert-deftest test-markdown-preview-starts-server-when-down () + "Normal: `cj/markdown-preview' starts the httpd listener when it's down +\(the 2026-07-01 autostart decision replaced the old user-error guard). +Also pins the rename off the bare `markdown-preview' that markdown-mode +shadows. Everything downstream is mocked so no listener or browser runs." + (let ((started nil) + (imp-user-filter nil) + (imp-last-state 0)) + (cl-letf (((symbol-function 'httpd-running-p) (lambda () nil)) + ((symbol-function 'cj/markdown-preview-server-start) + (lambda () (setq started t))) + ((symbol-function 'impatient-mode) (lambda (&rest _) nil)) + ((symbol-function 'imp--notify-clients) (lambda (&rest _) nil)) + ((symbol-function 'browse-url) (lambda (&rest _) nil))) + (with-temp-buffer + (cj/markdown-preview)) + (should started)))) (provide 'test-markdown-config) ;;; test-markdown-config.el ends here |
