diff options
| -rw-r--r-- | modules/music-config.el | 322 | ||||
| -rw-r--r-- | modules/org-config.el | 82 | ||||
| -rw-r--r-- | modules/org-roam-config.el | 25 | ||||
| -rw-r--r-- | tests/test-org-config-keymap-ownership.el | 6 |
4 files changed, 283 insertions, 152 deletions
diff --git a/modules/music-config.el b/modules/music-config.el index 7c3af0e13..0874c4982 100644 --- a/modules/music-config.el +++ b/modules/music-config.el @@ -103,6 +103,37 @@ ;; orderless never see the binding (the lexical-binding foreign-special-var trap). (defvar orderless-smart-case) (defvar emms-source-playlist-ask-before-overwrite) +(defvar emms-playlist-buffer-p) +(defvar emms-playlist-buffer) +(defvar emms-random-playlist) +(defvar emms-playlist-selected-marker) +(defvar emms-source-file-default-directory) +(defvar emms-player-mpv-parameters) +(defvar emms-player-mpv-regexp) +(defvar emms-player-playing-p) +(defvar emms-player-paused-p) +(defvar emms-playlist-mode-map) +(defvar dirvish-mode-map) + +;; Foreign functions used lazily after their packages load. +(declare-function emms-playlist-mode "emms-playlist-mode") +(declare-function emms-playlist-track-at "emms-playlist-mode") +(declare-function emms-playlist-mode-kill-track "emms-playlist-mode") +(declare-function emms-track-name "emms") +(declare-function emms-track-type "emms") +(declare-function emms-track-get "emms") +(declare-function emms-track-simple-description "emms") +(declare-function emms-playlist-current-selected-track "emms") +(declare-function emms-playlist-select "emms") +(declare-function emms-playlist-clear "emms") +(declare-function emms-playlist-save "emms-source-playlist") +(declare-function emms-start "emms") +(declare-function emms-random "emms") +(declare-function emms-next "emms") +(declare-function emms-previous "emms") +(declare-function dired-get-marked-files "dired") +(declare-function dired-get-file-for-visit "dired") +(declare-function face-remap-remove-relative "face-remap") ;;; Settings (no Customize) @@ -619,26 +650,26 @@ Initializes EMMS if needed." ;;; Dired/Dirvish integration -(with-eval-after-load 'dirvish - (defun cj/music-add-dired-selection () - "Add selected files/dirs in Dired/Dirvish to the EMMS playlist. +(defun cj/music-add-dired-selection () + "Add selected files/dirs in Dired/Dirvish to the EMMS playlist. Dirs added recursively." - (interactive) - (unless (derived-mode-p 'dired-mode) - (user-error "This command must be run in a Dired buffer")) - (cj/music--ensure-playlist-buffer) - (let ((files (if (use-region-p) - (dired-get-marked-files) - (list (dired-get-file-for-visit))))) - (when (null files) - (user-error "No files selected")) - (dolist (file files) - (cond - ((file-directory-p file) (cj/music-add-directory-recursive file)) - ((cj/music--valid-file-p file) (emms-add-file file)) - (t (message "Skipping non-music file: %s" file)))) - (message "Added %d item(s) to playlist" (length files)))) + (interactive) + (unless (derived-mode-p 'dired-mode) + (user-error "This command must be run in a Dired buffer")) + (cj/music--ensure-playlist-buffer) + (let ((files (if (use-region-p) + (dired-get-marked-files) + (list (dired-get-file-for-visit))))) + (when (null files) + (user-error "No files selected")) + (dolist (file files) + (cond + ((file-directory-p file) (cj/music-add-directory-recursive file)) + ((cj/music--valid-file-p file) (emms-add-file file)) + (t (message "Skipping non-music file: %s" file)))) + (message "Added %d item(s) to playlist" (length files)))) +(with-eval-after-load 'dirvish (keymap-set dirvish-mode-map "+" #'cj/music-add-dired-selection)) ;;; EMMS setup and keybindings @@ -680,6 +711,130 @@ Dirs added recursively." "C-; m z" "random" "C-; m x" "consume")) +;;; Playlist display helpers +;; +;; Defined at top level (not inside the `emms' use-package `:config') so the +;; byte-compiler sees them; they touch EMMS only at call time, after load. + +(defun cj/music--after-playlist-clear (&rest _) + "Forget the associated M3U file after the playlist is cleared." + (when-let ((buf (get-buffer cj/music-playlist-buffer-name))) + (with-current-buffer buf + (setq cj/music-playlist-file nil)))) + +(defun cj/music--format-duration (seconds) + "Convert SECONDS to a \"M:SS\" string." + (when (and seconds (numberp seconds) (> seconds 0)) + (format "%d:%02d" (/ seconds 60) (mod seconds 60)))) + +(defun cj/music--track-description (track) + "Return a human-readable description of TRACK. +For tagged tracks: \"Artist - Title [M:SS]\". +For file tracks without tags: filename without path or extension. +For URL tracks: decoded URL." + (let ((type (emms-track-type track)) + (title (emms-track-get track 'info-title)) + (artist (emms-track-get track 'info-artist)) + (duration (emms-track-get track 'info-playing-time)) + (name (emms-track-name track))) + (cond + ;; Tagged track with title + (title + (let ((dur-str (cj/music--format-duration duration)) + (parts '())) + (when artist (push artist parts)) + (push title parts) + (let ((desc (string-join (nreverse parts) " - "))) + (if dur-str (format "%s [%s]" desc dur-str) desc)))) + ;; File without tags — show clean filename + ((eq type 'file) + (file-name-sans-extension (file-name-nondirectory name))) + ;; URL — decode percent-encoded characters + ((eq type 'url) + (decode-coding-string (url-unhex-string name) 'utf-8)) + ;; Fallback + (t (emms-track-simple-description track))))) + +;; Multi-line header overlay +(defvar-local cj/music--header-overlay nil + "Overlay displaying the playlist header.") + +(defun cj/music--header-text () + "Build a multi-line header string for the playlist buffer overlay." + (let* ((pl-name (if cj/music-playlist-file + (file-name-sans-extension + (file-name-nondirectory cj/music-playlist-file)) + "Untitled")) + (track-count (count-lines (point-min) (point-max))) + (now-playing (cond + ((not emms-player-playing-p) "Stopped") + (emms-player-paused-p "Paused") + (t (let ((track (emms-playlist-current-selected-track))) + (if track + (cj/music--track-description track) + "Playing"))))) + (mode-indicator + (lambda (key label active) + (let ((face (if active 'cj/music-mode-on-face 'cj/music-mode-off-face))) + (propertize (format "[%s] %s" key label) 'face face))))) + (concat + (propertize "Playlist" 'face 'cj/music-header-face) + (propertize " : " 'face 'cj/music-header-face) + (propertize (format "%s (%d)" pl-name track-count) 'face 'cj/music-header-value-face) + "\n" + (propertize "Current " 'face 'cj/music-header-face) + (propertize " : " 'face 'cj/music-header-face) + (propertize now-playing 'face 'cj/music-header-value-face) + "\n" + (propertize "Mode " 'face 'cj/music-header-face) + (propertize " : " 'face 'cj/music-header-face) + (funcall mode-indicator "r" "repeat" (bound-and-true-p emms-repeat-playlist)) + " " + (funcall mode-indicator "t" "single" (bound-and-true-p emms-repeat-track)) + " " + (funcall mode-indicator "z" "random" (bound-and-true-p emms-random-playlist)) + " " + (funcall mode-indicator "x" "consume" cj/music-consume-mode) + "\n" + (propertize "Keys " 'face 'cj/music-header-face) + (propertize " : " 'face 'cj/music-header-face) + (propertize "a:add c:clear L:load S:save SPC:pause <>:skip ↑↓:move C-↑↓:reorder q:dismiss" + 'face 'cj/music-keyhint-face) + "\n\n"))) + +(defun cj/music--update-header () + "Insert or update the multi-line header overlay in the playlist buffer." + (when-let ((buf (get-buffer cj/music-playlist-buffer-name))) + (with-current-buffer buf + (unless cj/music--header-overlay + (setq cj/music--header-overlay (make-overlay (point-min) (point-min))) + (overlay-put cj/music--header-overlay 'priority 100)) + (move-overlay cj/music--header-overlay (point-min) (point-min)) + (overlay-put cj/music--header-overlay 'before-string + (cj/music--header-text))))) + +(defvar-local cj/music--bg-remap-cookie nil + "Cookie for the active-window background face remapping.") + +(defun cj/music--update-active-bg (&rest _) + "Toggle playlist buffer background based on whether its window is selected." + (when-let ((buf (get-buffer cj/music-playlist-buffer-name))) + (with-current-buffer buf + (let ((active (eq buf (window-buffer (selected-window))))) + (cond + ((and active (not cj/music--bg-remap-cookie)) + (setq cj/music--bg-remap-cookie + (face-remap-add-relative 'default :background "#1d1b19"))) + ((and (not active) cj/music--bg-remap-cookie) + (face-remap-remove-relative cj/music--bg-remap-cookie) + (setq cj/music--bg-remap-cookie nil))))))) + +(defun cj/music--setup-playlist-display () + "Set up header overlay and focus tracking in the playlist buffer." + (setq header-line-format nil) + (cj/music--update-header) + (add-hook 'window-selection-change-functions #'cj/music--update-active-bg nil t)) + (use-package emms :defer t :init @@ -704,7 +859,7 @@ Dirs added recursively." (emms-all) ;; Disable modeline display (keep modeline clean) - (emms-playing-time-disable-display) + (emms-playing-time-display-mode -1) (emms-mode-line-mode -1) ;; MPV configuration @@ -718,134 +873,16 @@ Dirs added recursively." (regexp-opt cj/music-file-extensions) "\\'\\)")) - ;; Keep cj/music-playlist-file in sync if playlist is cleared - (defun cj/music--after-playlist-clear (&rest _) - (when-let ((buf (get-buffer cj/music-playlist-buffer-name))) - (with-current-buffer buf - (setq cj/music-playlist-file nil)))) - - ;; Ensure we don't stack duplicate advice on reload + ;; Keep cj/music-playlist-file in sync if playlist is cleared. + ;; Ensure we don't stack duplicate advice on reload. (advice-remove 'emms-playlist-clear #'cj/music--after-playlist-clear) (advice-add 'emms-playlist-clear :after #'cj/music--after-playlist-clear) ;;; Playlist display ;; Track description: show "Artist - Title [M:SS]" instead of file paths - (defun cj/music--format-duration (seconds) - "Convert SECONDS to a \"M:SS\" string." - (when (and seconds (numberp seconds) (> seconds 0)) - (format "%d:%02d" (/ seconds 60) (mod seconds 60)))) - - (defun cj/music--track-description (track) - "Return a human-readable description of TRACK. -For tagged tracks: \"Artist - Title [M:SS]\". -For file tracks without tags: filename without path or extension. -For URL tracks: decoded URL." - (let ((type (emms-track-type track)) - (title (emms-track-get track 'info-title)) - (artist (emms-track-get track 'info-artist)) - (duration (emms-track-get track 'info-playing-time)) - (name (emms-track-name track))) - (cond - ;; Tagged track with title - (title - (let ((dur-str (cj/music--format-duration duration)) - (parts '())) - (when artist (push artist parts)) - (push title parts) - (let ((desc (string-join (nreverse parts) " - "))) - (if dur-str (format "%s [%s]" desc dur-str) desc)))) - ;; File without tags — show clean filename - ((eq type 'file) - (file-name-sans-extension (file-name-nondirectory name))) - ;; URL — decode percent-encoded characters - ((eq type 'url) - (decode-coding-string (url-unhex-string name) 'utf-8)) - ;; Fallback - (t (emms-track-simple-description track))))) - (setq emms-track-description-function #'cj/music--track-description) - ;; Multi-line header overlay - (defvar-local cj/music--header-overlay nil - "Overlay displaying the playlist header.") - - (defun cj/music--header-text () - "Build a multi-line header string for the playlist buffer overlay." - (let* ((pl-name (if cj/music-playlist-file - (file-name-sans-extension - (file-name-nondirectory cj/music-playlist-file)) - "Untitled")) - (track-count (count-lines (point-min) (point-max))) - (now-playing (cond - ((not emms-player-playing-p) "Stopped") - (emms-player-paused-p "Paused") - (t (let ((track (emms-playlist-current-selected-track))) - (if track - (cj/music--track-description track) - "Playing"))))) - (mode-indicator - (lambda (key label active) - (let ((face (if active 'cj/music-mode-on-face 'cj/music-mode-off-face))) - (propertize (format "[%s] %s" key label) 'face face))))) - (concat - (propertize "Playlist" 'face 'cj/music-header-face) - (propertize " : " 'face 'cj/music-header-face) - (propertize (format "%s (%d)" pl-name track-count) 'face 'cj/music-header-value-face) - "\n" - (propertize "Current " 'face 'cj/music-header-face) - (propertize " : " 'face 'cj/music-header-face) - (propertize now-playing 'face 'cj/music-header-value-face) - "\n" - (propertize "Mode " 'face 'cj/music-header-face) - (propertize " : " 'face 'cj/music-header-face) - (funcall mode-indicator "r" "repeat" (bound-and-true-p emms-repeat-playlist)) - " " - (funcall mode-indicator "t" "single" (bound-and-true-p emms-repeat-track)) - " " - (funcall mode-indicator "z" "random" (bound-and-true-p emms-random-playlist)) - " " - (funcall mode-indicator "x" "consume" cj/music-consume-mode) - "\n" - (propertize "Keys " 'face 'cj/music-header-face) - (propertize " : " 'face 'cj/music-header-face) - (propertize "a:add c:clear L:load S:save SPC:pause <>:skip ↑↓:move C-↑↓:reorder q:dismiss" - 'face 'cj/music-keyhint-face) - "\n\n"))) - - (defun cj/music--update-header () - "Insert or update the multi-line header overlay in the playlist buffer." - (when-let ((buf (get-buffer cj/music-playlist-buffer-name))) - (with-current-buffer buf - (unless cj/music--header-overlay - (setq cj/music--header-overlay (make-overlay (point-min) (point-min))) - (overlay-put cj/music--header-overlay 'priority 100)) - (move-overlay cj/music--header-overlay (point-min) (point-min)) - (overlay-put cj/music--header-overlay 'before-string - (cj/music--header-text))))) - - (defvar-local cj/music--bg-remap-cookie nil - "Cookie for the active-window background face remapping.") - - (defun cj/music--update-active-bg (&rest _) - "Toggle playlist buffer background based on whether its window is selected." - (when-let ((buf (get-buffer cj/music-playlist-buffer-name))) - (with-current-buffer buf - (let ((active (eq buf (window-buffer (selected-window))))) - (cond - ((and active (not cj/music--bg-remap-cookie)) - (setq cj/music--bg-remap-cookie - (face-remap-add-relative 'default :background "#1d1b19"))) - ((and (not active) cj/music--bg-remap-cookie) - (face-remap-remove-relative cj/music--bg-remap-cookie) - (setq cj/music--bg-remap-cookie nil))))))) - - (defun cj/music--setup-playlist-display () - "Set up header overlay and focus tracking in the playlist buffer." - (setq header-line-format nil) - (cj/music--update-header) - (add-hook 'window-selection-change-functions #'cj/music--update-active-bg nil t)) - (add-hook 'emms-playlist-mode-hook #'cj/music--setup-playlist-display) (add-hook 'emms-player-started-hook #'cj/music--record-random-history) (add-hook 'emms-player-started-hook #'cj/music--update-header) @@ -897,8 +934,6 @@ For URL tracks: decoded URL." ("S-<down>" . emms-playlist-mode-shift-track-down) ("C-<up>" . emms-playlist-mode-shift-track-up) ("C-<down>" . emms-playlist-mode-shift-track-down) - ;; Radio - ("R" . cj/music-create-radio-station) ;; Volume ("+" . emms-volume-raise) ("=" . emms-volume-raise) @@ -927,5 +962,10 @@ For URL tracks: decoded URL." (insert content)) (message "Created radio station: %s" (file-name-nondirectory file)))) +;; Bound here rather than in the emms `:bind' so use-package does not emit a +;; redundant autoload that collides with this same-file definition. +(with-eval-after-load 'emms + (keymap-set emms-playlist-mode-map "R" #'cj/music-create-radio-station)) + (provide 'music-config) ;;; music-config.el ends here diff --git a/modules/org-config.el b/modules/org-config.el index 8d722ad46..f316ee0df 100644 --- a/modules/org-config.el +++ b/modules/org-config.el @@ -17,6 +17,72 @@ (require 'keybindings) ;; provides cj/custom-keymap (used in :init below) +;; Declare org variables and functions used before org is loaded so this module +;; byte-compiles standalone. Plain `defvar' (no value) marks the symbol special +;; without assigning anything, so org's own defaults still apply at runtime. +(defvar org-dir) +(defvar org-mode-map) +(defvar org-mouse-map) +(defvar org-modules) +(defvar org-startup-folded) +(defvar org-cycle-open-archived-trees) +(defvar org-cycle-hide-drawers) +(defvar org-id-locations-file) +(defvar org-return-follows-link) +(defvar org-list-allow-alphabetical) +(defvar org-startup-indented) +(defvar org-adapt-indentation) +(defvar org-startup-with-inline-images) +(defvar org-image-actual-width) +(defvar org-yank-image-save-method) +(defvar org-bookmark-names-plist) +(defvar org-file-apps) +(defvar org-ellipsis) +(defvar org-hide-emphasis-markers) +(defvar org-hide-leading-stars) +(defvar org-pretty-entities) +(defvar org-pretty-entities-include-sub-superscripts) +(defvar org-fontify-emphasized-text) +(defvar org-fontify-whole-heading-line) +(defvar org-tags-column) +(defvar org-agenda-tags-column) +(defvar org-todo-keywords) +(defvar org-highest-priority) +(defvar org-lowest-priority) +(defvar org-default-priority) +(defvar org-enforce-todo-dependencies) +(defvar org-enforce-todo-checkbox-dependencies) +(defvar org-deadline-warning-days) +(defvar org-treat-insert-todo-heading-as-state-change) +(defvar org-log-into-drawer) +(defvar org-log-done) +(defvar org-use-property-inheritance) + +(declare-function org-current-level "org") +(declare-function org-add-planning-info "org") +(declare-function org-get-heading "org") +(declare-function org-edit-headline "org") +(declare-function org-priority "org") +(declare-function org-heading-components "org") +(declare-function org-todo "org") +(declare-function org-get-todo-state "org") +(declare-function org-back-to-heading "org") +(declare-function org-sort-entries "org") +(declare-function org-eval-in-calendar "org") +(declare-function org-open-at-point "org") +(declare-function org-backward-heading-same-level "org") +(declare-function org-forward-heading-same-level "org") +(declare-function org-reveal "org") +(declare-function org-show-todo-tree "org") +(declare-function org-fold-show-all "org-fold") +(declare-function outline-next-heading "outline") +(declare-function org-element-cache-reset "org-element") +(declare-function org-element-context "org-element") +(declare-function org-element-type "org-element-ast") +(declare-function org-superstar-configure-like-org-bullets "org-superstar") +(declare-function cj/--org-follow-link-same-window "org-config") +(declare-function cj/org-follow-link-at-mouse-same-window "org-config") + ;; ---------------------------- Org General Settings --------------------------- (defun cj/org-general-settings () @@ -250,14 +316,14 @@ whole row line." (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, + ;; Both `S' and `T' resolve to `org-fold-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 "S" #'org-fold-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 "T" #'org-fold-show-all) (keymap-set cj/org-map "R" #'org-reveal) :bind ("C-c c" . org-capture) @@ -273,8 +339,7 @@ whole row line." ("C-c N" . org-narrow-to-subtree) ("C-c >" . cj/org-narrow-forward) ("C-c <" . cj/org-narrow-backwards) - ("C-c <ESC>" . widen) - ("C-c C-a" . cj/org-appear-toggle)) + ("C-c <ESC>" . widen)) (:map cj/org-map ("r i" . org-table-insert-row) ("r d" . org-table-kill-row) @@ -401,6 +466,11 @@ especially in tables with long URLs)." (org-appear-mode 1) (message "org-appear enabled (links/emphasis show when editing)"))) +;; Bound here (after the defun) rather than in the org use-package `:bind' so +;; the command isn't autoloaded into a stub that shadows this definition. +(with-eval-after-load 'org + (keymap-set org-mode-map "C-c C-a" #'cj/org-appear-toggle)) + ;; --------------------------------- Org-Tidy ---------------------------------- ;; Hide :PROPERTIES: drawers behind a small inline marker so headings stay @@ -444,7 +514,7 @@ with a file, the function will throw an error." "Clear the org-element cache for the current buffer or all buffers. By default, clear cache for all org buffers. With prefix argument, clear only the current buffer's cache. Useful when encountering parsing errors like -'wrong-type-argument stringp nil' during agenda generation." +\"wrong-type-argument stringp nil\" during agenda generation." (interactive) (if current-prefix-arg (if (derived-mode-p 'org-mode) diff --git a/modules/org-roam-config.el b/modules/org-roam-config.el index 40df688d9..c6083c8fb 100644 --- a/modules/org-roam-config.el +++ b/modules/org-roam-config.el @@ -32,6 +32,24 @@ ;; capture template never reaches org-roam-dailies (the foreign-special-var trap). (defvar org-roam-dailies-capture-templates) +;; External variables, declared special so byte-compilation doesn't treat them +;; as free references/assignments. Owned by org and org-roam-dailies. +(defvar org-agenda-timegrid-use-ampm) +(defvar org-roam-dailies-map) +(defvar org-last-state) + +;; External functions, declared so the byte-compiler knows they're defined at +;; runtime by their respective packages. +(declare-function org-roam-node-tags "org-roam") +(declare-function org-roam-node-file "org-roam") +(declare-function org-roam-node-list "org-roam") +(declare-function org-roam-dailies--capture "org-roam-dailies") +(declare-function org-capture-get "org-capture") +(declare-function org-at-heading-p "org") +(declare-function org-heading-components "org") +(declare-function org-copy-subtree "org") +(declare-function org-cut-subtree "org") + ;; ---------------------------------- Org Roam --------------------------------- (defconst cj/--org-roam-dailies-head @@ -76,8 +94,6 @@ FILETAGS and TITLE must sit on separate lines so Org parses the :bind (("C-c n l" . org-roam-buffer-toggle) ("C-c n f" . org-roam-node-find) ("C-c n p" . cj/org-roam-find-node-project) - ("C-c n r" . cj/org-roam-find-node-recipe) - ("C-c n t" . cj/org-roam-find-node-topic) ("C-c n i" . org-roam-node-insert) ("C-c n w" . cj/org-roam-find-node-webclip) :map org-mode-map @@ -191,6 +207,11 @@ created in that subdirectory of `org-roam-directory'." (interactive) (cj/org-roam-find-node "Recipe" "r" (concat roam-dir "templates/recipe.org") "recipes/")) +;; Bound after their defuns (not in the use-package :bind) so the byte-compiler +;; doesn't see both a :bind autoload and the real defun as two definitions. +(keymap-global-set "C-c n r" #'cj/org-roam-find-node-recipe) +(keymap-global-set "C-c n t" #'cj/org-roam-find-node-topic) + ;; ---------------------- Org Capture After Finalize Hook ---------------------- (defun cj/org-roam-add-node-to-agenda-files-finalize-hook () diff --git a/tests/test-org-config-keymap-ownership.el b/tests/test-org-config-keymap-ownership.el index 729d497cb..81f1ccd46 100644 --- a/tests/test-org-config-keymap-ownership.el +++ b/tests/test-org-config-keymap-ownership.el @@ -60,14 +60,14 @@ at the top level." "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 +capitals resolve to `org-fold-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 "S") #'org-fold-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 "T") #'org-fold-show-all)) (should (eq (keymap-lookup cj/org-map "R") #'org-reveal))) (ert-deftest test-org-config-keymap-ownership-regression-no-duplicate-org-keymap () |
