aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-24 19:59:28 -0500
committerCraig Jennings <c@cjennings.net>2026-05-24 19:59:28 -0500
commit08014b2f15e099a1c5e662a17a41290f37aeebf4 (patch)
treefba90116d0bb59b90d57489bdc6bc47f853c5384
parent47f222f66d7d481fb0d50661d64f49440455ff6d (diff)
downloaddotemacs-08014b2f15e099a1c5e662a17a41290f37aeebf4.tar.gz
dotemacs-08014b2f15e099a1c5e662a17a41290f37aeebf4.zip
refactor(load-graph): route C-; registration through the keymap API
Migrated all 31 cj/custom-keymap registration sites across 24 modules from direct (keymap-set cj/custom-keymap ...) calls to cj/register-prefix-map and cj/register-command. Consumers no longer reference cj/custom-keymap directly, so keybindings.el is the sole owner of the C-; prefix and modules reach it only through the API (each already requires keybindings from Phase 2). Behavior-preserving: I dumped every C-; binding before and after the migration and they're identical: 279 bindings, each resolving to the same command. The which-key label blocks are untouched, since they use string key descriptions and never assumed the keymap existed. I byte-compiled all 24 files (no new free-variable warnings, because the cj/custom-keymap references are gone), and make test, validate-modules, and an init load all pass.
-rw-r--r--modules/ai-config.el2
-rw-r--r--modules/calendar-sync.el2
-rw-r--r--modules/custom-buffer-file.el2
-rw-r--r--modules/custom-case.el2
-rw-r--r--modules/custom-comments.el2
-rw-r--r--modules/custom-datetime.el2
-rw-r--r--modules/custom-line-paragraph.el2
-rw-r--r--modules/custom-misc.el16
-rw-r--r--modules/custom-ordering.el2
-rw-r--r--modules/custom-text-enclose.el2
-rw-r--r--modules/custom-whitespace.el2
-rw-r--r--modules/dev-fkeys.el2
-rw-r--r--modules/erc-config.el2
-rw-r--r--modules/mail-config.el2
-rw-r--r--modules/music-config.el2
-rw-r--r--modules/org-config.el2
-rw-r--r--modules/org-drill-config.el2
-rw-r--r--modules/org-noter-config.el2
-rw-r--r--modules/system-commands.el2
-rw-r--r--modules/telega-config.el2
-rw-r--r--modules/test-runner.el2
-rw-r--r--modules/vc-config.el2
-rw-r--r--modules/video-audio-recording.el2
-rw-r--r--modules/vterm-config.el2
-rw-r--r--todo.org14
25 files changed, 34 insertions, 42 deletions
diff --git a/modules/ai-config.el b/modules/ai-config.el
index e2a71fed..199f644b 100644
--- a/modules/ai-config.el
+++ b/modules/ai-config.el
@@ -524,7 +524,7 @@ Works for any buffer, whether it's visiting a file or not."
"s" #'cj/gptel-save-conversation ;; save conversation
"t" #'cj/toggle-gptel ;; toggles the ai-assistant window
"x" #'cj/gptel-clear-buffer) ;; clears the assistant buffer
-(keymap-set cj/custom-keymap "a" cj/ai-keymap)
+(cj/register-prefix-map "a" cj/ai-keymap)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
diff --git a/modules/calendar-sync.el b/modules/calendar-sync.el
index 21ef8727..13c74ca1 100644
--- a/modules/calendar-sync.el
+++ b/modules/calendar-sync.el
@@ -1703,7 +1703,7 @@ Syncs all calendars immediately, then every `calendar-sync-interval-minutes'."
"S" #'calendar-sync-start
"x" #'calendar-sync-stop)
-(keymap-set cj/custom-keymap "g" cj/calendar-map)
+(cj/register-prefix-map "g" cj/calendar-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
diff --git a/modules/custom-buffer-file.el b/modules/custom-buffer-file.el
index d24c66b9..6c3e6c6e 100644
--- a/modules/custom-buffer-file.el
+++ b/modules/custom-buffer-file.el
@@ -538,7 +538,7 @@ Signals an error if:
"<right>" #'cj/window-resize-sticky
"<up>" #'cj/window-resize-sticky
"<down>" #'cj/window-resize-sticky)
-(keymap-set cj/custom-keymap "b" cj/buffer-and-file-map)
+(cj/register-prefix-map "b" cj/buffer-and-file-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
diff --git a/modules/custom-case.el b/modules/custom-case.el
index d8c60b55..d30ebf94 100644
--- a/modules/custom-case.el
+++ b/modules/custom-case.el
@@ -129,7 +129,7 @@ short prepositions, and all articles are considered minor words."
"t" #'cj/title-case-region
"u" #'cj/upcase-dwim
"l" #'cj/downcase-dwim)
-(keymap-set cj/custom-keymap "c" cj/case-map)
+(cj/register-prefix-map "c" cj/case-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
diff --git a/modules/custom-comments.el b/modules/custom-comments.el
index 467e1fd7..4e203f12 100644
--- a/modules/custom-comments.el
+++ b/modules/custom-comments.el
@@ -646,7 +646,7 @@ Leverages cj/comment-inline-border."
"h" #'cj/comment-heavy-box
"u" #'cj/comment-unicode-box
"n" #'cj/comment-block-banner)
-(keymap-set cj/custom-keymap "C" cj/comment-map)
+(cj/register-prefix-map "C" cj/comment-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
diff --git a/modules/custom-datetime.el b/modules/custom-datetime.el
index 3db4d28f..87b286de 100644
--- a/modules/custom-datetime.el
+++ b/modules/custom-datetime.el
@@ -124,7 +124,7 @@ Use `readable-date-format' for formatting."
"T" #'cj/insert-readable-time
"d" #'cj/insert-sortable-date
"D" #'cj/insert-readable-date )
-(keymap-set cj/custom-keymap "d" cj/datetime-map)
+(cj/register-prefix-map "d" cj/datetime-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
diff --git a/modules/custom-line-paragraph.el b/modules/custom-line-paragraph.el
index 8bbbeadb..2cbcecc1 100644
--- a/modules/custom-line-paragraph.el
+++ b/modules/custom-line-paragraph.el
@@ -160,7 +160,7 @@ If the line is empty or contains only whitespace, abort with a message."
"R" #'cj/remove-duplicate-lines-region-or-buffer
"r" #'cj/remove-lines-containing
"u" #'cj/underscore-line)
-(keymap-set cj/custom-keymap "l" cj/line-and-paragraph-map)
+(cj/register-prefix-map "l" cj/line-and-paragraph-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
diff --git a/modules/custom-misc.el b/modules/custom-misc.el
index 2ab5e779..7e5e4f8d 100644
--- a/modules/custom-misc.el
+++ b/modules/custom-misc.el
@@ -172,14 +172,14 @@ to nil."
(advice-remove 'align-regexp #'cj/align-regexp-with-spaces)
(advice-add 'align-regexp :around #'cj/align-regexp-with-spaces)
-(keymap-set cj/custom-keymap ")" #'cj/jump-to-matching-paren)
-(keymap-set cj/custom-keymap "f" #'cj/format-region-or-buffer)
-(keymap-set cj/custom-keymap "# w" #'cj/count-words-buffer-or-region)
-(keymap-set cj/custom-keymap "# c" #'cj/count-characters-buffer-or-region)
-(keymap-set cj/custom-keymap "/" #'cj/replace-fraction-glyphs)
-(keymap-set cj/custom-keymap "A" #'align-regexp)
-(keymap-set cj/custom-keymap "SPC" #'cj/switch-to-previous-buffer)
-(keymap-set cj/custom-keymap "|" #'display-fill-column-indicator-mode)
+(cj/register-command ")" #'cj/jump-to-matching-paren)
+(cj/register-command "f" #'cj/format-region-or-buffer)
+(cj/register-command "# w" #'cj/count-words-buffer-or-region)
+(cj/register-command "# c" #'cj/count-characters-buffer-or-region)
+(cj/register-command "/" #'cj/replace-fraction-glyphs)
+(cj/register-command "A" #'align-regexp)
+(cj/register-command "SPC" #'cj/switch-to-previous-buffer)
+(cj/register-command "|" #'display-fill-column-indicator-mode)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
diff --git a/modules/custom-ordering.el b/modules/custom-ordering.el
index 6536039e..578bede4 100644
--- a/modules/custom-ordering.el
+++ b/modules/custom-ordering.el
@@ -275,7 +275,7 @@ Returns the transformed string without modifying the buffer."
"L" #'cj/comma-separated-text-to-lines
"o" #'cj/org-sort-by-todo-and-priority)
-(keymap-set cj/custom-keymap "o" cj/ordering-map)
+(cj/register-prefix-map "o" cj/ordering-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
"C-; o" "ordering/sorting menu"
diff --git a/modules/custom-text-enclose.el b/modules/custom-text-enclose.el
index cbae2990..fdfb9223 100644
--- a/modules/custom-text-enclose.el
+++ b/modules/custom-text-enclose.el
@@ -280,7 +280,7 @@ Works on region if active, otherwise entire buffer."
"I" #'change-inner
"O" #'change-outer)
-(keymap-set cj/custom-keymap "s" cj/enclose-map)
+(cj/register-prefix-map "s" cj/enclose-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
"C-; s" "text enclose menu"
diff --git a/modules/custom-whitespace.el b/modules/custom-whitespace.el
index 19e2e020..0d4d1cc0 100644
--- a/modules/custom-whitespace.el
+++ b/modules/custom-whitespace.el
@@ -225,7 +225,7 @@ Operate on the active region designated by START and END."
"t" #'untabify
"T" #'tabify)
-(keymap-set cj/custom-keymap "w" cj/whitespace-map)
+(cj/register-prefix-map "w" cj/whitespace-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
"C-; w" "whitespace menu"
diff --git a/modules/dev-fkeys.el b/modules/dev-fkeys.el
index 00bb91ad..00a46774 100644
--- a/modules/dev-fkeys.el
+++ b/modules/dev-fkeys.el
@@ -530,7 +530,7 @@ message."
;; ---------- Bindings ----------
-(keymap-set cj/custom-keymap "P" #'cj/projectile-reset-cmds)
+(cj/register-command "P" #'cj/projectile-reset-cmds)
(keymap-global-set "<f4>" #'cj/f4-compile-and-run)
(keymap-global-set "C-<f4>" #'cj/f4-compile-only)
diff --git a/modules/erc-config.el b/modules/erc-config.el
index e63b12eb..22ba7f53 100644
--- a/modules/erc-config.el
+++ b/modules/erc-config.el
@@ -192,7 +192,7 @@ Auto-adds # prefix if missing. Offers completion from configured channels."
"q" #'erc-part-from-channel ;; quit channel
"Q" #'erc-quit-server) ;; Quit ERC entirely
-(keymap-set cj/custom-keymap "E" cj/erc-keymap)
+(cj/register-prefix-map "E" cj/erc-keymap)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
"C-; E" "ERC chat menu"
diff --git a/modules/mail-config.el b/modules/mail-config.el
index e1ebdfce..a498844e 100644
--- a/modules/mail-config.el
+++ b/modules/mail-config.el
@@ -403,7 +403,7 @@ Prompts user for the action when executing."
"d" cj/mail-dmail-map
"g" cj/mail-gmail-map
"s" #'cj/mu4e-save-attachment-here)
- (keymap-set cj/custom-keymap "e" cj/email-map)
+ (cj/register-prefix-map "e" cj/email-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
"C-; e" "email menu"
diff --git a/modules/music-config.el b/modules/music-config.el
index 27a282e2..197c73be 100644
--- a/modules/music-config.el
+++ b/modules/music-config.el
@@ -600,7 +600,7 @@ Dirs added recursively."
"z" #'emms-toggle-random-playlist
"x" #'cj/music-toggle-consume)
-(keymap-set cj/custom-keymap "m" cj/music-map)
+(cj/register-prefix-map "m" cj/music-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
"C-; m" "music menu"
diff --git a/modules/org-config.el b/modules/org-config.el
index 8ebfdbdb..01586a9e 100644
--- a/modules/org-config.el
+++ b/modules/org-config.el
@@ -140,7 +140,7 @@
:init
(defvar-keymap cj/org-map
:doc "General org-mode operations and utilities.")
- (keymap-set cj/custom-keymap "O" cj/org-map)
+ (cj/register-prefix-map "O" cj/org-map)
;; Keymap conventions for this prefix:
;; - Table operations claim `r' (row) and `c' (column) as
;; sub-prefixes, so single-key commands that would otherwise
diff --git a/modules/org-drill-config.el b/modules/org-drill-config.el
index b695619c..296b0550 100644
--- a/modules/org-drill-config.el
+++ b/modules/org-drill-config.el
@@ -110,7 +110,7 @@ With a prefix arg OTHER-DIR, prompt for the directory instead of `drill-dir'."
"r" #'cj/drill-refile
"R" #'org-drill-resume)
-(keymap-set cj/custom-keymap "D" cj/drill-map)
+(cj/register-prefix-map "D" cj/drill-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
diff --git a/modules/org-noter-config.el b/modules/org-noter-config.el
index 6504550f..4e5bd177 100644
--- a/modules/org-noter-config.el
+++ b/modules/org-noter-config.el
@@ -311,7 +311,7 @@ and to read more naturally as direction."
"q" #'org-noter-kill-session
"t" #'cj/org-noter-start
"T" #'org-noter-toggle-notes-window-location)
-(keymap-set cj/custom-keymap "n" cj/org-noter-map)
+(cj/register-prefix-map "n" cj/org-noter-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
diff --git a/modules/system-commands.el b/modules/system-commands.el
index 9aa8b3e1..dba4d40e 100644
--- a/modules/system-commands.el
+++ b/modules/system-commands.el
@@ -177,7 +177,7 @@ daemon alive rather than killing the session blindly."
"l" #'cj/system-cmd-lock
"E" #'cj/system-cmd-exit-emacs
"e" #'cj/system-cmd-restart-emacs)
-(keymap-set cj/custom-keymap "!" cj/system-command-map)
+(cj/register-prefix-map "!" cj/system-command-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
diff --git a/modules/telega-config.el b/modules/telega-config.el
index 55682447..0ae5116b 100644
--- a/modules/telega-config.el
+++ b/modules/telega-config.el
@@ -73,7 +73,7 @@ pointed at =scripts/setup-telega.sh= and the manual fallback."
(concat "telega not installed -- run scripts/setup-telega.sh, "
"or `M-x package-install RET telega'"))))
-(keymap-set cj/custom-keymap "T" #'cj/telega)
+(cj/register-command "T" #'cj/telega)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
diff --git a/modules/test-runner.el b/modules/test-runner.el
index 2a6f25e7..25c38f96 100644
--- a/modules/test-runner.el
+++ b/modules/test-runner.el
@@ -523,7 +523,7 @@ Returns the number of tests deleted."
"v" #'cj/test-view-focused
"t" #'cj/test-toggle-mode)
-(keymap-set cj/custom-keymap "t" cj/testrunner-map)
+(cj/register-prefix-map "t" cj/testrunner-map)
;; which-key integration
(with-eval-after-load 'which-key
diff --git a/modules/vc-config.el b/modules/vc-config.el
index 8b82b4cc..654116c5 100644
--- a/modules/vc-config.el
+++ b/modules/vc-config.el
@@ -244,7 +244,7 @@ repository's README if found, else `dired's the clone."
(keymap-set cj/vc-map "i" cj/vc-issues-map)
-(keymap-set cj/custom-keymap "v" cj/vc-map)
+(cj/register-prefix-map "v" cj/vc-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
"C-; v" "version control menu"
diff --git a/modules/video-audio-recording.el b/modules/video-audio-recording.el
index cec5df85..4c934ef1 100644
--- a/modules/video-audio-recording.el
+++ b/modules/video-audio-recording.el
@@ -1088,7 +1088,7 @@ Changes take effect on the next recording (not the current one)."
map)
"Keymap for video/audio recording operations under C-; r.")
-(keymap-set cj/custom-keymap "r" cj/record-map)
+(cj/register-prefix-map "r" cj/record-map)
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements
diff --git a/modules/vterm-config.el b/modules/vterm-config.el
index a87d354e..e7965c65 100644
--- a/modules/vterm-config.el
+++ b/modules/vterm-config.el
@@ -55,7 +55,7 @@
(defvar-keymap cj/vterm-map
:doc "Personal vterm command map.")
;; Lowercase x picked over V for fewer Shift presses; v is the VC menu.
-(keymap-set cj/custom-keymap "x" cj/vterm-map)
+(cj/register-prefix-map "x" cj/vterm-map)
(defvar-local cj/vterm-tmux-history--origin-buffer nil
"Buffer active before opening the tmux history buffer.")
diff --git a/todo.org b/todo.org
index 9b6763aa..eaec9369 100644
--- a/todo.org
+++ b/todo.org
@@ -412,18 +412,10 @@ Do this incrementally. After each batch:
- Run =make test= or at least targeted tests.
- Check that keybindings still resolve and which-key labels still appear.
-**** DOING [#B] Centralize custom keymap registration :refactor:
+**** 2026-05-24 Sun @ 19:59:01 -0500 Centralized custom keymap registration
+Added cj/register-prefix-map and cj/register-command to keybindings.el (commit 47f222f6) with test-init-keymap-registration.el, then migrated all 31 cj/custom-keymap registration sites across 24 modules onto the API. Consumers no longer reference cj/custom-keymap directly — keybindings.el is the sole owner of the prefix, and modules require keybindings to reach the API.
-Many modules mutate =cj/custom-keymap= or global keys at top level. This is a
-real architectural boundary because it forces load order and makes standalone
-module loading brittle.
-
-Expected outcome:
-- Define a small helper or convention for registering prefix maps.
-- Modules can expose their keymaps without assuming =keybindings.el= has already
- loaded.
-- =keybindings.el= remains the owner of global prefixes like =C-;=.
-- Existing keymaps continue to work.
+Verified behavior-preserving by dumping every C-; binding before and after: identical, 279 bindings, each resolving to the same command. Byte-compiled all 24 migrated files (no new free-variable warnings — the cj/custom-keymap coupling is gone), and full make test, validate-modules, and an init load all pass. which-key label blocks were left intact; they use string key descriptions and never assumed cj/custom-keymap existed.
Related existing task: [#B] "Review and rebind M-S- keybindings".