(defun elchemy/create-dashboard (&optional RECREATE) "Create the user dashboard" (interactive) (let ((buffer (get-buffer-create "*Dashboard*"))) (switch-to-buffer buffer) (unless (and buffer-read-only (not RECREATE)) (read-only-mode -1) (erase-buffer) (when (file-exists-p (concat elchemy/elchemy-root elchemy/dashboard-splash)) (insert-image (create-image (concat elchemy/elchemy-root elchemy/dashboard-splash) nil nil :scale 0.25)) (insert "\n")) (let ((start (point))) (insert "Elchemy Dashboard") (add-text-properties start (point) '(face (:height 4.0)))) (insert "\n\n") (elchemy/display-tabular-button-alist elchemy/dashboard/heading-buttons elchemy/dashboard/heading-columns elchemy/dashboard/heading-padding) (insert "\n\n") (when (file-exists-p (concat elchemy/elchemy-root elchemy/elchemy-projects-file)) (let ((start (point))) (insert "Projects") (add-text-properties start (point) '(face (:height 1.5)))) (insert "\n") (elchemy/display-tabular-button-alist (elchemy/read-alist-file (concat elchemy/elchemy-root elchemy/elchemy-projects-file)) elchemy/dashboard/projects-columns elchemy/dashboard/projects-padding) (insert "\n")) (ignore-errors (setq agenda-items (mapcar #'(lambda (x) (elchemy/get-agenda-items x 3)) elchemy/dashboard-agenda-titles) agenda-max-count (apply 'max (mapcar #'(lambda (x) (length x)) agenda-items)) agenda-max-length (apply 'max (mapcar #'(lambda (x) (apply 'max (mapcar #'(lambda (y) (length y)) x))) agenda-items))) (let ((start (point))) (insert "Agenda") (add-text-properties start (point) '(face (:height 1.5)))) (insert "\n") (insert (apply 'format (concat "%-" (format "%d" (+ agenda-max-length elchemy/dashboard-agenda-padding)) "s" "%-" (format "%d" (+ agenda-max-length elchemy/dashboard-agenda-padding)) "s" "%s\n") elchemy/dashboard-agenda-titles)) (dotimes (i agenda-max-count) (insert (format (concat "%-" (format "%d" (+ agenda-max-length elchemy/dashboard-agenda-padding)) "s") (elchemy/replace-nil (nth i (nth 0 agenda-items))))) (insert (format (concat "%-" (format "%d" (+ agenda-max-length elchemy/dashboard-agenda-padding)) "s") (elchemy/replace-nil (nth i (nth 1 agenda-items))))) (insert (format "%s" (elchemy/replace-nil (nth i (nth 2 agenda-items))))) (insert "\n") ) (insert "\n") (let ((start (point))) (insert "Overdue") (add-text-properties start (point) '(face (:height 1.5)))) (insert "\n") (insert (elchemy/format-processed-agenda (mapcar 'elchemy/process-agenda-heading (org-ql-select (org-agenda-files) `(and (todo "STRT" "WAIT" "TODO" "CYCL") (ts :from ,(- elchemy/schedule-lookahead) :to today)) :sort '(todo priority date))))) (insert "\n") (let ((start (point))) (insert "Upcoming") (add-text-properties start (point) '(face (:height 1.5)))) (insert "\n") (insert (elchemy/format-processed-agenda (mapcar 'elchemy/process-agenda-heading (org-ql-select (org-agenda-files) `(and (todo "STRT" "WAIT" "TODO" "CYCL") (ts :from today :to ,elchemy/schedule-lookahead)) :sort '(todo priority date))))) (insert "\n")) (let ((start (point))) (insert "Command Reference") (add-text-properties start (point) '(face (:height 1.5)))) (insert "\n") (insert "C-/ ~ Undo\n") (insert "C-x n n ~ Narrow\n") (insert "C-x n w ~ Widen\n") (insert "M-% ~ Query Replace\n") (insert "C-M-s ~ Regex Search\n") (insert "F3 ~ Record Macro\n") (insert "F4 ~ Play Macro\n") (insert "M-0 F4 ~ Play Macro until failure\n") (insert "M-l ~ Lowercase following word\n") (insert "M-u ~ Uppercase following word\n") (insert "M-c ~ Capitalize following word\n") (insert "M-g w ~ Jump to word\n") (insert "M-g l ~ Jump to line\n") (insert "C-x C-l ~ Lowercase Region\n") (insert "C-x C-u ~ Uppercase Region\n") (insert "C-M-n ~ Move forward one balanced expression\n") (insert "C-M-p ~ Move forward one balanced expression\n") (insert "\n") (insert (buttonize "Refresh" '(lambda (x) (elchemy/recreate-dashboard)))) (insert "\n") (button-mode +1) (read-only-mode +1)))) (defun elchemy/recreate-dashboard () "Recreate the dashboard" (interactive) (elchemy/create-dashboard t)) (provide 'elchemy-dashboard)