aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-28 06:42:00 -0400
committerCraig Jennings <c@cjennings.net>2026-06-28 06:42:00 -0400
commit16be44154cf823332332d1df995ae1ed50ff43c4 (patch)
tree8f4b7fc73ae061fe67dfec2141ed0d0992937a0b
parentda7ee0841924dfbd91c9a944e0bfeff6903bd8a1 (diff)
downloademacs-wttrin-16be44154cf823332332d1df995ae1ed50ff43c4.tar.gz
emacs-wttrin-16be44154cf823332332d1df995ae1ed50ff43c4.zip
fix: don't auto-fit the loading placeholder to a huge font
With auto-fit on, the one-line "Loading..." placeholder was sized to fill the window height (capped huge), and a reused buffer kept the previous weather's auto-fitted font while loading. Auto-fit now runs only once real weather has rendered, and the placeholder resets to the base font.
-rw-r--r--tests/test-wttrin--update-layout.el39
-rw-r--r--wttrin.el29
2 files changed, 67 insertions, 1 deletions
diff --git a/tests/test-wttrin--update-layout.el b/tests/test-wttrin--update-layout.el
new file mode 100644
index 0000000..b8df665
--- /dev/null
+++ b/tests/test-wttrin--update-layout.el
@@ -0,0 +1,39 @@
+;;; test-wttrin--update-layout.el --- Auto-fit gating -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2024-2026 Craig Jennings
+
+;;; Commentary:
+;; Auto-fit must not size the transient "Loading..." placeholder to fill the
+;; window; it runs only once real weather has rendered.
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+(require 'wttrin)
+(require 'testutil-wttrin)
+
+(ert-deftest test-wttrin--update-layout-error-skips-fit-on-placeholder ()
+ "Error: with auto-fit on, the loading placeholder (weather not rendered) is
+not auto-fitted; the fit runs only after weather renders."
+ (let ((buf (get-buffer-create "*wttrin-layout-test*"))
+ (fit-calls 0))
+ (unwind-protect
+ (save-window-excursion
+ (cl-letf (((symbol-function 'wttrin--apply-fit-font)
+ (lambda (&rest _) (setq fit-calls (1+ fit-calls))))
+ ((symbol-function 'wttrin--center-buffer) #'ignore))
+ (with-current-buffer buf (insert "Loading..."))
+ (set-window-buffer (selected-window) buf)
+ (with-current-buffer buf
+ (let ((wttrin-auto-fit-font t))
+ (setq-local wttrin--weather-rendered nil)
+ (wttrin--update-layout)
+ (should (= 0 fit-calls))
+ (setq-local wttrin--weather-rendered t)
+ (wttrin--update-layout)
+ (should (= 1 fit-calls))))))
+ (kill-buffer buf))))
+
+(provide 'test-wttrin--update-layout)
+;;; test-wttrin--update-layout.el ends here
diff --git a/wttrin.el b/wttrin.el
index c0359d9..ef83b45 100644
--- a/wttrin.el
+++ b/wttrin.el
@@ -927,6 +927,11 @@ When NAME is the favorite, it is left as a literal query with a warning."
(defvar-local wttrin--current-font-height nil
"The font height (1/10 pt) currently applied via `wttrin--face-remap-cookie'.")
+(defvar-local wttrin--weather-rendered nil
+ "Non-nil once real weather has rendered in this buffer.
+Auto-fit keys on this so the transient \"Loading...\" placeholder is not sized
+to fill the window.")
+
(define-derived-mode wttrin-mode special-mode "Wttrin"
"Major mode for displaying wttr.in weather information.
@@ -1148,13 +1153,28 @@ height is unchanged."
:height height))
(setq wttrin--current-font-height height))))
+(defun wttrin--reset-font-height ()
+ "Re-apply the base `wttrin-font-height', discarding any auto-fit remap.
+Used for the loading placeholder so it shows at the base size rather than the
+previous weather's auto-fitted (possibly capped) height. No-op when the buffer
+has no remap cookie yet."
+ (when wttrin--face-remap-cookie
+ (face-remap-remove-relative wttrin--face-remap-cookie)
+ (setq wttrin--face-remap-cookie
+ (face-remap-add-relative 'default
+ :family wttrin-font-name
+ :height wttrin-font-height))
+ (setq wttrin--current-font-height wttrin-font-height)))
+
(defun wttrin--update-layout (&rest _)
"Auto-fit the font (when enabled), then center the block in the buffer's window.
+Auto-fit runs only once real weather has rendered (`wttrin--weather-rendered'),
+so the one-line \"Loading...\" placeholder is not sized to fill the window.
Accepts and ignores hook arguments, so it is safe on
`window-configuration-change-hook'. No-op when the buffer has no window."
(let ((win (get-buffer-window (current-buffer))))
(when win
- (when wttrin-auto-fit-font
+ (when (and wttrin-auto-fit-font wttrin--weather-rendered)
(wttrin--apply-fit-font win))
(wttrin--center-buffer win))))
@@ -1207,6 +1227,9 @@ coordinates but can name the place)."
(wttrin--add-buffer-instructions)
(goto-char (point-min)))
+ ;; Real weather is now in the buffer, so auto-fit may size to it.
+ (setq-local wttrin--weather-rendered t)
+
;; Anchor the window to the top. Point is at point-min, but when the
;; buffer is taller than the window a reused window can keep an old
;; mid-buffer window-start, hiding the weather above the fold.
@@ -1240,6 +1263,10 @@ coordinates from a geolocation command."
(insert "Loading weather for " (or display query) "...")
(setq buffer-read-only t)
(setq-local wttrin--current-request-id request-id)
+ ;; The placeholder is one line; keep auto-fit off it and show it at the base
+ ;; font rather than the previous weather's auto-fitted (possibly capped) size.
+ (setq-local wttrin--weather-rendered nil)
+ (wttrin--reset-font-height)
(wttrin--get-cached-or-fetch
query
(lambda (raw-string &optional error-msg)