aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-09 18:02:14 -0500
committerCraig Jennings <c@cjennings.net>2026-07-09 18:02:14 -0500
commit23374dbaf6648af773c0a6fee5514c364e24de31 (patch)
treef5bb931527b25d04fe074aabe65d4f151b51a857
parent0f3d168cbf97886ed5ddc187ca66d42ce3a50936 (diff)
downloaddotemacs-23374dbaf6648af773c0a6fee5514c364e24de31.tar.gz
dotemacs-23374dbaf6648af773c0a6fee5514c364e24de31.zip
feat(music): always dock the playlist at the bottom
The F10 playlist docked as a right-side column when the frame was wide enough, splitting the frame three ways. That's annoying and often unexpected, so the frame's shape no longer decides where the playlist goes. I deleted the chooser (cj/--music-playlist-side) and the right-dock width knobs rather than leaving them wired to nothing, and a test asserts they're gone. cj/preferred-dock-direction stays, since ai-term and eat still dock by frame shape. The old side-chooser test is replaced by one that stubs cj/side-window-display and asserts what the toggle asks for, so it runs headless.
-rw-r--r--modules/music-config.el58
-rw-r--r--tests/test-music-config--playlist-dock.el74
-rw-r--r--tests/test-music-config--playlist-side.el45
3 files changed, 87 insertions, 90 deletions
diff --git a/modules/music-config.el b/modules/music-config.el
index 7e3b9d0f..3559930b 100644
--- a/modules/music-config.el
+++ b/modules/music-config.el
@@ -30,7 +30,6 @@
(require 'subr-x)
(require 'user-constants)
(require 'keybindings) ;; provides cj/custom-keymap
-(require 'cj-window-geometry-lib) ;; cj/preferred-dock-direction (F10 dock side)
(require 'cj-window-toggle-lib) ;; side-window size memory (F10 toggle)
(require 'system-lib) ;; cj/confirm-strong (overwrite confirms)
@@ -778,40 +777,22 @@ Intended for use on `emms-player-finished-hook'."
(defvar cj/music-playlist-window-height 0.3
"Default fraction of frame height for the F10 music playlist side window.
-Used when the playlist docks at the bottom and hasn't been resized and
-toggled off this session; after that, the toggled-off height is remembered
-in `cj/--music-playlist-height'.")
-
-(defvar cj/music-playlist-window-width 0.4
- "Default fraction of frame width for the F10 music playlist side window.
-Used when the playlist docks as a right-side column (see
-`cj/--music-playlist-side') and hasn't been resized this session; after
-that the toggled-off width is remembered in `cj/--music-playlist-width'.")
+Used when the playlist hasn't been resized and toggled off this session;
+after that, the toggled-off height is remembered in
+`cj/--music-playlist-height'.")
(defvar cj/--music-playlist-height nil
- "Last height fraction the playlist was toggled off at while docked bottom.
+ "Last height fraction the playlist was toggled off at.
nil means fall back to `cj/music-playlist-window-height'. In-memory only --
resets each Emacs session.")
-(defvar cj/--music-playlist-width nil
- "Last width fraction the playlist was toggled off at while docked right.
-nil means fall back to `cj/music-playlist-window-width'. In-memory only --
-resets each Emacs session.")
-
-(defun cj/--music-playlist-side ()
- "Return the side the F10 playlist should dock on: `right' or `bottom'.
-Docks as a right-side column only when a side-by-side split would leave
-both panes at least `cj/window-dock-min-columns' wide (the playlist's
-share is `cj/music-playlist-window-width'); otherwise docks at the bottom.
-See `cj/preferred-dock-direction'."
- (if (eq (cj/preferred-dock-direction (frame-width)
- cj/music-playlist-window-width)
- 'right)
- 'right
- 'bottom))
-
(defun cj/music-playlist-toggle ()
"Toggle the EMMS playlist buffer in a bottom side window.
+The playlist always docks at the bottom, whatever the frame's shape. It
+used to dock as a right-side column on a wide frame (via
+`cj/preferred-dock-direction'), which split a wide frame three ways --
+unexpected often enough that Craig retired the rule (2026-07-09).
+
The window opens at `cj/music-playlist-window-height'; if it has been
resized and toggled off this session, it reopens at that remembered height."
(interactive)
@@ -820,28 +801,15 @@ resized and toggled off this session, it reopens at that remembered height."
(win (and buffer (get-buffer-window buffer))))
(if win
(progn
- ;; Capture the resized size into the var matching the window's
- ;; actual side, so width and height memories stay independent.
- ;; Guard the parameter lookup: a dead or non-window WIN (the
- ;; capture helpers tolerate one) must not error here.
- (let ((side (if (window-live-p win)
- (or (window-parameter win 'window-side) 'bottom)
- 'bottom)))
- (if (memq side '(left right))
- (cj/side-window-capture-size win side 'cj/--music-playlist-width)
- (cj/side-window-capture-size win 'bottom 'cj/--music-playlist-height)))
+ (cj/side-window-capture-size win 'bottom 'cj/--music-playlist-height)
(delete-window win)
(message "Playlist window closed"))
(progn
(cj/emms--setup)
(setq buffer (cj/music--ensure-playlist-buffer))
- (let* ((side (cj/--music-playlist-side))
- (right (eq side 'right)))
- (setq win (cj/side-window-display
- buffer side
- (if right 'cj/--music-playlist-width 'cj/--music-playlist-height)
- (if right cj/music-playlist-window-width
- cj/music-playlist-window-height))))
+ (setq win (cj/side-window-display
+ buffer 'bottom 'cj/--music-playlist-height
+ cj/music-playlist-window-height))
(select-window win)
(with-current-buffer buffer
(if (and (fboundp 'emms-playlist-current-selected-track)
diff --git a/tests/test-music-config--playlist-dock.el b/tests/test-music-config--playlist-dock.el
new file mode 100644
index 00000000..69d24cc3
--- /dev/null
+++ b/tests/test-music-config--playlist-dock.el
@@ -0,0 +1,74 @@
+;;; test-music-config--playlist-dock.el --- Tests for the F10 playlist dock -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; The F10 playlist always docks at the bottom, whatever the frame's shape.
+;; It used to pick `right' on a wide frame via `cj/preferred-dock-direction',
+;; which produced an unwanted three-way split on a wide terminal.
+;;
+;; `cj/side-window-display' is the window-system boundary here, so it is the
+;; thing stubbed (an ordinary defun -- safe to `cl-letf', unlike the frame-*
+;; subrs). Stubbing it lets these tests assert what the toggle *asks for*
+;; without needing a live frame under `--batch'.
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+(require 'music-config)
+
+(defmacro test-music-dock--with-captured-side (captured &rest body)
+ "Run BODY with the playlist display path stubbed, recording its args in CAPTURED.
+CAPTURED is set to a plist of :side, :size-var and :default-size."
+ (declare (indent 1))
+ `(let ((buffer (generate-new-buffer " *test-playlist*")))
+ (unwind-protect
+ (cl-letf (((symbol-function 'cj/emms--setup) (lambda (&rest _) nil))
+ ((symbol-function 'cj/music--ensure-playlist-buffer)
+ (lambda (&rest _) buffer))
+ ((symbol-function 'emms-playlist-mode-center-current)
+ (lambda (&rest _) nil))
+ ((symbol-function 'cj/side-window-display)
+ (lambda (_buf side size-var default-size)
+ (setq ,captured (list :side side :size-var size-var
+ :default-size default-size))
+ (selected-window))))
+ ,@body)
+ (kill-buffer buffer))))
+
+(ert-deftest test-music-config-playlist-toggle-docks-bottom-on-wide-frame ()
+ "Normal: a wide frame still docks the playlist at the bottom.
+A wide frame used to dock right, splitting the frame three ways."
+ (let (captured)
+ (test-music-dock--with-captured-side captured
+ (cl-letf (((symbol-function 'frame-width) (lambda (&rest _) 400)))
+ (cj/music-playlist-toggle)))
+ (should (eq 'bottom (plist-get captured :side)))))
+
+(ert-deftest test-music-config-playlist-toggle-docks-bottom-on-narrow-frame ()
+ "Boundary: a narrow frame docks at the bottom, as it always did."
+ (let (captured)
+ (test-music-dock--with-captured-side captured
+ (cl-letf (((symbol-function 'frame-width) (lambda (&rest _) 40)))
+ (cj/music-playlist-toggle)))
+ (should (eq 'bottom (plist-get captured :side)))))
+
+(ert-deftest test-music-config-playlist-toggle-uses-height-memory ()
+ "Normal: the bottom dock carries the height fraction and its memory var."
+ (let (captured)
+ (test-music-dock--with-captured-side captured
+ (cj/music-playlist-toggle))
+ (should (eq 'cj/--music-playlist-height (plist-get captured :size-var)))
+ (should (= cj/music-playlist-window-height (plist-get captured :default-size)))))
+
+(ert-deftest test-music-config-playlist-dock-has-no-width-knobs ()
+ "Error: the right-dock width variables are gone, not merely unused.
+A stale `cj/music-playlist-window-width' would read as a live knob that
+silently does nothing."
+ (should-not (boundp 'cj/music-playlist-window-width))
+ (should-not (boundp 'cj/--music-playlist-width))
+ (should-not (fboundp 'cj/--music-playlist-side)))
+
+(provide 'test-music-config--playlist-dock)
+;;; test-music-config--playlist-dock.el ends here
diff --git a/tests/test-music-config--playlist-side.el b/tests/test-music-config--playlist-side.el
deleted file mode 100644
index f4969469..00000000
--- a/tests/test-music-config--playlist-side.el
+++ /dev/null
@@ -1,45 +0,0 @@
-;;; test-music-config--playlist-side.el --- Tests for the F10 dock-side helper -*- lexical-binding: t; -*-
-
-;;; Commentary:
-;; `cj/--music-playlist-side' maps the shared dock rule's verdict to a
-;; `display-buffer-in-side-window' side: `right' stays `right', anything
-;; else becomes `bottom'. The decision itself lives in
-;; `cj/preferred-dock-direction' (tested in test-cj-window-geometry-lib.el);
-;; here we stub it (an ordinary defun -- safe to `cl-letf', unlike the
-;; frame-* subrs) to prove the mapping and that the width fraction is
-;; passed through.
-
-;;; Code:
-
-(require 'ert)
-(require 'cl-lib)
-
-(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
-(require 'music-config)
-
-(ert-deftest test-music-config--playlist-side-right-verdict-is-right ()
- "Normal: a `right' verdict from the dock rule docks the playlist right."
- (cl-letf (((symbol-function 'cj/preferred-dock-direction)
- (lambda (&rest _) 'right)))
- (should (eq (cj/--music-playlist-side) 'right))))
-
-(ert-deftest test-music-config--playlist-side-below-verdict-is-bottom ()
- "Normal: a `below' verdict maps to the `bottom' side window."
- (cl-letf (((symbol-function 'cj/preferred-dock-direction)
- (lambda (&rest _) 'below)))
- (should (eq (cj/--music-playlist-side) 'bottom))))
-
-(ert-deftest test-music-config--playlist-side-passes-width-fraction ()
- "Normal: the playlist's width fraction reaches the dock rule."
- (let ((cj/music-playlist-window-width 0.4)
- captured)
- (cl-letf (((symbol-function 'cj/preferred-dock-direction)
- (lambda (cols frac &rest _)
- (setq captured (list cols frac))
- 'below)))
- (cj/--music-playlist-side)
- (should (= (nth 1 captured) 0.4))
- (should (integerp (nth 0 captured))))))
-
-(provide 'test-music-config--playlist-side)
-;;; test-music-config--playlist-side.el ends here