2017-06-08 11:47:56 +02:00
|
|
|
;;; ui/doom-dashboard/config.el -*- lexical-binding: t; -*-
|
2017-02-20 16:33:14 -05:00
|
|
|
|
2018-06-16 21:01:16 +02:00
|
|
|
(defvar +doom-dashboard-name "*doom*"
|
2017-09-13 20:11:16 +02:00
|
|
|
"The name to use for the dashboard buffer.")
|
2017-02-20 16:33:14 -05:00
|
|
|
|
2018-07-03 20:00:37 +02:00
|
|
|
(defvar +doom-dashboard-functions
|
|
|
|
'(doom-dashboard-widget-banner
|
|
|
|
doom-dashboard-widget-shortmenu
|
|
|
|
doom-dashboard-widget-loaded
|
|
|
|
doom-dashboard-widget-footer)
|
2018-01-20 02:53:06 -05:00
|
|
|
"List of widget functions to run in the dashboard buffer to construct the
|
|
|
|
dashboard. These functions take no arguments and the dashboard buffer is current
|
|
|
|
while they run.")
|
2017-02-20 16:33:14 -05:00
|
|
|
|
2018-08-10 12:34:17 +02:00
|
|
|
(defvar +doom-dashboard-banner-file "default.png"
|
|
|
|
"The path to the image file to be used in on the dashboard. The path is
|
|
|
|
relative to `+doom-dashboard-banner-dir'. If nil, always use the ASCII banner.")
|
2018-07-05 14:33:48 +02:00
|
|
|
|
2018-08-10 12:34:17 +02:00
|
|
|
(defvar +doom-dashboard-banner-dir (concat (DIR!) "banners/")
|
|
|
|
"Where to look for `+doom-dashboard-banner-file'.")
|
|
|
|
|
|
|
|
(defvar +doom-dashboard-banner-padding '(4 . 4)
|
|
|
|
"Number of newlines to pad the banner with, above and below, respectively.")
|
2018-07-05 14:33:48 +02:00
|
|
|
|
2017-12-29 01:49:29 -05:00
|
|
|
(defvar +doom-dashboard-inhibit-refresh nil
|
|
|
|
"If non-nil, the doom buffer won't be refreshed.")
|
|
|
|
|
2017-10-02 19:59:18 +02:00
|
|
|
(defvar +doom-dashboard-inhibit-functions ()
|
2018-01-20 02:53:06 -05:00
|
|
|
"A list of functions which take no arguments. If any of them return non-nil,
|
|
|
|
dashboard reloading is inhibited.")
|
|
|
|
|
2017-12-27 13:24:14 -05:00
|
|
|
(defvar +doom-dashboard-pwd-policy 'last-project
|
|
|
|
"The policy to use when setting the `default-directory' in the dashboard.
|
|
|
|
|
|
|
|
Possible values:
|
|
|
|
|
|
|
|
'last-project the `doom-project-root' of the last open buffer
|
|
|
|
'last the `default-directory' of the last open buffer
|
|
|
|
a FUNCTION a function run with the `default-directory' of the last
|
|
|
|
open buffer, that returns a directory path
|
|
|
|
a STRING a fixed path
|
|
|
|
nil `default-directory' will never change")
|
|
|
|
|
2018-07-03 20:00:37 +02:00
|
|
|
(defvar +doom-dashboard-menu-sections
|
|
|
|
'(("Reload last session"
|
|
|
|
:icon (all-the-icons-octicon "history" :face 'font-lock-keyword-face)
|
|
|
|
:when (and (bound-and-true-p persp-mode)
|
|
|
|
(file-exists-p (expand-file-name persp-auto-save-fname
|
|
|
|
persp-save-dir)))
|
2018-07-04 15:33:15 +02:00
|
|
|
:face (:inherit (font-lock-keyword-face bold))
|
2018-07-07 11:41:24 +02:00
|
|
|
:action +workspace/load-last-session)
|
2018-08-17 04:10:11 +02:00
|
|
|
("Open org-agenda"
|
2018-07-03 20:00:37 +02:00
|
|
|
:icon (all-the-icons-octicon "calendar" :face 'font-lock-keyword-face)
|
2018-08-17 04:10:11 +02:00
|
|
|
:when (fboundp 'org-agenda)
|
|
|
|
:action org-agenda)
|
2018-07-03 20:00:37 +02:00
|
|
|
("Recently opened files"
|
|
|
|
:icon (all-the-icons-octicon "file-text" :face 'font-lock-keyword-face)
|
2018-07-04 23:05:49 +02:00
|
|
|
:action recentf-open-files)
|
2018-07-03 20:00:37 +02:00
|
|
|
("Open project"
|
|
|
|
:icon (all-the-icons-octicon "briefcase" :face 'font-lock-keyword-face)
|
2018-07-04 23:05:49 +02:00
|
|
|
:action projectile-switch-project)
|
2018-07-03 20:00:37 +02:00
|
|
|
("Jump to bookmark"
|
|
|
|
:icon (all-the-icons-octicon "bookmark" :face 'font-lock-keyword-face)
|
2018-07-04 23:05:49 +02:00
|
|
|
:action bookmark-jump)
|
2018-07-03 20:00:37 +02:00
|
|
|
("Open private configuration"
|
|
|
|
:icon (all-the-icons-octicon "tools" :face 'font-lock-keyword-face)
|
|
|
|
:when (file-directory-p doom-private-dir)
|
2018-07-05 12:36:32 +02:00
|
|
|
:action +default/find-in-config)
|
2018-07-03 20:00:37 +02:00
|
|
|
("Open user manual"
|
|
|
|
:icon (all-the-icons-octicon "book" :face 'font-lock-keyword-face)
|
2018-07-05 12:37:05 +02:00
|
|
|
:when (file-exists-p (expand-file-name "index.org" doom-docs-dir))
|
2018-07-04 23:05:49 +02:00
|
|
|
:action doom/open-manual))
|
2018-07-03 20:00:37 +02:00
|
|
|
"An alist of menu buttons used by `doom-dashboard-widget-shortmenu'. Each
|
|
|
|
element is a cons cell (LABEL . PLIST). LABEL is a string to display after the
|
|
|
|
icon and before the key string.
|
|
|
|
|
|
|
|
PLIST can have the following properties:
|
|
|
|
|
|
|
|
:icon FORM
|
|
|
|
Uses the return value of FORM as an icon (can be literal string).
|
|
|
|
:key STRING
|
|
|
|
The keybind displayed next to the button.
|
|
|
|
:when FORM
|
|
|
|
If FORM returns nil, don't display this button.
|
|
|
|
:face FACE
|
|
|
|
Displays the icon and text with FACE (a face symbol).
|
|
|
|
:action FORM
|
|
|
|
Run FORM when the button is pushed.")
|
|
|
|
|
2017-12-27 13:24:14 -05:00
|
|
|
;;
|
|
|
|
(defvar +doom-dashboard--last-cwd nil)
|
2017-09-13 20:15:46 +02:00
|
|
|
(defvar +doom-dashboard--width 80)
|
2017-09-13 20:11:16 +02:00
|
|
|
(defvar +doom-dashboard--old-fringe-indicator fringe-indicator-alist)
|
2018-01-20 02:53:06 -05:00
|
|
|
(defvar +doom-dashboard--pwd-alist ())
|
2017-09-13 20:11:16 +02:00
|
|
|
|
2017-12-29 01:49:29 -05:00
|
|
|
(defvar all-the-icons-scale-factor)
|
|
|
|
(defvar all-the-icons-default-adjust)
|
|
|
|
|
2017-09-13 20:11:16 +02:00
|
|
|
|
2018-01-08 16:15:28 -05:00
|
|
|
;;
|
2018-01-20 02:53:06 -05:00
|
|
|
;; Bootstrap
|
2018-01-08 16:15:28 -05:00
|
|
|
|
2018-02-01 20:06:00 -05:00
|
|
|
(setq doom-fallback-buffer-name +doom-dashboard-name
|
2018-09-20 15:01:28 -04:00
|
|
|
;; 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 (and (string-match-p "^[^-]" arg)
|
|
|
|
(file-exists-p arg))
|
|
|
|
return t)))
|
|
|
|
#'+doom-dashboard-initial-buffer))
|
2018-01-20 02:53:06 -05:00
|
|
|
|
|
|
|
(add-hook 'window-setup-hook #'+doom-dashboard|init)
|
2018-01-08 16:15:28 -05:00
|
|
|
|
|
|
|
|
|
|
|
;;
|
2018-01-20 02:53:06 -05:00
|
|
|
;; Major mode
|
2018-01-08 16:15:28 -05:00
|
|
|
|
2017-06-25 02:01:05 +02:00
|
|
|
(define-derived-mode +doom-dashboard-mode special-mode
|
2017-09-29 02:41:21 +02:00
|
|
|
(format "DOOM v%s" doom-version)
|
2018-03-18 02:36:12 -04:00
|
|
|
:syntax-table nil
|
|
|
|
:abbrev-table nil
|
2017-06-25 02:01:05 +02:00
|
|
|
"Major mode for the DOOM dashboard buffer."
|
2018-07-29 17:59:37 +02:00
|
|
|
(setq truncate-lines t)
|
2017-12-22 16:33:08 -05:00
|
|
|
(setq-local whitespace-style nil)
|
2017-12-25 19:09:55 -05:00
|
|
|
(setq-local show-trailing-whitespace nil)
|
2018-06-30 02:52:57 +02:00
|
|
|
(setq-local hscroll-margin 0)
|
2018-07-03 20:00:37 +02:00
|
|
|
(setq-local tab-width 2)
|
2017-06-25 02:01:05 +02:00
|
|
|
(cl-loop for (car . _cdr) in fringe-indicator-alist
|
|
|
|
collect (cons car nil) into alist
|
2018-03-18 02:35:52 -04:00
|
|
|
finally do (setq fringe-indicator-alist alist))
|
2018-06-03 17:22:23 +02:00
|
|
|
(add-hook 'post-command-hook #'+doom-dashboard|reposition-point nil t))
|
2018-06-03 15:46:00 +02:00
|
|
|
|
|
|
|
(define-key! +doom-dashboard-mode-map
|
2018-07-03 20:05:27 +02:00
|
|
|
[remap forward-button] #'+doom-dashboard/forward-button
|
|
|
|
[remap backward-button] #'+doom-dashboard/backward-button
|
2018-06-03 15:46:00 +02:00
|
|
|
"n" #'forward-button
|
|
|
|
"p" #'backward-button
|
Introduce general.el & rewrite map!
+ Now uses an overriding keymap for leader keys, so that it is always
available, even outside of normal/visual states. In insert/emacs
states, or in sessions where evil is absent, an alternative prefix is
used for leader/localleader keys. See these variables:
+ doom-leader-prefix
+ doom-leader-alt-prefix
+ doom-localleader-prefix
+ doom-localleader-alt-prefix
+ Keybinds now support alternative prefixes through the new :alt-prefix
property. This is useful for non-evil users and non-normal evil
states. By default, this is M-SPC (leader) and M-SPC m (localleader).
+ Removed +evil-commands flag from config/default (moved to
feature/evil/+commands.el).
+ config/default/+bindings.el has been split into
config/default/+{evil,emacs}-bindings.el, which one is loaded depends
on whether evil is present or not. The latter is blank, but will soon
be populated with a keybinding scheme for non-evil users (perhaps
inspired by #641).
+ The define-key! macro has been replaced; it is now an alias for
general-def.
+ Added unmap! as an alias for general-unbind.
+ The following modifier key conventions are now enforced for
consistency, across all OSes:
alt/option = meta
windows/command = super
It used to be
alt/option = alt
windows/command = meta
Many of the default keybinds have been updated to reflect this switch,
but it is likely to affect personal meta/super keybinds!
The map! macro has also been rewritten to use general-define-key. Here
is what has been changed:
+ map! no longer works with characters, e.g. (map! ?x #'do-something) is
no longer supported. Keys must be kbd-able strings like "C-c x" or
vectors like [?C-c ?x].
+ The :map and :map* properties are now the same thing. If specified
keymaps aren't defined when binding keys, it is automatically
deferred.
+ The way you bind local keybinds has changed:
;; Don't do this
(map! :l "a" #'func-a
:l "b" #'func-b)
;; Do this
(map! :map 'local "a" #'func-a
"b" #'func-b)
+ map! now supports the following new blocks:
+ (:if COND THEN-FORM ELSE-FORM...)
+ (:alt-prefix PREFIX KEYS...) -- this prefix will be used for
non-normal evil states. Equivalent to :non-normal-prefix in general.
+ The way you declare a which-key label for a prefix key has changed:
;; before
(map! :desc "label" :prefix "a" ...)
;; now
(map! :prefix ("a" . "label") ...)
+ It used to be that map! supported binding a key to a key sequence,
like so:
(map! "a" [?x]) ; pressing a is like pressing x
This functionality was removed *temporarily* while I figure out the
implementation.
Addresses: #448, #814, #860
Mentioned in: #940
2018-12-22 03:30:04 -05:00
|
|
|
"C-n" #'forward-button
|
|
|
|
"C-p" #'backward-button
|
2018-06-03 15:46:00 +02:00
|
|
|
[down] #'forward-button
|
|
|
|
[up] #'backward-button
|
|
|
|
[tab] #'forward-button
|
|
|
|
[backtab] #'backward-button)
|
|
|
|
|
Introduce general.el & rewrite map!
+ Now uses an overriding keymap for leader keys, so that it is always
available, even outside of normal/visual states. In insert/emacs
states, or in sessions where evil is absent, an alternative prefix is
used for leader/localleader keys. See these variables:
+ doom-leader-prefix
+ doom-leader-alt-prefix
+ doom-localleader-prefix
+ doom-localleader-alt-prefix
+ Keybinds now support alternative prefixes through the new :alt-prefix
property. This is useful for non-evil users and non-normal evil
states. By default, this is M-SPC (leader) and M-SPC m (localleader).
+ Removed +evil-commands flag from config/default (moved to
feature/evil/+commands.el).
+ config/default/+bindings.el has been split into
config/default/+{evil,emacs}-bindings.el, which one is loaded depends
on whether evil is present or not. The latter is blank, but will soon
be populated with a keybinding scheme for non-evil users (perhaps
inspired by #641).
+ The define-key! macro has been replaced; it is now an alias for
general-def.
+ Added unmap! as an alias for general-unbind.
+ The following modifier key conventions are now enforced for
consistency, across all OSes:
alt/option = meta
windows/command = super
It used to be
alt/option = alt
windows/command = meta
Many of the default keybinds have been updated to reflect this switch,
but it is likely to affect personal meta/super keybinds!
The map! macro has also been rewritten to use general-define-key. Here
is what has been changed:
+ map! no longer works with characters, e.g. (map! ?x #'do-something) is
no longer supported. Keys must be kbd-able strings like "C-c x" or
vectors like [?C-c ?x].
+ The :map and :map* properties are now the same thing. If specified
keymaps aren't defined when binding keys, it is automatically
deferred.
+ The way you bind local keybinds has changed:
;; Don't do this
(map! :l "a" #'func-a
:l "b" #'func-b)
;; Do this
(map! :map 'local "a" #'func-a
"b" #'func-b)
+ map! now supports the following new blocks:
+ (:if COND THEN-FORM ELSE-FORM...)
+ (:alt-prefix PREFIX KEYS...) -- this prefix will be used for
non-normal evil states. Equivalent to :non-normal-prefix in general.
+ The way you declare a which-key label for a prefix key has changed:
;; before
(map! :desc "label" :prefix "a" ...)
;; now
(map! :prefix ("a" . "label") ...)
+ It used to be that map! supported binding a key to a key sequence,
like so:
(map! "a" [?x]) ; pressing a is like pressing x
This functionality was removed *temporarily* while I figure out the
implementation.
Addresses: #448, #814, #860
Mentioned in: #940
2018-12-22 03:30:04 -05:00
|
|
|
(map! :when (featurep 'evil)
|
|
|
|
:map +doom-dashboard-mode-map
|
|
|
|
:n "j" #'forward-button
|
|
|
|
:n "k" #'backward-button
|
|
|
|
:n "n" #'forward-button
|
|
|
|
:n "p" #'backward-button
|
|
|
|
:n "C-n" #'forward-button
|
|
|
|
:n "C-p" #'backward-button
|
|
|
|
:n [down] #'forward-button
|
|
|
|
:n [up] #'backward-button
|
|
|
|
:n [tab] #'forward-button
|
|
|
|
:n [backtab] #'backward-button
|
|
|
|
[left-margin mouse-1] #'ignore
|
|
|
|
[remap evil-next-visual-line] #'forward-button
|
|
|
|
[remap evil-previous-visual-line] #'backward-button
|
|
|
|
[remap evil-delete] #'ignore
|
|
|
|
[remap evil-delete-line] #'ignore
|
|
|
|
[remap evil-insert] #'ignore
|
|
|
|
[remap evil-append] #'ignore
|
|
|
|
[remap evil-replace] #'ignore
|
|
|
|
[remap evil-replace-state] #'ignore
|
|
|
|
[remap evil-change] #'ignore
|
|
|
|
[remap evil-change-line] #'ignore
|
|
|
|
[remap evil-visual-char] #'ignore
|
|
|
|
[remap evil-visual-line] #'ignore)
|
2018-01-20 02:53:06 -05:00
|
|
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
;; Hooks
|
|
|
|
|
2018-03-18 02:35:52 -04:00
|
|
|
(defun +doom-dashboard|reposition-point ()
|
|
|
|
"Trap the point in the buttons."
|
2018-03-20 00:00:21 -04:00
|
|
|
(when (region-active-p)
|
|
|
|
(deactivate-mark t)
|
|
|
|
(when (bound-and-true-p evil-mode)
|
|
|
|
(evil-change-to-previous-state)))
|
2018-03-18 15:17:20 -04:00
|
|
|
(or (ignore-errors
|
|
|
|
(if (button-at (point))
|
|
|
|
(forward-button 0)
|
|
|
|
(backward-button 1)))
|
|
|
|
(progn (goto-char (point-min))
|
|
|
|
(forward-button 1))))
|
2018-03-18 02:35:52 -04:00
|
|
|
|
2018-01-20 02:53:06 -05:00
|
|
|
(defun +doom-dashboard|init ()
|
|
|
|
"Initializes Doom's dashboard."
|
2018-05-25 00:46:11 +02:00
|
|
|
(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)
|
2018-07-02 23:29:53 +02:00
|
|
|
(add-hook 'doom-enter-buffer-hook #'+doom-dashboard|reload-on-kill)
|
2018-05-25 00:46:11 +02:00
|
|
|
;; `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))
|
2018-10-17 14:49:35 -04:00
|
|
|
(if (daemonp)
|
|
|
|
(add-hook 'after-make-frame-functions #'+doom-dashboard|reload-frame)
|
|
|
|
(+doom-dashboard-reload t)))
|
2017-02-20 16:33:14 -05:00
|
|
|
|
2017-12-29 01:49:29 -05:00
|
|
|
(defun +doom-dashboard|reload-on-kill ()
|
2018-01-20 02:53:06 -05:00
|
|
|
"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.
|
2017-12-29 04:16:14 -05:00
|
|
|
|
|
|
|
If this is the dashboard buffer, reload the dashboard."
|
2018-01-20 02:53:06 -05:00
|
|
|
(or (let ((buf (current-buffer)))
|
|
|
|
(unless (+doom-dashboard-p buf)
|
|
|
|
(when (doom-real-buffer-p buf)
|
|
|
|
(setq +doom-dashboard--last-cwd default-directory)
|
|
|
|
(+doom-dashboard-update-pwd))
|
|
|
|
t))
|
2017-12-27 17:12:50 -05:00
|
|
|
(ignore
|
|
|
|
(let (+doom-dashboard-inhibit-refresh)
|
|
|
|
(ignore-errors (+doom-dashboard-reload))))))
|
2017-06-08 11:47:56 +02:00
|
|
|
|
2018-10-17 14:49:35 -04:00
|
|
|
(defun +doom-dashboard|reload-frame (_frame)
|
|
|
|
"Reload the dashboard after a brief pause. This is necessary for new frames,
|
|
|
|
whose dimensions may not be fully initialized by the time this is run."
|
|
|
|
(run-with-timer 0.1 nil #'+doom-dashboard-reload t))
|
|
|
|
|
2018-05-15 13:28:39 +02:00
|
|
|
(defun +doom-dashboard|resize (&rest _)
|
|
|
|
"Recenter the dashboard, and reset its margins and fringes."
|
|
|
|
(let ((windows (get-buffer-window-list (doom-fallback-buffer) nil t)))
|
|
|
|
(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
|
|
|
|
(with-silent-modifications
|
|
|
|
(goto-char (point-min))
|
2018-06-02 10:48:55 +02:00
|
|
|
(delete-region (line-beginning-position)
|
|
|
|
(save-excursion (skip-chars-forward "\n")
|
|
|
|
(point)))
|
|
|
|
(insert (make-string
|
|
|
|
(max 0 (- (/ (window-height (get-buffer-window)) 2)
|
2018-08-10 12:34:17 +02:00
|
|
|
(round (/ (+ (count-lines (point-min) (point-max))
|
|
|
|
(car +doom-dashboard-banner-padding))
|
|
|
|
2))))
|
|
|
|
?\n))))))))
|
2018-01-20 02:53:06 -05:00
|
|
|
|
|
|
|
(defun +doom-dashboard|detect-project (&rest _)
|
|
|
|
"Check for a `last-project-root' parameter in the perspective, and set the
|
|
|
|
dashboard's `default-directory' to it if it exists.
|
|
|
|
|
|
|
|
This and `+doom-dashboard|record-project' provides `persp-mode' integration with
|
|
|
|
the Doom dashboard. It ensures that the dashboard is always in the correct
|
|
|
|
project (which may be different across perspective)."
|
|
|
|
(when (bound-and-true-p persp-mode)
|
|
|
|
(when-let* ((pwd (persp-parameter 'last-project-root)))
|
|
|
|
(+doom-dashboard-update-pwd pwd))))
|
|
|
|
|
|
|
|
(defun +doom-dashboard|record-project (&optional persp &rest _)
|
|
|
|
"Record the last `doom-project-root' for the current perspective. See
|
|
|
|
`+doom-dashboard|detect-project' for more information."
|
|
|
|
(when (bound-and-true-p persp-mode)
|
|
|
|
(set-persp-parameter
|
|
|
|
'last-project-root (doom-project-root)
|
|
|
|
(if (perspective-p persp) persp (get-current-persp)))))
|
|
|
|
|
2017-06-25 01:59:58 +02:00
|
|
|
|
2018-01-20 02:53:06 -05:00
|
|
|
;;
|
|
|
|
;; Library
|
|
|
|
|
|
|
|
(defun +doom-dashboard-initial-buffer ()
|
|
|
|
"Returns buffer to display on startup. Designed for `initial-buffer-choice'."
|
2018-09-20 15:01:28 -04:00
|
|
|
(get-buffer-create +doom-dashboard-name))
|
2018-01-20 02:53:06 -05:00
|
|
|
|
|
|
|
(defun +doom-dashboard-p (buffer)
|
2017-03-15 22:59:21 -04:00
|
|
|
"Returns t if BUFFER is the dashboard buffer."
|
2018-07-04 23:14:12 +02:00
|
|
|
(eq buffer (get-buffer +doom-dashboard-name)))
|
2017-12-29 01:49:29 -05:00
|
|
|
|
2018-01-20 02:53:06 -05:00
|
|
|
(defun +doom-dashboard-update-pwd (&optional pwd)
|
2018-01-05 14:54:45 -05:00
|
|
|
"Update `default-directory' in the Doom dashboard buffer. What it is set to is
|
|
|
|
controlled by `+doom-dashboard-pwd-policy'."
|
2018-02-01 01:24:19 -05:00
|
|
|
(if pwd
|
|
|
|
(with-current-buffer (doom-fallback-buffer)
|
|
|
|
(setq-local default-directory pwd))
|
|
|
|
(let ((new-pwd (+doom-dashboard--get-pwd)))
|
|
|
|
(when (and new-pwd (file-directory-p new-pwd))
|
|
|
|
(unless (string-suffix-p "/" new-pwd)
|
|
|
|
(setq new-pwd (concat new-pwd "/")))
|
|
|
|
(+doom-dashboard-update-pwd new-pwd)))))
|
2017-12-29 01:49:29 -05:00
|
|
|
|
|
|
|
(defun +doom-dashboard-reload (&optional force)
|
|
|
|
"Update the DOOM scratch buffer (or create it, if it doesn't exist)."
|
2018-01-20 02:53:06 -05:00
|
|
|
(when (or (and (not +doom-dashboard-inhibit-refresh)
|
|
|
|
(get-buffer-window (doom-fallback-buffer))
|
|
|
|
(not (window-minibuffer-p (frame-selected-window)))
|
|
|
|
(not (run-hook-with-args-until-success '+doom-dashboard-inhibit-functions)))
|
|
|
|
force)
|
|
|
|
(with-current-buffer (doom-fallback-buffer)
|
|
|
|
(with-silent-modifications
|
|
|
|
(save-excursion
|
2017-12-29 01:49:29 -05:00
|
|
|
(unless (eq major-mode '+doom-dashboard-mode)
|
|
|
|
(+doom-dashboard-mode))
|
|
|
|
(erase-buffer)
|
2018-05-15 13:28:39 +02:00
|
|
|
(run-hooks '+doom-dashboard-functions)))
|
2018-01-20 02:53:06 -05:00
|
|
|
(+doom-dashboard|resize)
|
2018-05-15 13:28:39 +02:00
|
|
|
(+doom-dashboard|detect-project)
|
2018-01-20 02:53:06 -05:00
|
|
|
(+doom-dashboard-update-pwd)
|
|
|
|
(current-buffer))))
|
2017-02-20 16:33:14 -05:00
|
|
|
|
2017-12-29 01:49:29 -05:00
|
|
|
;; helpers
|
|
|
|
(defun +doom-dashboard--center (len s)
|
2017-06-25 02:01:05 +02:00
|
|
|
(concat (make-string (ceiling (max 0 (- len (length s))) 2) ? )
|
|
|
|
s))
|
|
|
|
|
2017-12-28 19:59:32 -05:00
|
|
|
(defun +doom-dashboard--get-pwd ()
|
2017-12-27 21:00:03 -05:00
|
|
|
(let ((lastcwd +doom-dashboard--last-cwd)
|
|
|
|
(policy +doom-dashboard-pwd-policy))
|
2018-01-28 18:14:41 -05:00
|
|
|
(cond ((null policy)
|
2017-12-27 21:00:03 -05:00
|
|
|
default-directory)
|
2017-12-29 04:15:56 -05:00
|
|
|
((stringp policy)
|
|
|
|
(expand-file-name policy lastcwd))
|
|
|
|
((functionp policy)
|
|
|
|
(funcall policy lastcwd))
|
2017-12-27 21:00:03 -05:00
|
|
|
((null lastcwd)
|
|
|
|
default-directory)
|
|
|
|
((eq policy 'last-project)
|
|
|
|
(let ((cwd default-directory)
|
|
|
|
(default-directory lastcwd))
|
|
|
|
(if (doom-project-p)
|
|
|
|
(doom-project-root)
|
|
|
|
cwd)))
|
2017-12-28 19:58:27 -05:00
|
|
|
((eq policy 'last)
|
|
|
|
lastcwd)
|
2017-12-27 21:00:03 -05:00
|
|
|
(t
|
|
|
|
(warn "`+doom-dashboard-pwd-policy' has an invalid value of '%s'"
|
2017-12-29 04:15:56 -05:00
|
|
|
policy)))))
|
2017-12-27 13:24:14 -05:00
|
|
|
|
2018-01-08 16:15:28 -05:00
|
|
|
|
|
|
|
;;
|
|
|
|
;; Widgets
|
|
|
|
|
2018-01-20 02:53:06 -05:00
|
|
|
(defun doom-dashboard-widget-banner ()
|
2018-07-04 16:19:30 +02:00
|
|
|
(let ((point (point)))
|
|
|
|
(mapc (lambda (line)
|
|
|
|
(insert (propertize (+doom-dashboard--center +doom-dashboard--width line)
|
|
|
|
'face 'font-lock-comment-face) " ")
|
|
|
|
(insert "\n"))
|
|
|
|
'("================= =============== =============== ======== ========"
|
|
|
|
"\\\\ . . . . . . .\\\\ //. . . . . . .\\\\ //. . . . . . .\\\\ \\\\. . .\\\\// . . //"
|
|
|
|
"||. . ._____. . .|| ||. . ._____. . .|| ||. . ._____. . .|| || . . .\\/ . . .||"
|
|
|
|
"|| . .|| ||. . || || . .|| ||. . || || . .|| ||. . || ||. . . . . . . ||"
|
|
|
|
"||. . || || . .|| ||. . || || . .|| ||. . || || . .|| || . | . . . . .||"
|
|
|
|
"|| . .|| ||. _-|| ||-_ .|| ||. . || || . .|| ||. _-|| ||-_.|\\ . . . . ||"
|
|
|
|
"||. . || ||-' || || `-|| || . .|| ||. . || ||-' || || `|\\_ . .|. .||"
|
|
|
|
"|| . _|| || || || || ||_ . || || . _|| || || || |\\ `-_/| . ||"
|
|
|
|
"||_-' || .|/ || || \\|. || `-_|| ||_-' || .|/ || || | \\ / |-_.||"
|
|
|
|
"|| ||_-' || || `-_|| || || ||_-' || || | \\ / | `||"
|
|
|
|
"|| `' || || `' || || `' || || | \\ / | ||"
|
|
|
|
"|| .===' `===. .==='.`===. .===' /==. | \\/ | ||"
|
|
|
|
"|| .==' \\_|-_ `===. .===' _|_ `===. .===' _-|/ `== \\/ | ||"
|
|
|
|
"|| .==' _-' `-_ `=' _-' `-_ `=' _-' `-_ /| \\/ | ||"
|
|
|
|
"|| .==' _-' '-__\\._-' '-_./__-' `' |. /| | ||"
|
|
|
|
"||.==' _-' `' | /==.||"
|
|
|
|
"==' _-' E M A C S \\/ `=="
|
|
|
|
"\\ _-' `-_ /"
|
|
|
|
" `'' ``'"))
|
2018-08-10 12:34:17 +02:00
|
|
|
(when (and (stringp +doom-dashboard-banner-file)
|
|
|
|
(display-graphic-p)
|
|
|
|
(file-exists-p! +doom-dashboard-banner-file +doom-dashboard-banner-dir))
|
|
|
|
(let* ((image (create-image (expand-file-name +doom-dashboard-banner-file
|
|
|
|
+doom-dashboard-banner-dir)
|
|
|
|
'png nil))
|
|
|
|
(size (image-size image nil))
|
|
|
|
(margin (+ 1 (/ (- +doom-dashboard--width (car size)) 2))))
|
|
|
|
(add-text-properties
|
|
|
|
point (point) `(display ,image rear-nonsticky (display)))
|
|
|
|
(when (> margin 0)
|
|
|
|
(save-excursion
|
|
|
|
(goto-char point)
|
|
|
|
(insert (make-string (truncate margin) ? )))))
|
|
|
|
(insert (make-string (or (cdr +doom-dashboard-banner-padding) 0) ?\n)))))
|
2017-02-20 16:33:14 -05:00
|
|
|
|
2018-01-20 02:53:06 -05:00
|
|
|
(defun doom-dashboard-widget-loaded ()
|
2017-02-20 16:33:14 -05:00
|
|
|
(insert
|
2018-01-20 02:53:06 -05:00
|
|
|
"\n\n"
|
2017-02-20 16:33:14 -05:00
|
|
|
(propertize
|
2017-12-29 01:49:29 -05:00
|
|
|
(+doom-dashboard--center
|
2017-06-25 02:01:05 +02:00
|
|
|
+doom-dashboard--width
|
2018-05-14 20:56:17 +02:00
|
|
|
(doom|display-benchmark 'return))
|
2017-02-20 16:33:14 -05:00
|
|
|
'face 'font-lock-comment-face)
|
2018-07-03 20:00:37 +02:00
|
|
|
"\n"))
|
2017-02-20 16:33:14 -05:00
|
|
|
|
2018-01-20 02:53:06 -05:00
|
|
|
(defun doom-dashboard-widget-shortmenu ()
|
2017-09-29 02:42:38 +02:00
|
|
|
(let ((all-the-icons-scale-factor 1.45)
|
|
|
|
(all-the-icons-default-adjust -0.02))
|
2018-01-20 02:53:06 -05:00
|
|
|
(insert "\n")
|
2018-07-03 20:00:37 +02:00
|
|
|
(dolist (section +doom-dashboard-menu-sections)
|
2018-07-04 23:05:49 +02:00
|
|
|
(cl-destructuring-bind (label &key icon action when face) section
|
|
|
|
(when (and (fboundp action)
|
|
|
|
(or (null when)
|
|
|
|
(eval when t)))
|
2018-07-03 20:00:37 +02:00
|
|
|
(insert
|
|
|
|
(+doom-dashboard--center
|
|
|
|
(- +doom-dashboard--width 1)
|
|
|
|
(let ((icon (if (stringp icon) icon (eval icon t))))
|
|
|
|
(format (format "%s%%s%%-10s" (if icon "%3s\t" "%3s"))
|
|
|
|
(or icon "")
|
|
|
|
(with-temp-buffer
|
|
|
|
(insert-text-button
|
2018-07-05 01:32:04 +02:00
|
|
|
label
|
2018-07-04 23:05:49 +02:00
|
|
|
'action
|
|
|
|
`(lambda (_)
|
|
|
|
(call-interactively (or (command-remapping #',action)
|
|
|
|
#',action)))
|
2018-07-05 01:32:04 +02:00
|
|
|
'face (or face 'font-lock-keyword-face)
|
2018-07-03 20:00:37 +02:00
|
|
|
'follow-link t
|
|
|
|
'help-echo label)
|
|
|
|
(format "%-37s" (buffer-string)))
|
|
|
|
;; Lookup command keys dynamically
|
2018-12-27 00:06:06 -05:00
|
|
|
(or (when-let* ((key (where-is-internal action nil t)))
|
|
|
|
(propertize (with-temp-buffer
|
|
|
|
(save-excursion (insert (key-description key)))
|
|
|
|
(while (re-search-forward "<\\([^>]+\\)>" nil t)
|
|
|
|
(replace-match (upcase (substring (match-string 1) 0 3))))
|
|
|
|
(buffer-string))
|
|
|
|
'face 'font-lock-constant-face))
|
2018-07-04 23:05:49 +02:00
|
|
|
""))))
|
2018-07-03 20:00:37 +02:00
|
|
|
(if (display-graphic-p)
|
|
|
|
"\n\n"
|
|
|
|
"\n")))))))
|
|
|
|
|
|
|
|
(defun doom-dashboard-widget-footer ()
|
|
|
|
(insert
|
|
|
|
"\n"
|
|
|
|
(+doom-dashboard--center
|
|
|
|
(- +doom-dashboard--width 2)
|
|
|
|
(with-temp-buffer
|
|
|
|
;; TODO Publish the site!
|
|
|
|
;; (insert-text-button (propertize "doomemacs.org" 'face 'font-lock-keyword-face)
|
2018-07-05 01:32:04 +02:00
|
|
|
;; 'action (lambda (_) (browse-url "http://doomemacs.org"))
|
2018-07-03 20:00:37 +02:00
|
|
|
;; 'follow-link t
|
|
|
|
;; 'help-echo "Open home page")
|
|
|
|
;; (insert (propertize " x " 'face 'font-lock-comment-face))
|
|
|
|
(insert-text-button (or (all-the-icons-octicon "octoface" :face 'all-the-icons-green :height 1.3 :v-adjust -0.15)
|
|
|
|
(propertize "github" 'face 'font-lock-keyword-face))
|
|
|
|
'action (lambda (_) (browse-url "https://github.com/hlissner/doom-emacs"))
|
|
|
|
'follow-link t
|
2018-08-21 02:57:40 +02:00
|
|
|
'help-echo "Open Doom Emacs github page")
|
2018-07-03 20:00:37 +02:00
|
|
|
(buffer-string)))
|
|
|
|
"\n"))
|