diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-14 19:05:43 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-14 19:05:43 -0500 |
| commit | 1dbf5a4a2d2ce4277dc97a3e9783240324ad5f53 (patch) | |
| tree | 2a81d246d624064660681df8adf72672a38b8092 | |
| parent | 0b5ada69861b338d93ee947645e7fa1ed12fca00 (diff) | |
| download | dotemacs-1dbf5a4a2d2ce4277dc97a3e9783240324ad5f53.tar.gz dotemacs-1dbf5a4a2d2ce4277dc97a3e9783240324ad5f53.zip | |
refactor(org-config): surface narrowing + sparse-tree under C-; O
Narrowing and sparse-tree commands existed in the `:bind' block
on `C-c'-style shortcuts but nothing in `cj/org-map' surfaced
them, so which-key never showed them and discoverability was
poor.
Add direct bindings under `C-; O', flat (no sub-prefixes for
narrow / sparse-tree). Lowercase creates; capital of the same
letter cancels:
- `n' / `N' narrow-to-subtree / widen
- `s' / `S' match-sparse-tree / show-all
- `t' / `T' show-todo-tree / show-all
- `>' / `<' forward / backward sibling narrow (kept as-is)
- `R' reveal-context (no lowercase pair -- `r' is the
table-row sub-prefix)
Both `S' and `T' resolve to the same `org-show-all' command so
the mental model is just "capital cancels the lowercase I just
ran" without having to recall which letter the cancel actually
lives on.
Free up F2: the old `(<f2> . org-reveal)' binding in the org-mode
`:bind' block is now redundant with `C-; O R'. Drop it; F2
becomes available for whatever wants it next.
Four new ERT assertions in `test-org-config-keymap-ownership.el'
lock the shape -- the old sparse-tree-submap test was rewritten
for the flat layout and the narrow-submap test became
narrow-bindings (also flat).
| -rw-r--r-- | modules/org-config.el | 42 | ||||
| -rw-r--r-- | tests/test-org-config-keymap-ownership.el | 25 |
2 files changed, 62 insertions, 5 deletions
diff --git a/modules/org-config.el b/modules/org-config.el index 8c2dc646..852dfd37 100644 --- a/modules/org-config.el +++ b/modules/org-config.el @@ -129,10 +129,32 @@ (defvar-keymap cj/org-map :doc "General org-mode operations and utilities.") (keymap-set cj/custom-keymap "O" cj/org-map) - ;; Table operations live directly under the org menu: `r' for row, - ;; `c' for column. Single-key org commands under this prefix use - ;; capitals (e.g. `C' for clear element cache) to leave the - ;; lowercase letters free as table sub-prefixes. + ;; Keymap conventions for this prefix: + ;; - Table operations claim `r' (row) and `c' (column) as + ;; sub-prefixes, so single-key commands that would otherwise + ;; want lowercase `r' or `c' use capitals (e.g. `C' for clear + ;; element cache). + ;; - Narrow and sparse-tree commands follow a lowercase-creates / + ;; uppercase-cancels pattern. `n' narrows to the current + ;; subtree; `N' widens. `s' is the sparse-tree sub-prefix and + ;; `s S' cancels the sparse tree. + + ;; Narrow / widen (direct, flat under the org menu) + (keymap-set cj/org-map "n" #'org-narrow-to-subtree) + (keymap-set cj/org-map "N" #'widen) + (keymap-set cj/org-map ">" #'cj/org-narrow-forward) + (keymap-set cj/org-map "<" #'cj/org-narrow-backwards) + + ;; Sparse trees: lowercase creates, capital of the same letter cancels. + ;; Both `S' and `T' resolve to `org-show-all' -- same cancel command, + ;; paired with each lowercase create so the mental model is "capital + ;; cancels the lowercase command I just ran" without having to recall + ;; which letter the cancel actually lives on. + (keymap-set cj/org-map "s" #'org-match-sparse-tree) + (keymap-set cj/org-map "S" #'org-show-all) + (keymap-set cj/org-map "t" #'org-show-todo-tree) + (keymap-set cj/org-map "T" #'org-show-all) + (keymap-set cj/org-map "R" #'org-reveal) :bind ("C-c c" . org-capture) ("C-c a" . org-agenda) @@ -147,7 +169,6 @@ ("C-c N" . org-narrow-to-subtree) ("C-c >" . cj/org-narrow-forward) ("C-c <" . cj/org-narrow-backwards) - ("<f2>" . org-reveal) ("C-c <ESC>" . widen) ("C-c C-a" . cj/org-appear-toggle)) (:map cj/org-map @@ -329,6 +350,17 @@ status to preserve priority ordering within TODO groups." "C-; O c" "table column" "C-; O c i" "insert column" "C-; O c d" "delete column" + ;; org narrowing (flat under the org menu; lowercase narrows, capital widens) + "C-; O n" "narrow to subtree" + "C-; O N" "widen" + "C-; O >" "narrow forward sibling" + "C-; O <" "narrow backward sibling" + ;; org sparse tree (flat; lowercase creates, capital of same letter cancels) + "C-; O s" "match sparse tree" + "C-; O S" "show all (cancel)" + "C-; O t" "show all TODOs" + "C-; O T" "show all (cancel)" + "C-; O R" "reveal context" ;; org global bindings "C-c a" "org agenda" "C-c c" "org capture" diff --git a/tests/test-org-config-keymap-ownership.el b/tests/test-org-config-keymap-ownership.el index 7f08a172..729d497c 100644 --- a/tests/test-org-config-keymap-ownership.el +++ b/tests/test-org-config-keymap-ownership.el @@ -45,6 +45,31 @@ command (which moved to capital `C')." (should (eq (keymap-lookup cj/org-map "c i") #'org-table-insert-column)) (should (eq (keymap-lookup cj/org-map "c d") #'org-table-delete-column))) +(ert-deftest test-org-config-keymap-ownership-narrow-bindings () + "Narrow / widen sit directly under `C-; O' (flat, no sub-prefix). +Lowercase `n' narrows to the current subtree; capital `N' widens, +matching the lowercase-creates / uppercase-cancels pattern shared +with the sparse-tree sub-prefix. Sibling-stepping is on `>' / `<' +at the top level." + (should (eq (keymap-lookup cj/org-map "n") #'org-narrow-to-subtree)) + (should (eq (keymap-lookup cj/org-map "N") #'widen)) + (should (eq (keymap-lookup cj/org-map ">") #'cj/org-narrow-forward)) + (should (eq (keymap-lookup cj/org-map "<") #'cj/org-narrow-backwards))) + +(ert-deftest test-org-config-keymap-ownership-sparse-tree-bindings () + "Sparse-tree commands sit directly under `C-; O' (flat). +Lowercase creates, capital of the same letter cancels: `s' / +`S' for match-sparse-tree, `t' / `T' for show-todo-tree. Both +capitals resolve to `org-show-all' -- the user's mental model is +\"capital cancels the lowercase I just ran\" without having to +remember which letter the cancel actually lives on. `R' is +`org-reveal' (no lowercase pair -- `r' is the table-row sub-prefix)." + (should (eq (keymap-lookup cj/org-map "s") #'org-match-sparse-tree)) + (should (eq (keymap-lookup cj/org-map "S") #'org-show-all)) + (should (eq (keymap-lookup cj/org-map "t") #'org-show-todo-tree)) + (should (eq (keymap-lookup cj/org-map "T") #'org-show-all)) + (should (eq (keymap-lookup cj/org-map "R") #'org-reveal))) + (ert-deftest test-org-config-keymap-ownership-regression-no-duplicate-org-keymap () "The old duplicate `cj/org-keymap' binding should not exist." (should-not (boundp 'cj/org-keymap))) |
