diff --git a/modules/ui/doom-dashboard/autoload.el b/modules/ui/doom-dashboard/autoload.el index 898ae8a4f..a116497ee 100644 --- a/modules/ui/doom-dashboard/autoload.el +++ b/modules/ui/doom-dashboard/autoload.el @@ -10,7 +10,7 @@ "Switch to the dashboard in the current window, of the current FRAME." (interactive (list (selected-frame))) (with-selected-frame frame - (switch-to-buffer (+doom-dashboard-initial-buffer)) + (switch-to-buffer (doom-fallback-buffer)) (+doom-dashboard-reload t))) ;;;###autoload diff --git a/modules/ui/doom-dashboard/config.el b/modules/ui/doom-dashboard/config.el index cfaa23df9..5444cb559 100644 --- a/modules/ui/doom-dashboard/config.el +++ b/modules/ui/doom-dashboard/config.el @@ -99,40 +99,56 @@ PLIST can have the following properties: ;; -;; Bootstrap +;;; Bootstrap -(setq doom-fallback-buffer-name +doom-dashboard-name - ;; Fixes #850: `emacs file.txt' opens two windows, one for file.txt and - ;; one for `initial-buffer-choice' (in `command-line-1'). We want one or - ;; the other, not both. - initial-buffer-choice - (when (or (daemonp) - (not (cl-loop for arg in (cdr command-line-args) - if (or (equal arg "--restore") - (and (string-match-p "^[^-]" arg) - (file-exists-p arg))) - return t))) - #'+doom-dashboard-initial-buffer)) +(defun +doom-dashboard|init () + "Initializes Doom's dashboard." + (unless noninteractive + ;; Ensure the dashboard is up-to-date whenever it is switched to or resized. + (add-hook 'window-configuration-change-hook #'+doom-dashboard|resize) + (add-hook 'window-size-change-functions #'+doom-dashboard|resize) + (add-hook 'kill-buffer-query-functions #'+doom-dashboard|reload-on-kill) + (add-hook 'doom-switch-buffer-hook #'+doom-dashboard|reload-on-kill) + (add-hook 'delete-frame-functions #'+doom-dashboard|reload-frame) -(add-hook 'doom-init-ui-hook #'+doom-dashboard|init 'append) + ;; `persp-mode' integration: update `default-directory' when switching perspectives + (add-hook 'persp-created-functions #'+doom-dashboard|record-project) + (add-hook 'persp-activated-functions #'+doom-dashboard|detect-project) + (add-hook 'persp-before-switch-functions #'+doom-dashboard|record-project) + + ;; Ensure the dashboard becomes Emacs' go-to buffer when there's nothing + ;; else to show. + (setq doom-fallback-buffer-name +doom-dashboard-name + initial-buffer-choice #'doom-fallback-buffer) + (when (equal (buffer-name) "*scratch*") + (switch-to-buffer (doom-fallback-buffer)) + (if (daemonp) + (add-hook 'after-make-frame-functions #'+doom-dashboard|reload-frame) + (+doom-dashboard-reload))))) + +(add-hook 'doom-init-ui-hook #'+doom-dashboard|init) ;; -;; Major mode +;;; Major mode (define-derived-mode +doom-dashboard-mode special-mode (format "DOOM v%s" doom-version) + "Major mode for the DOOM dashboard buffer." :syntax-table nil :abbrev-table nil - "Major mode for the DOOM dashboard buffer." (setq truncate-lines t) (setq-local whitespace-style nil) (setq-local show-trailing-whitespace nil) (setq-local hscroll-margin 0) (setq-local tab-width 2) + ;; Don't scroll to follow cursor + (setq-local scroll-preserve-screen-position nil) + (setq-local auto-hscroll-mode nil) (cl-loop for (car . _cdr) in fringe-indicator-alist collect (cons car nil) into alist finally do (setq fringe-indicator-alist alist)) + ;; Ensure point is always on a button (add-hook 'post-command-hook #'+doom-dashboard|reposition-point nil t)) (define-key! +doom-dashboard-mode-map @@ -175,13 +191,13 @@ PLIST can have the following properties: ;; -;; Hooks +;;; Hooks (defun +doom-dashboard|reposition-point () "Trap the point in the buttons." (when (region-active-p) (deactivate-mark t) - (when (bound-and-true-p evil-mode) + (when (bound-and-true-p evil-local-mode) (evil-change-to-previous-state))) (or (ignore-errors (if (button-at (point)) @@ -190,25 +206,12 @@ PLIST can have the following properties: (progn (goto-char (point-min)) (forward-button 1)))) -(defun +doom-dashboard|init () - "Initializes Doom's dashboard." - (unless noninteractive - (add-hook 'window-configuration-change-hook #'+doom-dashboard|resize) - (add-hook 'window-size-change-functions #'+doom-dashboard|resize) - (add-hook 'kill-buffer-query-functions #'+doom-dashboard|reload-on-kill) - (add-hook 'doom-switch-buffer-hook #'+doom-dashboard|reload-on-kill) - ;; `persp-mode' integration: update `default-directory' when switching - (add-hook 'persp-created-functions #'+doom-dashboard|record-project) - (add-hook 'persp-activated-functions #'+doom-dashboard|detect-project) - (add-hook 'persp-before-switch-functions #'+doom-dashboard|record-project)) - (if (daemonp) - (add-hook 'after-make-frame-functions #'+doom-dashboard|reload-frame) - (+doom-dashboard-reload t))) - (defun +doom-dashboard|reload-on-kill () - "A `kill-buffer-query-functions' hook. If this isn't a dashboard buffer, move -along, but record its `default-directory' if the buffer is real. See -`doom-real-buffer-p' for an explanation for what 'real' means. + "A `kill-buffer-query-functions' hook. + +If this isn't a dashboard buffer, move along, but record its `default-directory' +if the buffer is real. See `doom-real-buffer-p' for an explanation for what +'real' means. If this is the dashboard buffer, reload the dashboard." (or (let ((buf (current-buffer))) @@ -230,11 +233,13 @@ whose dimensions may not be fully initialized by the time this is run." "Recenter the dashboard, and reset its margins and fringes." (let ((windows (get-buffer-window-list (doom-fallback-buffer) nil t)) buffer-list-update-hook) - (dolist (win windows) - (set-window-start win 0) - (set-window-fringes win 0 0) - (set-window-margins - win (max 0 (/ (- (window-total-width win) +doom-dashboard--width) 2)))) + (let (window-configuration-change-hook + window-size-change-functions) + (dolist (win windows) + (set-window-start win 0) + (set-window-fringes win 0 0) + (set-window-margins + win (max 0 (/ (- (window-total-width win) +doom-dashboard--width) 2))))) (when windows (with-current-buffer (doom-fallback-buffer) (save-excursion @@ -271,12 +276,7 @@ project (which may be different across perspective)." ;; -;; Library - -(defun +doom-dashboard-initial-buffer () - "Returns buffer to display on startup. Designed for `initial-buffer-choice'." - (let (buffer-list-update-hook) - (get-buffer-create +doom-dashboard-name))) +;;; Library (defun +doom-dashboard-p (buffer) "Returns t if BUFFER is the dashboard buffer." @@ -303,15 +303,17 @@ controlled by `+doom-dashboard-pwd-policy'." force) (with-current-buffer (doom-fallback-buffer) (with-silent-modifications - (save-excursion + (let ((pt (point))) (unless (eq major-mode '+doom-dashboard-mode) (+doom-dashboard-mode)) (erase-buffer) - (run-hooks '+doom-dashboard-functions))) - (+doom-dashboard|resize) - (+doom-dashboard|detect-project) - (+doom-dashboard-update-pwd) - (current-buffer)))) + (run-hooks '+doom-dashboard-functions) + (goto-char pt) + (+doom-dashboard|reposition-point)) + (+doom-dashboard|resize) + (+doom-dashboard|detect-project) + (+doom-dashboard-update-pwd) + (current-buffer))))) ;; helpers (defun +doom-dashboard--center (len s) @@ -337,13 +339,12 @@ controlled by `+doom-dashboard-pwd-policy'." cwd))) ((eq policy 'last) lastcwd) - (t - (warn "`+doom-dashboard-pwd-policy' has an invalid value of '%s'" + ((warn "`+doom-dashboard-pwd-policy' has an invalid value of '%s'" policy))))) ;; -;; Widgets +;;; Widgets (defun doom-dashboard-widget-banner () (let ((point (point)))