diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-10 13:15:48 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-10 13:15:48 -0500 |
| commit | f2c45a7146568bea7eea12270688c8c8ed814c86 (patch) | |
| tree | 866d32ca0484dea1d9414184988e2ae617ed0e16 | |
| parent | 5eccbf7bd3c9780eee6170839dbf3224a32e9ef3 (diff) | |
| download | dotemacs-f2c45a7146568bea7eea12270688c8c8ed814c86.tar.gz dotemacs-f2c45a7146568bea7eea12270688c8c8ed814c86.zip | |
fix(dirvish): rename pw -> wp to clear quick-access key collision
Pressing `g' in dirvish (`dirvish-quick-access') failed with `Wrong type argument: command, (keymap (107 . transient:dirvish-quick-access::N))'. Transient auto-groups multi-character keys into nested prefix keymaps; when one entry's KEY is also the prefix of a longer entry's KEY, the shorter slot resolves to the auto-generated sub-prefix keymap rather than to the intended leaf command. The "wallpaper" entry on `pw' and the "project work" entry on `pwk' (added in 4ece1eb) collided. Rename `pw' to `wp'; `pwk' is now the only entry under the `pw'-prefix, so transient builds a clean leaf.
Add `tests/test-dirvish-config-quick-access.el' with five tests: four cover a small `test-dirvish-config--key-collisions' helper against synthetic inputs (collision detected, clean list, empty, single-entry), and one regression test asserts the live `dirvish-quick-access-entries' contains no shorter-key-is-prefix-of-longer-key pair.
| -rw-r--r-- | modules/dirvish-config.el | 2 | ||||
| -rw-r--r-- | tests/test-dirvish-config-quick-access.el | 80 |
2 files changed, 81 insertions, 1 deletions
diff --git a/modules/dirvish-config.el b/modules/dirvish-config.el index 5f30ba10..fadf09ca 100644 --- a/modules/dirvish-config.el +++ b/modules/dirvish-config.el @@ -268,8 +268,8 @@ Uses feh on X11, swww on Wayland." ("pk" "~/projects/kit/" "project kit") ("pn" "~/projects/nextjob/" "project nextjob") ("ps" ,(concat pix-dir "/screenshots/") "pictures screenshots") - ("pw" ,(concat pix-dir "/wallpaper/") "pictures wallpaper") ("px" ,pix-dir "pictures directory") + ("wp" ,(concat pix-dir "/wallpaper/") "pictures wallpaper") ("rcj" "/sshx:cjennings@cjennings.net:~" "remote c@cjennings.net") ("rtl" "/sshx:cjennings@truenas.local:~" "remote cjennings@truenas.local") ("rtt" "/sshx:cjennings@truenas:~" "remote cjennings@truenas (tailscale)") diff --git a/tests/test-dirvish-config-quick-access.el b/tests/test-dirvish-config-quick-access.el new file mode 100644 index 00000000..46f9b163 --- /dev/null +++ b/tests/test-dirvish-config-quick-access.el @@ -0,0 +1,80 @@ +;;; test-dirvish-config-quick-access.el --- Regression for quick-access key shape -*- lexical-binding: t; -*- + +;;; Commentary: +;; `dirvish-quick-access' uses transient under the hood. Entries are a list +;; of (KEY PATH DOC) cells, and transient auto-groups multi-character keys +;; into nested prefix keymaps. When one entry's KEY is also the prefix of a +;; longer entry's KEY (e.g. "pw" as a leaf and "pwk" as a deeper key), the +;; transient build falls over: the shorter-key slot resolves to the auto- +;; generated sub-prefix keymap rather than to the intended leaf command. +;; Pressing the dirvish `g' binding then raises: +;; +;; Wrong type argument: command, (keymap (107 . transient:...::N)), command +;; +;; That happened on 2026-05-10 after the `pcr' -> `pwk' rename in commit +;; 4ece1eb made `pw' (wallpaper, leaf) collide with `pwk' (project work). +;; This test guards against any future occurrence by walking the entries +;; list and asserting that no key is a prefix of any other key. + +;;; Code: + +(require 'ert) +(require 'cl-lib) +(require 'package) + +(setq package-user-dir (expand-file-name "elpa" user-emacs-directory)) +(package-initialize) +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(add-to-list 'load-path (expand-file-name "elpa/dirvish-2.3.0/extensions" + user-emacs-directory)) +(require 'user-constants) +(require 'keybindings) +(require 'dirvish-config) + +(defun test-dirvish-config--key-collisions (entries) + "Return a list of (SHORTER . LONGER) pairs where SHORTER is a prefix of LONGER. +ENTRIES is the same shape as `dirvish-quick-access-entries' -- a list of +(KEY PATH DOC) cells." + (let ((keys (mapcar #'car entries)) + collisions) + (dolist (a keys) + (dolist (b keys) + (when (and (not (string= a b)) + (string-prefix-p a b)) + (push (cons a b) collisions)))) + collisions)) + +(ert-deftest test-dirvish-config--key-collisions-detects-prefix-of-leaf () + "Normal: a leaf KEY that prefixes a longer KEY is reported as a collision." + (let ((entries '(("pw" "/wallpaper" "wallpaper") + ("pwk" "/work" "project work") + ("h" "~/" "home")))) + (should (member '("pw" . "pwk") + (test-dirvish-config--key-collisions entries))))) + +(ert-deftest test-dirvish-config--key-collisions-clean-list-empty () + "Boundary: a list with no overlapping prefixes returns no collisions." + (let ((entries '(("h" "~/" "home") + ("dx" "/dx" "documents") + ("dl" "/dl" "downloads") + ("pwk" "/wk" "project work") + ("wp" "/wp" "wallpaper")))) + (should-not (test-dirvish-config--key-collisions entries)))) + +(ert-deftest test-dirvish-config--key-collisions-empty-list-empty () + "Boundary: an empty entries list has no collisions." + (should-not (test-dirvish-config--key-collisions '()))) + +(ert-deftest test-dirvish-config--key-collisions-single-entry-empty () + "Boundary: a single-entry list has no collisions." + (should-not (test-dirvish-config--key-collisions + '(("h" "~/" "home"))))) + +(ert-deftest test-dirvish-config-quick-access-entries-have-no-collisions () + "Regression: the live `dirvish-quick-access-entries' list contains no key +that is a prefix of another key. See commentary for why this matters." + (should-not (test-dirvish-config--key-collisions + dirvish-quick-access-entries))) + +(provide 'test-dirvish-config-quick-access) +;;; test-dirvish-config-quick-access.el ends here |
