hamacs/ha-dashboard.org
Howard Abrams ccb49d5a58 Tangle all configuration files to my elisp directory
Haven't really needed this, as I have a function to load the org file
as Emacs Lisp code directly, but this can be a little helpful for debugging.
2023-07-05 10:22:18 -07:00

10 KiB
Raw Blame History

Start Screen

A literate programming file for configuring Emacs to show a startup screen.

Left Side

Dad Jokes!

The critical part of my dashboard, is the Dad Joke function, a curl call to a web service:

  curl -sH "Accept: text/plain" https://icanhazdadjoke.com/

For this, I use the request package (and Ill use this elsewhere too) and the dashboard project (defined below) will incorporate it:

  (use-package request
    :init
    (defvar ha-dad-joke nil "Holds the latest dad joke.")

    :config
    (defun ha-dad-joke ()
      "Display a random dad joke."
      (interactive)
      (message (ha--dad-joke)))

    (defun ha--dad-joke ()
      "Return string containing a dad joke from www.icanhazdadjoke.com."
      (setq ha-dad-joke nil)  ; Clear out old joke
      (ha--dad-joke-request)
      (ha--dad-joke-wait))

    (defun ha--dad-joke-wait ()
      (while (not ha-dad-joke)
        (sit-for 1))
      (unless ha-dad-joke
        (ha--dad-joke-wait))
      ha-dad-joke)

    (defun ha--dad-joke-request ()
      (request "https://icanhazdadjoke.com"
        :sync t
        :complete (cl-function
                   (lambda (&key data &allow-other-keys)
                     (setq ha-dad-joke data))))))

Dashboard

The emacs-dashboard project makes a nicer startup screen.

  (use-package dashboard
    :init
    (defun ha-dashboard-version ()
      (let ((smaller-version (replace-regexp-in-string
                              (rx " (" (zero-or-more any) eol) "" (emacs-version))))
        (string-replace "\n" "" smaller-version)))

    (setq dashboard-banner-logo-title
          (format "Emacs %s ⸺ %s"
                  (if (and (fboundp 'native-comp-available-p)
                           (native-comp-available-p))
                      "with Native Compilation" "")
                  (ha-dashboard-version))
          dashboard-startup-banner "~/other/hamacs/support/levitating-gnu.png"
          dashboard-center-content t
          dashboard-set-init-info t
          dashboard-projects-switch-function 'projectile-persp-switch-project
          dashboard-items '((projects . 5)
                            ;; (agenda . 5)
                            (bookmarks . 5)))
    (setq dashboard-footer-messages (list (ha--dad-joke)))

    :config
    (dashboard-setup-startup-hook)

    ;; Real shame that :config is incompatible with :hook, otherwise:
    ;; :hook (dashboard-after-initialize . ha-dashboard)
    (add-hook 'dashboard-after-initialize-hook 'ha-dashboard))

This dashboard project requires page-break-lines (which is a nice project):

  (use-package page-break-lines)

I would appreciate seeing if my Emacs installation has the features that I expect:

  (defun ha-hamacs-features (&optional iconic)
    "Simple display of features I'm most keen about.
    If ICONIC is non-nil, return a string of icons."
    (interactive)
    (let* ((png-icon  (all-the-icons-material "image"))
           (svg-icon  (all-the-icons-alltheicon "svg"))
           (tls-icon  (all-the-icons-faicon "expeditedssl"))
           (json-icon (all-the-icons-fileicon "jsx"))
           (mag-icon  (all-the-icons-faicon "magic"))
           (jit-icon  (all-the-icons-faicon "cog"))
           (results (s-join " "
                            (list (when (and (fboundp 'native-comp-available-p)
                                             (native-comp-available-p))
                                                                        (if iconic jit-icon "Native-Compilation"))
                                  (when (image-type-available-p 'svg)   (if iconic svg-icon "SVG"))
                                  (when (image-type-available-p 'png)   (if iconic png-icon "PNG"))
                                  (when (gnutls-available-p)            (if iconic tls-icon "TLS"))
                                  (when (json-available-p)              (if iconic json-icon "JSON"))
                                  (when (fboundp 'imagemagick-types)    (if iconic mag-icon "ImageMagick"))))))
      (if (called-interactively-p)
          (message "Enabled features: %s" results)
        results)))

Right Side

On the right side should show a list of keybindings or other hints that I want to work on memorizing.

Cheatsheet

Lots of things to learn and keep straight. Lets try the cheatsheet.el project.

  (use-package cheatsheet
    :config
    (cheatsheet-add-group 'Text-Objects
                          '(:key "w" :description "word")
                          '(:key "s" :description "sentence")
                          '(:key "p" :description "paragraph")
                          '(:key "l" :description "line / list")
                          '(:key "o" :description "symbol")
                          '(:key "a" :description "argument")
                          '(:key "x" :description "s-exp")
                          '(:key "'" :description "string")
                          '(:key "d" :description "function")
                          '(:key "j" :description "smaller indent block")
                          '(:key "k" :description "larger indent block")
                          '(:key "i" :description "indented block")
                          '(:key "c" :description "comment"))

    (cheatsheet-add-group 'Symbols
                          '(:key "(" :description "h d ... jump start s-expression")
                          '(:key ")" :description "h f ... jump to end s-expression")
                          '(:key "{" :description "h e ... forward expression")
                          '(:key "}" :description "h r ... backward expression")
                          '(:key "[" :description "h c ... backward expression")
                          '(:key "]" :description "h v ... forward expression")
                          '(:key "@" :description "h w ... play macro")
                          '(:key "!" :description "h q ... shell command")
                          '(:key "#" :description "h a ... reverse search (not `n')")
                          '(:key "^" :description "h x ... start of line")
                          '(:key "$" :description "h s ... end of line")
                          '(:key "%" :description "h z ... jump paren start/end")
                          '(:key "~" :description "h b ... change case")
                          '(:key "`" :description "h g ... jump to mark. See `m'")
                          '(:key "|" :description "h t ... goto column. Number prefix")
                          )
    (cheatsheet-add-group 'G
                          '(:key "g ;" :description "goto last change")
                          '(:key "g ," :description "return from last change")

                          '(:key "g ." :description "goto definition")
                          '(:key "g >" :description "goto definition other window")
                          '(:key "g ," :description "return definition stack")
                          '(:key "g <" :description "go forward (like definition)")
                          '(:key "g /" :description "find references")
                          '(:key "g ?" :description "find references and replace")
                          '(:key "g h" :description "find apropos with LSP")

                          '(:key "g d" :description "goto definition ... g b to go back")
                          '(:key "g w" :description "fill to object, g q to fill and move")
                          '(:key "g c" :description "comment line")
                          '(:key "g e" :description "go backward word end")
                          '(:key "g s" :description "visual search for line")
                          '(:key "g r" :description "visual search/replace")))

Learn This

Simple function to display a file in the top-right corner (if the file exists):

  (defun ha-show-learn-this ()
    ""
    (interactive)
    (let ((filename "~/other/hamacs/learn-this.org")
          (curr-win (get-buffer-window (buffer-name))))
      (when (file-exists-p filename)
        (split-window-below 15)
        (select-window curr-win)
        (find-file filename))))

Altogether

The dashboard project hooks to emacs-startup-hook and this ha-dashboard function hooks to dashboards dashboard-after-initialize-hook:

  (defun ha-dashboard ()
    "Shows the extra stuff with the dashboard."
    (interactive)
    (let ((width (thread-first (window-total-width)
                               (/ 3)
                               (* 2))))
      (split-window-right width)
      (cheatsheet-show)
      (ha-show-learn-this)))