diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-15 21:48:10 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-15 21:48:10 -0500 |
| commit | 12fad985f6e08b4544521844ba6968ee2c1b6526 (patch) | |
| tree | 82a9455bfcb1ccfccda72f159803d8b82df64e81 | |
| parent | de32ffbe0d501f9dc61bc3a8889df3e207459535 (diff) | |
| download | dotemacs-12fad985f6e08b4544521844ba6968ee2c1b6526.tar.gz dotemacs-12fad985f6e08b4544521844ba6968ee2c1b6526.zip | |
feat(ui-navigation): C-x 2/3 show the dashboard in the new window
Splitting with C-x 2 or C-x 3 now shows *dashboard* in the freshly created window and keeps point in the original, instead of mirroring the current buffer. cj/--split-show-buffer does the placement; cj/--dashboard-buffer fetches or opens the dashboard without disturbing windows.
| -rw-r--r-- | modules/ui-navigation.el | 28 | ||||
| -rw-r--r-- | tests/test-ui-navigation--split-dashboard.el | 69 |
2 files changed, 97 insertions, 0 deletions
diff --git a/modules/ui-navigation.el b/modules/ui-navigation.el index f2181d97e..fba9153c2 100644 --- a/modules/ui-navigation.el +++ b/modules/ui-navigation.el @@ -103,6 +103,34 @@ nudging until any other key. Bound to `C-; b <left>/<right>/<up>/<down>'." (consult-buffer)) (keymap-global-set "M-S-h" #'cj/split-and-follow-below) ;; was M-H +(defun cj/--dashboard-buffer () + "Return the *dashboard* buffer, creating it if needed, without changing windows." + (or (get-buffer "*dashboard*") + (save-window-excursion + (when (fboundp 'dashboard-open) (dashboard-open)) + (get-buffer "*dashboard*")))) + +(defun cj/--split-show-buffer (split-fn buffer) + "Split with SPLIT-FN, show BUFFER in the new window, keep point in the current +window. Return the new window." + (let ((new (funcall split-fn))) + (when (and (window-live-p new) buffer) + (set-window-buffer new buffer)) + new)) + +(defun cj/split-below-with-dashboard () + "Split below and show the dashboard in the new window; stay in this one." + (interactive) + (cj/--split-show-buffer #'split-window-below (cj/--dashboard-buffer))) + +(defun cj/split-right-with-dashboard () + "Split right and show the dashboard in the new window; stay in this one." + (interactive) + (cj/--split-show-buffer #'split-window-right (cj/--dashboard-buffer))) + +(keymap-global-set "C-x 2" #'cj/split-below-with-dashboard) +(keymap-global-set "C-x 3" #'cj/split-right-with-dashboard) + ;; ------------------------- Split Window Reorientation ------------------------ (defun toggle-window-split () diff --git a/tests/test-ui-navigation--split-dashboard.el b/tests/test-ui-navigation--split-dashboard.el new file mode 100644 index 000000000..b815a4c59 --- /dev/null +++ b/tests/test-ui-navigation--split-dashboard.el @@ -0,0 +1,69 @@ +;;; test-ui-navigation--split-dashboard.el --- Tests for split-with-dashboard -*- lexical-binding: t; -*- + +;;; Commentary: +;; C-x 2 / C-x 3 split and show the *dashboard* in the new window while point +;; stays in the original. cj/--split-show-buffer does the placement; +;; cj/split-below/right-with-dashboard wire it to the two split directions. + +;;; Code: + +(require 'ert) +(require 'cl-lib) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'ui-navigation) + +(ert-deftest test-ui-navigation-split-dashboard-keybindings () + "Normal: C-x 2 / C-x 3 are bound to the dashboard-split commands." + (should (eq (key-binding (kbd "C-x 2")) #'cj/split-below-with-dashboard)) + (should (eq (key-binding (kbd "C-x 3")) #'cj/split-right-with-dashboard))) + +(ert-deftest test-ui-navigation-split-show-buffer-displays-and-keeps-point () + "Normal: the new window shows the buffer; the original stays selected." + (let ((buf (get-buffer-create " *split-dash-test*")) + (config (current-window-configuration))) + (unwind-protect + (progn + (delete-other-windows) + (let* ((orig (selected-window)) + (new (cj/--split-show-buffer #'split-window-below buf))) + (should (window-live-p new)) + (should (not (eq new orig))) + (should (eq (window-buffer new) buf)) + (should (eq (selected-window) orig)))) ; point stays put + (set-window-configuration config) + (kill-buffer buf)))) + +(ert-deftest test-ui-navigation-split-below-routes-to-split-window-below () + "Normal: cj/split-below-with-dashboard splits below with the dashboard buffer." + (let (captured) + (cl-letf (((symbol-function 'cj/--dashboard-buffer) (lambda () 'dashboard)) + ((symbol-function 'cj/--split-show-buffer) + (lambda (fn buf) (setq captured (list fn buf)) nil))) + (cj/split-below-with-dashboard)) + (should (eq (car captured) #'split-window-below)) + (should (eq (cadr captured) 'dashboard)))) + +(ert-deftest test-ui-navigation-split-right-routes-to-split-window-right () + "Normal: cj/split-right-with-dashboard splits right with the dashboard buffer." + (let (captured) + (cl-letf (((symbol-function 'cj/--dashboard-buffer) (lambda () 'dashboard)) + ((symbol-function 'cj/--split-show-buffer) + (lambda (fn buf) (setq captured (list fn buf)) nil))) + (cj/split-right-with-dashboard)) + (should (eq (car captured) #'split-window-right)) + (should (eq (cadr captured) 'dashboard)))) + +(ert-deftest test-ui-navigation-dashboard-buffer-returns-existing () + "Boundary: cj/--dashboard-buffer returns an existing *dashboard* without opening." + (let ((db (get-buffer-create "*dashboard*")) + (opened nil)) + (unwind-protect + (cl-letf (((symbol-function 'dashboard-open) + (lambda (&rest _) (setq opened t)))) + (should (eq (cj/--dashboard-buffer) db)) + (should-not opened)) + (kill-buffer db)))) + +(provide 'test-ui-navigation--split-dashboard) +;;; test-ui-navigation--split-dashboard.el ends here |
