aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-12 10:07:09 -0500
committerCraig Jennings <c@cjennings.net>2026-06-12 10:07:09 -0500
commit4a1ecf647270e49da1a185f4d52c2553e1fedba8 (patch)
treeee521ff355f9349e032eb22c55f4f386ffa0bc5d
parent1aef127f4bf35917829d22b18593fee64974ccb1 (diff)
downloaddotemacs-4a1ecf647270e49da1a185f4d52c2553e1fedba8.tar.gz
dotemacs-4a1ecf647270e49da1a185f4d52c2553e1fedba8.zip
fix(keys): bind eww/elfeed/calibredb launchers to the uppercase Meta event
Meta+Shift+<letter> emits the uppercase event (M-E/M-R/M-B), so the M-S-e/M-S-r/M-S-b :bind specs on lowercase letters were never reached by the keychord and the three launchers were dead. Rebind them to M-E/M-R/M-B. Three ERT tests assert each chord resolves to eww, cj/elfeed-open, and calibredb respectively.
-rw-r--r--modules/calibredb-epub-config.el2
-rw-r--r--modules/elfeed-config.el2
-rw-r--r--modules/eww-config.el2
-rw-r--r--tests/test-launcher-meta-shift-keys.el32
-rw-r--r--todo.org5
5 files changed, 38 insertions, 5 deletions
diff --git a/modules/calibredb-epub-config.el b/modules/calibredb-epub-config.el
index a17bf8c9..20262e6e 100644
--- a/modules/calibredb-epub-config.el
+++ b/modules/calibredb-epub-config.el
@@ -112,7 +112,7 @@ which re-applies `calibredb-search-filter' instead."
(use-package calibredb
:commands calibredb
:bind
- ("M-S-b" . calibredb) ;; was M-B, overrides backward-word
+ ("M-B" . calibredb) ;; Meta+Shift+b emits the uppercase event; overrides backward-word
;; use built-in filter by tag, add clear-filters
(:map calibredb-search-mode-map
("l" . calibredb-filter-by-tag)
diff --git a/modules/elfeed-config.el b/modules/elfeed-config.el
index ad7bda83..4f408915 100644
--- a/modules/elfeed-config.el
+++ b/modules/elfeed-config.el
@@ -33,7 +33,7 @@
(use-package elfeed
:bind
- ("M-S-r" . cj/elfeed-open) ;; was M-R
+ ("M-R" . cj/elfeed-open) ;; Meta+Shift+r emits the uppercase event
(:map elfeed-show-mode-map
("w" . eww-open-in-new-buffer))
(:map elfeed-search-mode-map
diff --git a/modules/eww-config.el b/modules/eww-config.el
index 066fae98..18648c1b 100644
--- a/modules/eww-config.el
+++ b/modules/eww-config.el
@@ -67,7 +67,7 @@
(use-package eww
:ensure nil ;; built-in
:bind
- (("M-S-e" . eww) ;; was M-E, overrides forward-sentence
+ (("M-E" . eww) ;; Meta+Shift+e emits the uppercase event; overrides forward-sentence
:map eww-mode-map
("<" . eww-back-url)
(">" . eww-forward-url)
diff --git a/tests/test-launcher-meta-shift-keys.el b/tests/test-launcher-meta-shift-keys.el
new file mode 100644
index 00000000..574a8d68
--- /dev/null
+++ b/tests/test-launcher-meta-shift-keys.el
@@ -0,0 +1,32 @@
+;;; test-launcher-meta-shift-keys.el --- Meta+Shift launcher keys reach their commands -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Meta+Shift+<letter> emits the uppercase event (M-E, M-R, M-B), so a
+;; binding written as "M-S-e" on a lowercase letter is never reached by
+;; the keychord. These launchers must be bound under the uppercase
+;; event the keyboard actually produces.
+
+;;; Code:
+
+(require 'ert)
+(require 'testutil-general)
+
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+(require 'eww-config)
+(require 'elfeed-config)
+(require 'calibredb-epub-config)
+
+(ert-deftest test-launcher-meta-shift-e-opens-eww ()
+ "Normal: M-E (Meta+Shift+e) is bound to `eww'."
+ (should (eq (key-binding (kbd "M-E")) 'eww)))
+
+(ert-deftest test-launcher-meta-shift-r-opens-elfeed ()
+ "Normal: M-R (Meta+Shift+r) is bound to `cj/elfeed-open'."
+ (should (eq (key-binding (kbd "M-R")) 'cj/elfeed-open)))
+
+(ert-deftest test-launcher-meta-shift-b-opens-calibredb ()
+ "Normal: M-B (Meta+Shift+b) is bound to `calibredb'."
+ (should (eq (key-binding (kbd "M-B")) 'calibredb)))
+
+(provide 'test-launcher-meta-shift-keys)
+;;; test-launcher-meta-shift-keys.el ends here
diff --git a/todo.org b/todo.org
index bc49cd73..d1c03ae6 100644
--- a/todo.org
+++ b/todo.org
@@ -852,8 +852,9 @@ From the 2026-06 config audit, =modules/dwim-shell-config.el=:
** TODO [#B] prog hooks mutate global state per buffer :bug:quick:solo:
From the 2026-06 config audit: =prog-go.el:64=, =prog-c.el:73=, =prog-shell.el:77= call global =(electric-pair-mode t)= from buffer setup hooks — one Go/C/shell buffer turns on pairing in org/text everywhere (python/webdev correctly use =electric-pair-local-mode=). =prog-general.el:79-80= — =display-line-numbers-type 'relative= setq/setq-default run from the hook AFTER the mode is enabled, so the first prog buffer of a session gets absolute numbers. Local-mode for the three; move the line-number setqs to top level.
-** TODO [#B] M-S- launcher keys dead: eww, elfeed, calibredb unreachable :bug:quick:solo:
-=eww-config.el:70= (M-S-e), =elfeed-config.el:36= (M-S-r), =calibredb-epub-config.el:115= (M-S-b) — Meta+Shift+letter generates the uppercase event (M-E/M-R/M-B), which never matches an explicit S- spec on a lowercase letter; verified dead in the live daemon (chord falls through to M-r move-to-window-line etc.). Same class as the text-config M-S-i finding. Write them as "M-E"/"M-R"/"M-B". Weather's M-S-w works only via the keyboard-compat translation layer — audit that layer's coverage while here. From the 2026-06 config audit.
+** DONE [#B] M-S- launcher keys dead: eww, elfeed, calibredb unreachable :bug:quick:solo:
+CLOSED: [2026-06-12 Fri]
+Fixed: rewrote the three =:bind= specs as =M-E= / =M-R= / =M-B= (=eww-config.el=, =elfeed-config.el=, =calibredb-epub-config.el=) so the uppercase event the keyboard actually emits is bound. 3 ERT tests in =tests/test-launcher-meta-shift-keys.el= assert =(key-binding (kbd "M-E"))= etc. resolve to =eww= / =cj/elfeed-open= / =calibredb= (red before, green after). Verified live in the daemon. Open follow-ups (not done here, kept scoped): the "same class" =M-S-i= binding in text-config, and an audit of the keyboard-compat translation layer that makes Weather's =M-S-w= work.
** TODO [#B] ai-rewrite: chosen directive never reaches the request :bug:solo:
=modules/ai-rewrite.el:64= — the directive is let-bound around =(call-interactively #'gptel-rewrite)=, but gptel-rewrite is a transient prefix that returns when the menu shows; the send resolves the directive AFTER the binding unwound (verified against ~/code/gptel/gptel-rewrite.el:780-799). The picker's choice is silently dropped — the module's core feature is inert. Set =gptel--rewrite-directive= buffer-locally (restore via =gptel-post-rewrite-functions=) or use a self-removing global hook entry. From the 2026-06 config audit.