diff --git a/README.org b/README.org index 0aee6d7..c86d7f7 100644 --- a/README.org +++ b/README.org @@ -15,7 +15,8 @@ This creates [[file:~/.emacs.d/init.el][~/.emacs.d/init.el]] that starts the pro - [[file:bootstrap.org][bootstrap]] :: configures =straight= and loads basic libraries the rest of the code depends on. It then loads the following files in order: - [[file:ha-config.org][config]] :: contains /most/ of my configuration, setting up my sequence key menus, evil, etc. - - [[file:ha-display.org][display]] :: sets up the visual aspects of an Emacs GUI, including themes, fonts and the dashboard. + - [[file:ha-display.org][display]] :: sets up the visual aspects of an Emacs GUI, including themes and fonts. + - [[file:ha-dashboard.org][dashboard]] :: sets up initial window layout of the =main= project with a dashboard. - [[file:ha-org.org][org]] :: configures the basics for org-mode formatted files. Specific features come from their own files. - [[file:ha-org-word-processor.org][org-word-processor]] :: attempts to make Org files /visually/ look like a word processor, including turning off the colors for headers, and instead increasing their size. - [[file:ha-org-clipboard.org][org-clipboard]] :: automatically converting HTML from a clipboard into Org-formatted content. diff --git a/bootstrap.org b/bootstrap.org index 2001e5d..42c4b94 100644 --- a/bootstrap.org +++ b/bootstrap.org @@ -243,7 +243,8 @@ The following loads the rest of my org-mode literate files. I add new filesas t "ha-org-publishing.org" "ha-email.org" "ha-aux-apps.org" - "ha-feed-reader.org")))) + "ha-feed-reader.org")) + "ha-dashboard.org")) "List of org files that complete the hamacs project.") #+end_src diff --git a/ha-config.org b/ha-config.org index 4a899d9..08bfd7e 100644 --- a/ha-config.org +++ b/ha-config.org @@ -127,48 +127,6 @@ As an example of its use, any Org files loaded in /this project/ should insert m #+begin_src emacs-lisp (ha-auto-insert-file (rx "hamacs/" (one-or-more any) ".org" eol) "hamacs-config") #+end_src -** Request System -The above code needs the [[https://github.com/tkf/emacs-request][request]] package: -#+begin_src emacs-lisp - (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)))))) -#+end_src -*** Dad Jokes! -The /critical part/ here, is the [[https://icanhazdadjoke.com/][Dad Joke]] function, a =curl= call to a web service: -#+begin_src sh - curl -sH "Accept: text/plain" https://icanhazdadjoke.com/ -#+end_src -For this, I use the =request= package, which is /asynchronous/ -#+begin_src emacs-lisp -#+end_src - * Configuration Changes ** Initial Settings and UI Let's turn off the menu and other settings: diff --git a/ha-dashboard.org b/ha-dashboard.org new file mode 100644 index 0000000..6cf133b --- /dev/null +++ b/ha-dashboard.org @@ -0,0 +1,236 @@ +#+TITLE: Start Screen +#+AUTHOR: Howard Abrams +#+DATE: 2022-11-02 +#+FILETAGS: :emacs: + +A literate programming file for configuring Emacs to show a startup screen. + +#+begin_src emacs-lisp :exports none + ;;; ha-dashboard --- show a startup screen. -*- lexical-binding: t; -*- + ;; + ;; © 2022 Howard Abrams + ;; Licensed under a Creative Commons Attribution 4.0 International License. + ;; See http://creativecommons.org/licenses/by/4.0/ + ;; + ;; Author: Howard Abrams + ;; Maintainer: Howard Abrams + ;; Created: November 2, 2022 + ;; + ;; While obvious, GNU Emacs does not include this file or project. + ;; + ;; *NB:* Do not edit this file. Instead, edit the original literate file at: + ;; /Users/howard/other/hamacs/ha-dashboard.org + ;; And tangle the file to recreate this one. + ;; + ;;; Code: + #+end_src +* Left Side +** Dad Jokes! +The /critical part/ of my dashboard, is the [[https://icanhazdadjoke.com/][Dad Joke]] function, a =curl= call to a web service: +#+begin_src sh + curl -sH "Accept: text/plain" https://icanhazdadjoke.com/ +#+end_src + +For this, I use the [[https://github.com/tkf/emacs-request][request]] package (and I’ll use this elsewhere too) and the =dashboard= project (defined below) will incorporate it: +#+begin_src emacs-lisp + (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)))))) +#+end_src +** Dashboard +The [[https://github.com/emacs-dashboard/emacs-dashboard][emacs-dashboard]] project makes a nicer startup screen. +#+begin_src emacs-lisp + (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)) +#+end_src + + This dashboard project requires [[https://github.com/purcell/page-break-lines][page-break-lines]] (which is a nice project): +#+begin_src emacs-lisp + (use-package page-break-lines) +#+end_src + +I would appreciate seeing if my Emacs installation has the features that I expect: +#+begin_src emacs-lisp + (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))) +#+end_src + +* 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. Let’s try the [[https://github.com/mykyta-shyrin/cheatsheet][cheatsheet.el]] project. +#+begin_src emacs-lisp + (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") + '(:key "o" :description "symbol") + '(:key "a" :description "argument") + '(:key "g" :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 "search for symbol (SPC s j/k)"))) + #+end_src +** Learn This +Simple function to display a file in the top-right corner (if the file exists): +#+begin_src emacs-lisp + (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)))) +#+end_src + +* Altogether +The =dashboard= project hooks to [[help:emacs-startup-hook][emacs-startup-hook]] and this =ha-dashboard= function hooks to dashboard’s [[help:dashboard-after-initialize-hook][dashboard-after-initialize-hook]]: + +#+begin_src emacs-lisp + (defun ha-dashboard () + "Shows the extra stuff with the dashboard." + (interactive) + (let ((width (thread-first (window-total-width) + (/ 3) + (* 2)))) + (split-window-right width) + (other-window 1) + (cheatsheet-show) + (ha-show-learn-this))) +#+end_src + +* Technical Artifacts :noexport: + +Let's =provide= a name so we can =require= this file: + +#+begin_src emacs-lisp :exports none + (provide 'ha-dashboard) + ;;; ha-dashboard.el ends here +#+end_src + +#+DESCRIPTION: configuring Emacs to show a startup screen. + +#+PROPERTY: header-args:sh :tangle no +#+PROPERTY: header-args:emacs-lisp :tangle yes +#+PROPERTY: header-args :results none :eval no-export :comments no mkdirp yes + +#+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil date:nil +#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil +#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js diff --git a/ha-display.org b/ha-display.org index ab20986..2300cae 100644 --- a/ha-display.org +++ b/ha-display.org @@ -23,70 +23,12 @@ A literate programming file to configure the Emacs UI. ;; ;;; Code: #+end_src -* Dashboard -The [[https://github.com/emacs-dashboard/emacs-dashboard][emacs-dashboard]] project makes a nicer startup screen. It requires [[https://github.com/purcell/page-break-lines][page-break-lines]] (which is a nice project): -#+begin_src emacs-lisp - (use-package page-break-lines) -#+end_src And let’s make this Emacs look more like a fancy IDE with [[https://github.com/domtronn/all-the-icons.el][all-the-icons]]: #+begin_src emacs-lisp (use-package all-the-icons :if (display-graphic-p)) #+end_src - -#+begin_src emacs-lisp - (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))) - :config - (dashboard-setup-startup-hook) - - (setq dashboard-footer-messages (list (ha--dad-joke)))) -#+end_src - -I would appreciate seeing if my Emacs installation has the features that I expect: -#+begin_src emacs-lisp - (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))) -#+end_src * Mode Line Let's install and load some of packages from the [[https://github.com/hlissner/doom-emacs][Doom Emacs]] project, like [[https://github.com/seagle0128/doom-modeline][doom-modeline]] and maybe the themes: #+begin_src emacs-lisp