Compare commits
No commits in common. "6923e14916b7643f08783ed1aab00412f88b3198" and "f09dcded7c42bf00294d27b6e2618c9e8599d5d3" have entirely different histories.
6923e14916
...
f09dcded7c
15 changed files with 568 additions and 785 deletions
|
@ -43,7 +43,7 @@ Best success comes from using the [[https://github.com/d12frosted/homebrew-emacs
|
|||
|
||||
I find that I need to … at least, on my work computer, install two different versions of Emacs that I use to distinguish one for “work” and the other for other activities, like IRC and [[file:ha-feed-reader.org][elfeed]]. To that end, I run the following command to install Emacs:
|
||||
#+begin_src sh
|
||||
brew install emacs-plus@30 --with-native-comp --with-mailutils --with-imagemagick --with-savchenkovaleriy-big-sur-icon --with-no-frame-refocus --debug
|
||||
brew install emacs-plus@29 --with-native-comp --with-mailutils --with-savchenkovaleriy-big-sur-icon --with-no-frame-refocus --debug
|
||||
#+end_src
|
||||
And if it fails, choose =shell= and type:
|
||||
#+begin_src sh
|
||||
|
@ -130,6 +130,10 @@ And if that doesn’t work, then we need to delete all packages installed by bre
|
|||
* Afterwards
|
||||
After Emacs is /kinda/ working, make sure you install *all* the fonts, that is:
|
||||
#+begin_example
|
||||
M-x all-the-icons-install-fonts
|
||||
#+end_example
|
||||
And to get the Doom Modeline working:
|
||||
#+begin_example
|
||||
M-x nerd-icons-install-fonts
|
||||
#+end_example
|
||||
|
||||
|
|
|
@ -190,7 +190,6 @@ The following /defines/ the rest of my org-mode literate files, that I load late
|
|||
"ha-theme.org"
|
||||
"ha-display.org")
|
||||
"ha-config.org"
|
||||
;; We need to replace ha-general (loaded in config) with:
|
||||
;; "ha-leader.org"
|
||||
"ha-evil.org"
|
||||
;; "ha-meow.org"
|
||||
|
|
|
@ -664,7 +664,7 @@ The [[https://github.com/alexluigit/dirvish][dirvish]] project aims to make a pr
|
|||
#+end_src
|
||||
|
||||
I’m beginning with dirvish to use the [[https://github.com/alexluigit/dirvish/blob/main/docs/CUSTOMIZING.org][sample configuration]] and change it:
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
#+begin_src emacs-lisp
|
||||
(use-package dirvish
|
||||
:straight (:host github :repo "alexluigit/dirvish")
|
||||
:init (dirvish-override-dired-mode)
|
||||
|
|
140
ha-config.org
140
ha-config.org
|
@ -56,9 +56,9 @@ Changes and settings I like introduced in Emacs 28:
|
|||
I’ve got preferences for how I like scrolling, and with my org files, I need a little more of the of the context, so this increases from =2= to =3=, but I like to keep the cursor in place when I can:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq next-screen-context-lines 30
|
||||
scroll-error-top-bottom t
|
||||
scroll-preserve-screen-position t)
|
||||
(setq next-screen-context-lines 3
|
||||
scroll-error-top-bottom t
|
||||
scroll-preserve-screen-position t)
|
||||
#+end_src
|
||||
|
||||
Emacs has some new code to display line-numbers, and the =visual= value works well with my Org files, allowing a jump to a line via ~6 j~:
|
||||
|
@ -364,7 +364,6 @@ The [[https://github.com/minad/marginalia][marginalia]] package gives a preview
|
|||
(add-to-list 'marginalia-command-categories '(project-find-file . file))
|
||||
(marginalia-mode))
|
||||
#+end_src
|
||||
|
||||
* Key Bindings
|
||||
The [[https://github.com/justbur/emacs-which-key][which-key]] project shows a menu of available key-bindings based on what you have already typed. For instance, if you remember that Org Goto function (like most Org-related functions) began with ~C-c~, after typing that sequence, all possible keybindings and their functions are shown. Useful for discovering new features.
|
||||
#+begin_src emacs-lisp
|
||||
|
@ -399,27 +398,23 @@ Pressing the ~SPACE~ can activate a /leader key sequence/ I define in my [[file:
|
|||
#+end_src
|
||||
This extends the =use-package= to include a =:general= keybinding section.
|
||||
|
||||
Since I seldom remember keybindings, or even function names, for major-modes, I pull them all together into a nice table using Jerry Peng’s [[https://github.com/jerrypnz/major-mode-hydrajjj0.el][Major Mode Hydra]] project:
|
||||
|
||||
Since I seldom remember keybindings, or even function names, for major-modes, I pull them all together into a nice table using the [[https://github.com/jerrypnz/major-mode-hydrajjj0.el][Major Mode Hydra]] project:
|
||||
#+begin_src emacs-lisp
|
||||
(use-package major-mode-hydra
|
||||
:bind ("s-," . major-mode-hydra)
|
||||
:init
|
||||
(defun major-mode-hydra-title (&optional mode)
|
||||
"Create a pleasant-looking title for MODE."
|
||||
(let ((mode-str (cond
|
||||
((null mode) (pp-to-string major-mode))
|
||||
((symbolp mode) (symbol-name mode))
|
||||
(t (pp-to-string major-mode)))))
|
||||
(thread-last mode-str
|
||||
(string-replace "-" " ")
|
||||
(string-replace " mode" "")
|
||||
(s-titleize))))
|
||||
:config
|
||||
(global-set-key (kbd "s-,") 'major-mode-hydra)
|
||||
|
||||
(defvar major-mode-hydra-title-generator
|
||||
'(lambda (&optional mode)
|
||||
(let ((title (major-mode-hydra-title mode)))
|
||||
(concat "ϻ " title " Commands")))))
|
||||
(setq major-mode-hydra-title-generator
|
||||
'(lambda (mode)
|
||||
(if (symbolp mode)
|
||||
(setq mode (symbol-name mode))
|
||||
(setq mode (pp-to-string mode)))
|
||||
|
||||
(let ((title (thread-last mode
|
||||
(string-replace "-" " ")
|
||||
(string-replace " mode" "")
|
||||
(s-titleize))))
|
||||
(concat "ϻ " title " Commands")))))
|
||||
#+end_src
|
||||
|
||||
Scattered throughout my configuration, I use =major-mode-hydra-define= where I’m configuring that mode. For instance, for the built-in Info, I can make:
|
||||
|
@ -711,11 +706,10 @@ While I grew up on =Control S=, I am liking the /mental model/ associated with t
|
|||
(:states 'normal "go" '("avy goto" . avy-goto-char-timer)
|
||||
"s" '("avy word" . avy-goto-subword-1))
|
||||
|
||||
:bind (("<f18>" . avy-goto-char-timer)
|
||||
("s-g" . avy-goto-char-timer)
|
||||
("s-e" . avy-next)
|
||||
("s-a" . avy-prev)
|
||||
:map isearch-mode-map ("s-g" . avy-isearch)))
|
||||
:bind ("<f18>" . avy-goto-char-timer)
|
||||
("s-g" . avy-goto-char-timer)
|
||||
("s-;" . avy-next)
|
||||
("s-a" . avy-prev))
|
||||
#+end_src
|
||||
*Note:* The links should be shorter near the point as opposed to starting from the top of the window.
|
||||
|
||||
|
@ -776,90 +770,15 @@ Magnar Sveen's [[https://github.com/magnars/expand-region.el][expand-region]] pr
|
|||
"-" 'er/contract-region))
|
||||
#+end_src
|
||||
*** iSearch
|
||||
The built-in =isearch= is fantastically simple and useful, bound to ~C-s~, but why not bind searching for the current symbol?
|
||||
The built-in =isearch= is fantastically simple and useful, but the [[https://github.com/kickingvegas/cc-isearch-menu][cc-isearch-menu]] helps expose some /buried/ features.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(global-set-key (kbd "m-s m-s") 'isearch-forward-thing-at-point)
|
||||
#+END_SRC
|
||||
|
||||
I like Charles Choi’s [[https://github.com/kickingvegas/casual][Casual Suite]], and his original [[https://github.com/kickingvegas/cc-isearch-menu][cc-isearch-menu]] was great at seeing the /buried/ features. I’ve duplicated the features using [[https://github.com/jerrypnz/major-mode-hydra.el][pretty-hydra]]. In the middle of a search, type ~⌘-s~ (Command-s), and menu of options I don’t remember appear.
|
||||
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(defvar ha-isearch--title (font-icons 'faicon "magnifying_glass"
|
||||
:title "Search Options"))
|
||||
|
||||
(pretty-hydra-define isearch-mode
|
||||
(:color amaranth :quit-key "C-s" :title ha-isearch--title)
|
||||
("Movement"
|
||||
(("n" isearch-repeat-forward "Forward")
|
||||
("p" isearch-repeat-backward "Backward")
|
||||
("j" avy-isearch "Jump" :color blue))
|
||||
"Expand"
|
||||
((">" isearch-yank-symbol-or-char "Full symbol")
|
||||
("z" isearch-yank-until-char "Until char")
|
||||
("$" isearch-yank-line "Full line"))
|
||||
"Replace"
|
||||
(("R" isearch-query-replace "Literal")
|
||||
("Q" isearch-query-replace-regexp "Regexp")
|
||||
("<return>" isearch-exit "Stay" :color blue))
|
||||
"Toggles"
|
||||
(("w" isearch-toggle-word "Word only" :toggle t)
|
||||
("s" isearch-toggle-symbol "Full symbol" :toggle t)
|
||||
("r" isearch-toggle-regexp "Regexp" :toggle t)
|
||||
("c" isearch-toggle-case-fold "Case Sensitive" :toggle t))
|
||||
"Highlight"
|
||||
(("H" isearch-highlight-regexp "Matches" :color blue)
|
||||
("L" isearch-highlight-lines-matching-regexp "Lines" :color blue))
|
||||
"Other"
|
||||
(("e" isearch-edit-string "Edit")
|
||||
("o" isearch-occur "Occur" :color blue)
|
||||
("C-g" isearch-abort "Abort" :color blue))))
|
||||
|
||||
(define-key isearch-mode-map (kbd "s-s") 'isearch-mode/body)
|
||||
#+begin_src emacs-lisp
|
||||
(use-package cc-isearch-menu
|
||||
:straight (:host github :repo "kickingvegas/cc-isearch-menu")
|
||||
:bind (:map isearch-mode-map ("s-g" . cc-isearch-menu-transient)))
|
||||
#+end_src
|
||||
|
||||
Pressing ~C-g~ aborts, and ~Return~ exits leaving the point in place. Typing ~C-s~ in the menu stops the menu to continue searching.
|
||||
|
||||
[[file:screenshots/isearch-hydra.png]]
|
||||
|
||||
How did I figure out the available bindings to make this? To see /all/ the bindings, start the =isearch= minor mode (using ~C-s~), then type ~F1~ twice. This fancy feature lets you select ~b~ to see all the keybindings (along with other features).
|
||||
*** Bookmarks
|
||||
I like the idea of dropping returnable bookmarks, but with /good defaults/ for the names of these global bookmarks:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun ha-bookmark-label-default ()
|
||||
"Return label for bookmarks based on thing-at-point."
|
||||
(concat
|
||||
(if-let ((filename (buffer-file-name)))
|
||||
(thread-last filename
|
||||
(string-replace (getenv "HOME") "~")
|
||||
(format "%s: ")))
|
||||
(which-function)))
|
||||
|
||||
;; (equal (ha-bookmark-label-default) "~/src/hamacs/ha-config.org :: Bookmarks")
|
||||
|
||||
(defun ha-bookmark-set (args)
|
||||
"Drop a bookmark based on the current context.
|
||||
If ARGS is non-nil, prompt for the bookmark's label.
|
||||
Replaces `bookmark-set'."
|
||||
(interactive "P")
|
||||
(let* ((default (ha-bookmark-label-default))
|
||||
(label (if args
|
||||
(read-string "Bookmark label: " default)
|
||||
default)))
|
||||
(bookmark-set label)))
|
||||
#+END_SRC
|
||||
|
||||
The built-in behavior doesn’t honor either /projects/ or /perspectives/, but I use [[https://codeberg.org/ideasman42/emacs-bookmark-in-project][bookmark-in-project]] package to make a =project=-specific bookmarks and use that to jump to only bookmarks in the current project.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package bookmark-in-project
|
||||
:bind
|
||||
(("C-x r m" . bookmark-in-project-toggle)
|
||||
("C-x r M" . ha-bookmark-set)))
|
||||
#+END_SRC
|
||||
|
||||
|
||||
The idea, is that you can start a search with ~C-s~ (or even ~s-f~ … er, ~Command-f~ on the Mac), and type some letters. Hitting ~C-s~ goes to the next occurrence of what you’ve typed, but if you hit ~Command-g~, a menu appears allowing you to pull in the rest of the word or symbol you are looking at, or edit it completely.
|
||||
** Minor Keybinding Annoys
|
||||
I like ~C-a~ to go to the beginning of the line, but what about getting to the beginning of text on that line? In Evil, you have ~^~ for beginning of line, and ~0~ for first text. Why not have ~C-a~ toggle between them both:
|
||||
|
||||
|
@ -869,7 +788,7 @@ I like ~C-a~ to go to the beginning of the line, but what about getting to the b
|
|||
(interactive "^p")
|
||||
(if (= (point) (line-beginning-position))
|
||||
(beginning-of-line-text n)
|
||||
(beginning-of-line n)))
|
||||
(beginning-of-line n)))
|
||||
|
||||
(global-set-key (kbd "C-a") 'ha-beginning-of-line)
|
||||
#+end_src
|
||||
|
@ -940,7 +859,7 @@ Build the hydra as well as configure the =perspective= project.
|
|||
:config
|
||||
(setq persp-suppress-no-prefix-key-warning t)
|
||||
|
||||
(persp-mode)
|
||||
(persp-mode +1)
|
||||
|
||||
(defhydra hydra-workspace-leader (:color blue :hint nil) "
|
||||
Workspaces- %s(ha-persp-labels)
|
||||
|
@ -1002,7 +921,6 @@ I often want a workspace dedicated to an /application/, so this function:
|
|||
|
||||
#+begin_src emacs-lisp
|
||||
(defun ha-app-perspective (name func)
|
||||
"Generate new perspective NAME, automatically running FUNC."
|
||||
(lambda ()
|
||||
(interactive)
|
||||
(let ((already-started? (seq-contains-p (persp-names) name 'equal)))
|
||||
|
|
|
@ -71,8 +71,10 @@ I would appreciate seeing if my Emacs installation has the features that I expec
|
|||
If NON-ICONIC is non-nil, return a string of text only."
|
||||
(interactive)
|
||||
|
||||
(defun feature-combo (container icon title)
|
||||
(font-icons container icon :title title :height 1.3 :v-adjust -0.1))
|
||||
(defun feature-combo (icon title)
|
||||
(if (or non-iconic (null icon))
|
||||
title
|
||||
(format "%s—%s" icon title)))
|
||||
|
||||
(defun all-images ()
|
||||
(s-join "·"
|
||||
|
@ -86,48 +88,35 @@ I would appreciate seeing if my Emacs installation has the features that I expec
|
|||
(when (image-type-available-p 'png) "PNG")))))
|
||||
|
||||
(let* ((features
|
||||
(list
|
||||
;; An either or ... at least for me:
|
||||
(when (eq (window-system) 'ns)
|
||||
(feature-combo 'faicon "apple" "MacOS"))
|
||||
(when (eq (window-system) 'pgtk)
|
||||
(feature-combo 'faicon "xing" "Gnome"))
|
||||
|
||||
;; Important to know if I have it:
|
||||
(when (and (fboundp 'native-comp-available-p)
|
||||
(native-comp-available-p))
|
||||
(feature-combo 'faicon "cog" "Native Compilation"))
|
||||
(when (treesit-available-p)
|
||||
(feature-combo 'faicon "tree" "Tree Sitter"))
|
||||
(when (sqlite-available-p)
|
||||
(feature-combo 'faicon "database" "Sqlite"))
|
||||
(when (gnutls-available-p)
|
||||
(feature-combo 'faicon "expeditedssl" "TLS"))
|
||||
|
||||
;; Did we build with mail utilities? Check the command line
|
||||
;; options we used to build Emacs:
|
||||
(when (or (string-search "with-mailutils" system-configuration-options)
|
||||
(string-search "without-pop" system-configuration-options))
|
||||
(feature-combo 'octicon "mail" "GNU Mail"))
|
||||
|
||||
(when (fboundp 'make-xwidget)
|
||||
(feature-combo 'mdicon "widgets" "XWidgets"))
|
||||
|
||||
;; This suffix of loadable module files will be nil if
|
||||
;; modules are not supported:
|
||||
(when module-file-suffix ; or (fboundp 'module-load)
|
||||
(feature-combo 'faicon "th" "Modules"))
|
||||
|
||||
(when (json-available-p)
|
||||
(feature-combo 'codicon "json" "JSON"))
|
||||
|
||||
(when (string-search "HARFBUZZ" system-configuration-features)
|
||||
(feature-combo 'faicon "font" "HARFBUZZ"))
|
||||
(when (string-search "DBUS" system-configuration-features)
|
||||
(feature-combo 'faicon "bus" "DBUS"))
|
||||
(feature-combo 'faicon "picture-o" (all-images))
|
||||
(when (fboundp 'imagemagick-types)
|
||||
(feature-combo 'faicon "magic" "ImageMagick"))))
|
||||
(list (when (and (fboundp 'native-comp-available-p)
|
||||
(native-comp-available-p))
|
||||
(feature-combo (all-the-icons-faicon "cog") "Native Compilation"))
|
||||
(when (eq (window-system) 'ns)
|
||||
(feature-combo (all-the-icons-faicon "apple") "MacOS"))
|
||||
(when (eq (window-system) 'pgtk)
|
||||
(feature-combo (all-the-icons-faicon "xing") "Gnome"))
|
||||
(when (treesit-available-p)
|
||||
(feature-combo (all-the-icons-faicon "tree") "Tree Sitter"))
|
||||
(when (sqlite-available-p)
|
||||
(feature-combo (all-the-icons-faicon "database") "Sqlite"))
|
||||
(when (gnutls-available-p)
|
||||
(feature-combo (all-the-icons-faicon "expeditedssl") "TLS"))
|
||||
(when (or (string-search "with-mailutils" system-configuration-options)
|
||||
(string-search "without-pop" system-configuration-options))
|
||||
(feature-combo (all-the-icons-material "mail") "GNU Mail"))
|
||||
(when (fboundp 'make-xwidget)
|
||||
(feature-combo (all-the-icons-material "widgets") "XWidgets"))
|
||||
(when module-file-suffix ; or (fboundp 'module-load)
|
||||
(feature-combo (all-the-icons-faicon "th") "Modules"))
|
||||
(when (json-available-p)
|
||||
(feature-combo (all-the-icons-fileicon "config-js") "JSON"))
|
||||
(when (string-search "HARFBUZZ" system-configuration-features)
|
||||
(feature-combo (all-the-icons-faicon "font") "HARFBUZZ"))
|
||||
(when (string-search "DBUS" system-configuration-features)
|
||||
(feature-combo (all-the-icons-faicon "bus") "DBUS"))
|
||||
(feature-combo (all-the-icons-faicon "picture-o") (all-images))
|
||||
(when (fboundp 'imagemagick-types)
|
||||
(feature-combo (all-the-icons-faicon "magic") "ImageMagick"))))
|
||||
(results (s-join " " (-remove 'null features))))
|
||||
|
||||
(if (called-interactively-p)
|
||||
|
|
655
ha-demos.org
655
ha-demos.org
|
@ -59,303 +59,7 @@ But I feel I should replace it, and this project encapsulates the following goal
|
|||
|
||||
* Presentations with Org
|
||||
A demonstration begins with an Org file where the screen shows a /single heading/ with a larger font. Not much more. I’m playing around with /all/ the projects available, including writing my own.
|
||||
** My Presentation Views
|
||||
Regardless of the presentation package I use, I make them all look similar with the following code. Much of this is getting rid of Emacs visual elements, like the cursor and the mode-line, as well as stopping minor modes that add visual changes, like spellchecking and the gutter. I can call this function from any presentation software used.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun ha-slide-setup (&optional frame-name)
|
||||
"Configure the look I want for presentations.
|
||||
The frame associated with FRAME-NAME is tidied
|
||||
by removing the gutters and other informative
|
||||
widgets not needed for a presentation."
|
||||
(org-indent-mode -1)
|
||||
;; (org-modern-mode -1)
|
||||
|
||||
(setq org-image-actual-width nil)
|
||||
(org-display-inline-images)
|
||||
(ha-org-blocks-hide-headers)
|
||||
;; (ha-org-hide-stars)
|
||||
(font-lock-update)
|
||||
(ha-demo-hide-mode-line)
|
||||
(ha-demo-hide-cursor)
|
||||
(ha-demo-presentation-frame frame-name)
|
||||
|
||||
(ha-set-favorite-font-size 42) ; instead of (text-scale-set 4)
|
||||
|
||||
(diff-hl-mode -1)
|
||||
(flycheck-mode -1)
|
||||
(jinx-mode -1)
|
||||
|
||||
;; Clear the demonstration state cache:
|
||||
(clrhash ha-demo-prev-state)
|
||||
|
||||
(evil-normal-state))
|
||||
#+END_SRC
|
||||
|
||||
And after a presentation finishes, this function cleans up by restoring minor modes, etc:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun ha-slide-teardown ()
|
||||
"Reset the Org after a presentation."
|
||||
(org-indent-mode 1)
|
||||
;; (org-modern-mode 1)
|
||||
|
||||
(ha-org-blocks-show-headers)
|
||||
(font-lock-update)
|
||||
(ha-demo-show-mode-line)
|
||||
(ha-demo-show-cursor)
|
||||
(ha-demo-normalize-frame)
|
||||
|
||||
(ha-mac-monitor-fontsize) ; (text-scale-set 0)
|
||||
(diff-hl-mode)
|
||||
(flycheck-mode)
|
||||
(jinx-mode))
|
||||
#+END_SRC
|
||||
|
||||
The =dslide= seems to reset /everything/ on each slide display, so:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun ha-slide-reset ()
|
||||
"Reset the current slide."
|
||||
(interactive)
|
||||
(ha-org-blocks-hide-headers)
|
||||
(font-lock-update))
|
||||
#+END_SRC
|
||||
|
||||
** Org Tree Slide
|
||||
I’ve used [[https://github.com/takaxp/org-tree-slide][org-tree-slide]] for years for showing org files as presentations. I like the /simple/ presentation and it seems to shows all the images.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp :tangle no
|
||||
(use-package org-tree-slide
|
||||
:config
|
||||
(setq org-tree-slide-heading-emphasis nil
|
||||
org-tree-slide-activate-message "† This demonstration is running in Emacs"
|
||||
org-tree-slide-indicator '(:next nil :previous nil :content nil)
|
||||
org-tree-slide-cursor-init nil)
|
||||
(org-tree-slide-simple-profile)
|
||||
|
||||
:bind
|
||||
(:map org-tree-slide-mode-map
|
||||
;; ("<f5>" . org-tree-slide-move-next-tree)
|
||||
;; ("S-<f5>" . org-tree-slide-move-previous-tree)
|
||||
("M-<f5>" . org-tree-slide-content)
|
||||
("C-<f5>" . (lambda () (interactive) (org-tree-slide-mode -1))))
|
||||
|
||||
:general
|
||||
(:states 'normal :keymaps 'org-tree-slide-mode-map
|
||||
"C" #'ha-demo-toggle-cursor
|
||||
"n" #'org-tree-slide-move-next-tree
|
||||
"p" #'org-tree-slide-move-previous-tree
|
||||
"Q" (lambda () (interactive) (org-tree-slide-mode -1)))
|
||||
|
||||
:hook
|
||||
((org-tree-slide-play . ha-slide-setup)
|
||||
(org-tree-slide-stop . ha-slide-teardown)))
|
||||
#+END_SRC
|
||||
** Org Present
|
||||
Converted to use [[https://github.com/rlister/org-present][org-present]]. I love the /hooks/ as that makes it easier to handle. My problem with =org-present= is that it doesn’t always display images based on how it handles overlays.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package org-present
|
||||
:config
|
||||
(defvar ha-org-present-mode-line mode-line-format
|
||||
"Cache previous mode-line format state")
|
||||
|
||||
:bind
|
||||
(:map org-present-mode-keymap
|
||||
;; ("<f5>" . org-present-next)
|
||||
;; ("S-<f5>" . org-present-previous)
|
||||
("C-<f5>" . org-present-quit))
|
||||
|
||||
:general
|
||||
(:states 'normal :keymaps 'org-present-mode-keymap
|
||||
"+" #'org-present-big
|
||||
"-" #'org-present-small
|
||||
"<" #'org-present-beginning
|
||||
">" #'org-present-end
|
||||
"c" #'org-present-hide-cursor
|
||||
"C" #'org-present-show-cursor
|
||||
"n" #'org-present-next
|
||||
"j" #'org-present-next
|
||||
"k" #'org-present-prev
|
||||
"p" #'org-present-prev
|
||||
"r" #'org-present-read-only
|
||||
"w" #'org-present-read-write
|
||||
"Q" #'org-present-quit)
|
||||
|
||||
:hook
|
||||
(org-present-mode . ha-slide-setup)
|
||||
(org-present-mode-quit . ha-slide-teardown))
|
||||
#+end_src
|
||||
** DSlide
|
||||
The [[https://github.com/positron-solutions/dslide][dslide project]] is flexible, interesting, and can perform actions based on blocks /in the slide/ as opposed to my previous approaches of having external control.
|
||||
|
||||
With some a startup bug that I haven’t been able to resolve, I’m not using it =dslide= at moment.
|
||||
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(use-package dslide
|
||||
:straight (dslide :host github :repo "positron-solutions/dslide")
|
||||
:commands (dslide-deck-start dslide-deck-stop)
|
||||
:custom
|
||||
(dslide-start-from 'point)
|
||||
;; Let's keep our presentations simple:
|
||||
(dslide-slide-in-effect nil)
|
||||
(dslide-header nil)
|
||||
(dslide-header-date nil)
|
||||
(dslide-header-author nil)
|
||||
(dslide-header-email nil)
|
||||
(dslide-breadcrumb-separator nil)
|
||||
|
||||
:general
|
||||
(:states 'normal :no-autoload t :keymaps 'dslide-mode-map
|
||||
"q" '("quit presentation" . dslide-deck-stop)
|
||||
"<left>" '("previous slide" . dslide-deck-backward)
|
||||
"<right>" '("next slide" . dslide-deck-forward)
|
||||
"C" '("show cursor" . ha-demo-show-cursor)
|
||||
"c" '("hide cursor" . ha-demo-hide-cursor)
|
||||
"<up>" '("previous slide" . previous-line)
|
||||
"<down>" '("next slide" . next-line))
|
||||
|
||||
:bind
|
||||
(:map dslide-mode-map
|
||||
;; ("<f5>" . ha-dslide-deck-forward)
|
||||
;; ("S-<f5>" . ha-dslide-deck-backward)
|
||||
("C-<f5>" . dslide-deck-stop))
|
||||
|
||||
:hook ((dslide-start . ha-slide-setup)
|
||||
;; (dslide-narrow . ha-slide-reset)
|
||||
(dslide-stop . ha-slide-teardown)))
|
||||
#+end_src
|
||||
|
||||
Let’s try it out by loading this example.[[file:~/.emacs.d/straight/repos/dslide/test/demo.org][ demo.org]]
|
||||
|
||||
What features do I like and want to take advantage of?
|
||||
- Inline Children show: =:DSLIDE_SLIDE_ACTION: dslide-slide-action-inline=
|
||||
- Flat Slide (shows children section immediately): =:DSLIDE_SLIDE_ACTION: dslide-slide-action-flat=
|
||||
- Show images only? I guess we could use my own thing, but it is nice and easy: =:DSLIDE_ACTIONS: dslide-action-image :slide-display nil=
|
||||
- No header slides: =:DSLIDE_SLIDE_ACTION: dslide-slide-action-child :header nil=
|
||||
- Re-execute Babel blocks: =:DSLIDE_SLIDE_ACTION: dslide-slide-babel=
|
||||
- Hiding Blocks
|
||||
- Results Only
|
||||
|
||||
Fixes and improvements for the dslide:
|
||||
|
||||
Call the =ha-slide-notes-update= function automatically after updating a slide. With =dslide=, we add a hook:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp :tangle no
|
||||
(use-package dslide
|
||||
:straight (dslide :host github :repo "positron-solutions/dslide")
|
||||
:commands (dslide-narrow-hook)
|
||||
:hook (dslide-narrow . 'ha-slide-notes-update))
|
||||
#+END_SRC
|
||||
|
||||
*** Master of Ceremonies
|
||||
The [[https://github.com/positron-solutions/moc][Master of Ceremonies]] package (moc) is to help when recording Emacs screens. Early in development, but it looks to have some potential. Not sure how to use it yet.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp :tangle no
|
||||
(use-package default-text-scale)
|
||||
|
||||
(use-package moc
|
||||
:straight (:type git :host github
|
||||
:repo "positron-solutions/moc"))
|
||||
#+END_SRC
|
||||
|
||||
Select text, and call =moc-focus= (call =moc-focus-quit= to stop). Highlight more text, and call =moc-focus-highlight= to brighten it, or =moc-focus-obscure= to hide it.
|
||||
|
||||
The =moc-screenshot= seems to only work on Linux.
|
||||
|
||||
An interesting approach for making presentations, that I’m not sure I will need.
|
||||
|
||||
*** TopSpace
|
||||
|
||||
The [[https://github.com/trevorpogue/topspace][topspace]] project can pad the top of a buffer, to make the first line in the center of the window. Helpful for presentations:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package topspace
|
||||
:straight (:type git :host github :repo "trevorpogue/topspace"))
|
||||
#+END_SRC
|
||||
|
||||
*** Showing Something associated with a Headline
|
||||
:PROPERTIES:
|
||||
:DSLIDE_ACTIONS: dslide-action-babel
|
||||
:END:
|
||||
|
||||
When I give a /demonstration/ (uising my [[New Demonstration]] project), I could, instead, use a custom =dslide= action.
|
||||
|
||||
But how would I get it to close? Maybe we use a combination of actions and my “demo” code for everything else?
|
||||
|
||||
*Note:* Code blocks with =exports= set to =none= are not displayed.
|
||||
|
||||
#+begin_src elisp :tangle no :exports none :results none :eval no
|
||||
(ha-demo-show-file "ha-org.org" :position 'right
|
||||
:focus 'presentation :heading "Meetings"
|
||||
:shift 0)
|
||||
#+end_src
|
||||
|
||||
#+BEGIN_SRC emacs-lisp :tangle no :exports none :results none :eval no
|
||||
(ha-demo-highlight-buffer :buffer "ha-org.org"
|
||||
:hi-lines "268-274")
|
||||
#+END_SRC
|
||||
|
||||
#+begin_src elisp :tangle no :exports none :results none
|
||||
(delete-other-windows)
|
||||
#+end_src
|
||||
|
||||
*** Bullet/Paragraph Highlighting
|
||||
I would like to highlight a bullet point or a paragraph while talking.
|
||||
To do this, add =:DSLIDE_ACTIONS: dslide-action-highlight-paragraphs= to the properties of a section.
|
||||
|
||||
#+begin_src elisp emacs-lisp :tangle no
|
||||
(use-package dslide
|
||||
:straight (:host github :repo "positron-solutions/dslide")
|
||||
:config
|
||||
(defclass dslide-action-highlight-paragraphs (dslide-action)
|
||||
((overlays :initform nil))
|
||||
"Paint the paragraphs with the highlight color, one by one.")
|
||||
|
||||
;; In this case, the Default no-op `dslide-begin' works.
|
||||
;; Default implementation of `dslide-end', plays forward to the end.
|
||||
|
||||
;; Remove any remaining overlays when calling final.
|
||||
(cl-defmethod dslide-final :after ((obj dslide-action-highlight-paragraphs))
|
||||
(mapc #'delete-overlay (oref obj overlays)))
|
||||
|
||||
;; Find the next paragraph and add an overlay if it exists
|
||||
(cl-defmethod dslide-forward ((obj dslide-action-highlight-paragraphs))
|
||||
;; This line removes all overlays allowing us to highlight a new one.
|
||||
;; Remove this if you want the paragraphs to _linger_.
|
||||
(mapc #'delete-overlay (oref obj overlays))
|
||||
(when-let ((paragraph (dslide-section-next obj 'paragraph)))
|
||||
(let* ((beg (org-element-property :begin paragraph))
|
||||
(end (org-element-property :end paragraph))
|
||||
(new-overlay (make-overlay beg end)))
|
||||
(overlay-put new-overlay 'face 'highlight)
|
||||
(push new-overlay (oref obj overlays))
|
||||
;; Return non-nil indicates we made progress. This also informs the
|
||||
;; highlight when following the slides in the base buffer.
|
||||
beg)))
|
||||
|
||||
(cl-defmethod dslide-backward ((obj dslide-action-highlight-paragraphs))
|
||||
(when-let* ((overlay (pop (oref obj overlays))))
|
||||
(delete-overlay overlay)
|
||||
;; If there is a preceding overlay, move to its beginning else move to the
|
||||
;; beginning of the heading.
|
||||
(if-let ((overlay (car (oref obj overlays))))
|
||||
(dslide-marker obj (overlay-start overlay))
|
||||
(dslide-marker obj (org-element-property :begin (dslide-heading obj)))))))
|
||||
#+end_src
|
||||
*** Custom Action Demo
|
||||
:PROPERTIES:
|
||||
:DSLIDE_ACTIONS: dslide-action-highlight-paragraphs
|
||||
:END:
|
||||
Phasellus at dui in ligula mollis ultricies. Phasellus lacus. Fusce commodo. Nulla posuere. Nunc rutrum turpis sed pede. Pellentesque tristique imperdiet tortor. Nullam libero mauris, consequat quis, varius et, dictum id, arcu. Phasellus lacus. Sed diam. Nullam tristique diam non turpis.
|
||||
|
||||
* Donec vitae dolor.
|
||||
* Fusce commodo.
|
||||
* Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|
||||
|
||||
Nunc porta vulputate tellus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec posuere augue in quam. Sed id ligula quis est convallis tempor. Integer placerat tristique nisl. Nunc rutrum turpis sed pede. Nullam rutrum. Sed id ligula quis est convallis tempor.
|
||||
** My Presentation Notes View
|
||||
** My Slides
|
||||
A /full/ presentation requires my /notes/ on one frame, and the presentation on the other.
|
||||
|
||||
To use this, following:
|
||||
|
@ -434,56 +138,332 @@ These interactive functions scroll the “notes” in the other window in anothe
|
|||
(recenter-top-bottom 0)))))
|
||||
#+end_src
|
||||
|
||||
** My Presentation Interface
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defvar ha-slide-presentation nil
|
||||
"The buffer name of the starting presentation.")
|
||||
Call the =ha-slide-notes-update= function automatically after updating a slide. With =dslide=, we add a hook:
|
||||
|
||||
(defun ha-slide-deck-start (&optional initial-heading)
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package dslide
|
||||
:straight (dslide :host github :repo "positron-solutions/dslide")
|
||||
:commands (dslide-narrow-hook)
|
||||
:hook (dslide-narrow . 'ha-slide-notes-update))
|
||||
#+END_SRC
|
||||
|
||||
** My Presentation View
|
||||
Regardless of the presentation package I use, I make them all look similar with the following code. Much of this is getting rid of Emacs visual elements, like the cursor and the mode-line, as well as stopping minor modes that add visual changes, like spellchecking and the gutter. I can call this function from any presentation software used.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun ha-slide-setup (&optional frame-name)
|
||||
"Configure the look I want for presentations.
|
||||
The frame associated with FRAME-NAME is tidied
|
||||
by removing the gutters and other informative
|
||||
widgets not needed for a presentation."
|
||||
(org-indent-mode -1)
|
||||
;; (org-modern-mode -1)
|
||||
|
||||
(setq org-image-actual-width nil)
|
||||
(org-display-inline-images)
|
||||
(ha-org-blocks-hide-headers)
|
||||
(ha-org-hide-stars)
|
||||
(font-lock-update)
|
||||
(ha-demo-hide-mode-line)
|
||||
(ha-demo-hide-cursor)
|
||||
(ha-demo-presentation-frame frame-name)
|
||||
|
||||
(text-scale-set 4)
|
||||
(diff-hl-mode -1)
|
||||
(flycheck-mode -1)
|
||||
(jinx-mode -1)
|
||||
|
||||
;; Clear the demonstration state cache:
|
||||
(clrhash ha-demo-prev-state)
|
||||
|
||||
(evil-normal-state))
|
||||
#+END_SRC
|
||||
|
||||
And after a presentation finishes, this function cleans up by restoring minor modes, etc:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun ha-slide-teardown ()
|
||||
"Reset the Org after a presentation."
|
||||
(org-indent-mode 1)
|
||||
;; (org-modern-mode 1)
|
||||
|
||||
(ha-org-blocks-show-headers)
|
||||
(font-lock-update)
|
||||
(ha-demo-show-mode-line)
|
||||
(ha-demo-show-cursor)
|
||||
(ha-demo-normalize-frame)
|
||||
|
||||
(text-scale-set 0)
|
||||
(diff-hl-mode)
|
||||
(flycheck-mode)
|
||||
(jinx-mode))
|
||||
#+END_SRC
|
||||
|
||||
The =dslide= seems to reset /everything/ on each slide display, so:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun ha-slide-reset ()
|
||||
"Reset the current slide."
|
||||
(interactive)
|
||||
(ha-org-blocks-hide-headers)
|
||||
(font-lock-update))
|
||||
#+END_SRC
|
||||
|
||||
** Org Tree Slide
|
||||
I’ve used [[https://github.com/takaxp/org-tree-slide][org-tree-slide]] for years for showing org files as presentations. I like the /simple/ presentation and it seems to shows all the images.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp :tangle no
|
||||
(use-package org-tree-slide
|
||||
:config
|
||||
(setq org-tree-slide-heading-emphasis nil
|
||||
org-tree-slide-activate-message "† This demonstration is running in Emacs"
|
||||
org-tree-slide-indicator '(:next nil :previous nil :content nil)
|
||||
org-tree-slide-cursor-init nil)
|
||||
(org-tree-slide-simple-profile)
|
||||
|
||||
:bind
|
||||
(:map org-tree-slide-mode-map
|
||||
("<f5>" . org-tree-slide-move-next-tree)
|
||||
("S-<f5>" . org-tree-slide-move-previous-tree)
|
||||
("M-<f5>" . org-tree-slide-content)
|
||||
("C-<f5>" . (lambda () (interactive) (org-tree-slide-mode -1))))
|
||||
|
||||
:general
|
||||
(:states 'normal :keymaps 'org-tree-slide-mode-map
|
||||
"C" #'ha-demo-toggle-cursor
|
||||
"n" #'org-tree-slide-move-next-tree
|
||||
"N" #'org-tree-slide-move-previous-tree
|
||||
"Q" (lambda () (interactive) (org-tree-slide-mode -1)))
|
||||
|
||||
:hook
|
||||
((org-tree-slide-play . ha-slide-setup)
|
||||
(org-tree-slide-stop . ha-slide-teardown)))
|
||||
#+END_SRC
|
||||
** Org Present
|
||||
Converted to use [[https://github.com/rlister/org-present][org-present]]. I love the /hooks/ as that makes it easier to handle. My problem with =org-present= is that it doesn’t always display images based on how it handles overlays.
|
||||
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(use-package org-present
|
||||
:config
|
||||
(defvar ha-org-present-mode-line mode-line-format
|
||||
"Cache previous mode-line format state")
|
||||
|
||||
:bind
|
||||
(:map org-present-mode-keymap
|
||||
("<f5>" . org-present-next)
|
||||
("S-<f5>" . org-present-previous)
|
||||
("C-<f5>" . org-present-quit))
|
||||
|
||||
:general
|
||||
(:states 'normal :keymaps 'org-present-mode-keymap
|
||||
"+" #'org-present-big
|
||||
"-" #'org-present-small
|
||||
"<" #'org-present-beginning
|
||||
">" #'org-present-end
|
||||
"c" #'org-present-hide-cursor
|
||||
"C" #'org-present-show-cursor
|
||||
"n" #'org-present-next
|
||||
"j" #'org-present-next
|
||||
"k" #'org-present-prev
|
||||
"p" #'org-present-prev
|
||||
"r" #'org-present-read-only
|
||||
"w" #'org-present-read-write
|
||||
"Q" #'org-present-quit)
|
||||
|
||||
:hook
|
||||
(org-present-mode . ha-slide-setup)
|
||||
(org-present-mode-quit . ha-slide-teardown))
|
||||
#+end_src
|
||||
** DSlide
|
||||
The [[https://github.com/positron-solutions/dslide][dslide project]] is flexible, interesting, and can run code.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package dslide
|
||||
:straight (dslide :host github :repo "positron-solutions/dslide")
|
||||
:commands (dslide-deck-start dslide-deck-stop)
|
||||
:custom
|
||||
(dslide-start-from 'point)
|
||||
;; Let's keep our presentations simple:
|
||||
(dslide-slide-in-effect nil)
|
||||
(dslide-header nil)
|
||||
(dslide-header-date nil)
|
||||
(dslide-header-author nil)
|
||||
(dslide-header-email nil)
|
||||
(dslide-breadcrumb-separator nil)
|
||||
|
||||
:general
|
||||
(:states 'normal :no-autoload t :keymaps 'dslide-mode-map
|
||||
"q" '("quit presentation" . dslide-deck-stop)
|
||||
"<left>" '("previous slide" . dslide-deck-backward)
|
||||
"<right>" '("next slide" . dslide-deck-forward)
|
||||
"C" '("show cursor" . ha-demo-show-cursor)
|
||||
"c" '("hide cursor" . ha-demo-hide-cursor)
|
||||
"<up>" '("previous slide" . previous-line)
|
||||
"<down>" '("next slide" . next-line))
|
||||
|
||||
:bind
|
||||
("C-<f5>" . ha-dslide-deck-start)
|
||||
(:map dslide-mode-map
|
||||
("<f5>" . ha-dslide-deck-forward)
|
||||
("S-<f5>" . ha-dslide-deck-backward)
|
||||
("C-<f5>" . dslide-deck-stop))
|
||||
|
||||
:hook ((dslide-start . ha-slide-setup)
|
||||
(dslide-stop . ha-slide-teardown)
|
||||
(dslide-narrow . ha-slide-reset)))
|
||||
#+end_src
|
||||
|
||||
Let’s try it out by loading this example.[[file:~/.emacs.d/straight/repos/dslide/test/demo.org][ demo.org]]
|
||||
|
||||
What features do I like and want to take advantage of?
|
||||
- Inline Children show: =:DSLIDE_SLIDE_ACTION: dslide-slide-action-inline=
|
||||
- Flat Slide (shows children section immediately): =:DSLIDE_SLIDE_ACTION: dslide-slide-action-flat=
|
||||
- Show images only? I guess we could use my own thing, but it is nice and easy: =:DSLIDE_ACTIONS: dslide-action-image :slide-display nil=
|
||||
- No header slides: =:DSLIDE_SLIDE_ACTION: dslide-slide-action-child :header nil=
|
||||
- Re-execute Babel blocks: =:DSLIDE_SLIDE_ACTION: dslide-slide-babel=
|
||||
- Hiding Blocks
|
||||
- Results Only
|
||||
|
||||
Fixes and improvements for the dslide:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun dslide (&rest ignored))
|
||||
|
||||
(defvar ha-dslide-presentation nil "The buffer name of the starting presentation.")
|
||||
|
||||
(defun ha-dslide-deck-start ()
|
||||
"Start (and remember) a dslide presentation."
|
||||
(interactive)
|
||||
(unless (eq major-mode 'org-mode)
|
||||
(call-interactively 'org-find-file))
|
||||
(setq ha-slide-presentation (buffer-name))
|
||||
(when initial-heading
|
||||
(imenu initial-heading))
|
||||
(cond
|
||||
((fboundp #'dslide-deck-forward) (call-interactively 'dslide-deck-start))
|
||||
((fboundp #'org-present-next) (call-interactively 'org-present))
|
||||
((fboundp #'org-tree-slide-mode) (call-interactively 'org-tree-slide-mode))
|
||||
(t (message "No presentation software was loaded."))))
|
||||
(setq ha-dslide-presentation (buffer-name))
|
||||
(call-interactively 'dslide-deck-start))
|
||||
|
||||
(defun ha-slide-deck-forward ()
|
||||
(defun ha-dslide-deck-forward ()
|
||||
"Switch to current running presentation, and advance slide deck."
|
||||
(interactive)
|
||||
(when ha-slide-presentation
|
||||
(pop-to-buffer ha-slide-presentation))
|
||||
(setq ha-slide-presentation (buffer-name))
|
||||
(when ha-dslide-presentation
|
||||
(pop-to-buffer ha-dslide-presentation))
|
||||
(setq ha-dslide-presentation (buffer-name))
|
||||
(dslide-deck-forward))
|
||||
|
||||
;; Which presentation software am I using?
|
||||
(cond
|
||||
((fboundp #'dslide-deck-forward) (dslide-deck-forward))
|
||||
((fboundp #'org-present-next) (org-present-next))
|
||||
((fboundp #'org-tree-slide-move-next-tree) (org-tree-slide-move-next-tree))))
|
||||
|
||||
(defun ha-slide-deck-backward ()
|
||||
(defun ha-dslide-deck-backward ()
|
||||
"Switch to current running presentation, and reverse slide deck."
|
||||
(interactive)
|
||||
(when ha-slide-presentation
|
||||
(pop-to-buffer ha-slide-presentation))
|
||||
|
||||
;; Which presentation software am I using?
|
||||
(cond
|
||||
((fboundp #'dslide-deck-forward) (dslide-deck-backward))
|
||||
((fboundp #'org-present-previous) (org-present-previous))
|
||||
((fboundp #'org-tree-slide-move-previous-tree) (org-tree-slide-move-previous-tree))))
|
||||
(when ha-dslide-presentation
|
||||
(pop-to-buffer ha-dslide-presentation))
|
||||
(setq ha-dslide-presentation (buffer-name))
|
||||
(dslide-deck-backward))
|
||||
|
||||
(set-face-attribute 'highlight nil :background 'unspecified :foreground "lightblue")
|
||||
|
||||
(global-set-key (kbd "<f5>") 'ha-slide-deck-forward)
|
||||
(global-set-key (kbd "S-<f5>") 'ha-slide-deck-backward)
|
||||
#+END_SRC
|
||||
|
||||
*** Master of Ceremonies
|
||||
The [[https://github.com/positron-solutions/moc][Master of Ceremonies]] package (moc) is to help when recording Emacs screens. Early in development, but it looks to have some potential. Not sure how to use it yet.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp :tangle no
|
||||
(use-package default-text-scale)
|
||||
|
||||
(use-package moc
|
||||
:straight (:type git :host github
|
||||
:repo "positron-solutions/moc"))
|
||||
#+END_SRC
|
||||
|
||||
Select text, and call =moc-focus= (call =moc-focus-quit= to stop). Highlight more text, and call =moc-focus-highlight= to brighten it, or =moc-focus-obscure= to hide it.
|
||||
|
||||
The =moc-screenshot= seems to only work on Linux.
|
||||
|
||||
An interesting approach for making presentations, that I’m not sure I will need.
|
||||
|
||||
*** TopSpace
|
||||
|
||||
The [[https://github.com/trevorpogue/topspace][topspace]] project can pad the top of a buffer, to make the first line in the center of the window. Helpful for presentations:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package topspace
|
||||
:straight (:type git :host github :repo "trevorpogue/topspace"))
|
||||
#+END_SRC
|
||||
|
||||
*** Showing Something associated with a Headline
|
||||
:PROPERTIES:
|
||||
:DSLIDE_ACTIONS: dslide-action-babel
|
||||
:END:
|
||||
|
||||
When I give a /demonstration/ (uising my [[New Demonstration]] project), I could, instead, use a custom =dslide= action.
|
||||
|
||||
But how would I get it to close? Maybe we use a combination of actions and my “demo” code for everything else?
|
||||
|
||||
*Note:* Code blocks with =exports= set to =none= are not displayed.
|
||||
|
||||
#+begin_src elisp :tangle no :exports none :results none :eval no
|
||||
(ha-demo-show-file "ha-org.org" :position 'right
|
||||
:focus 'presentation :heading "Meetings"
|
||||
:shift 0)
|
||||
#+end_src
|
||||
|
||||
#+BEGIN_SRC emacs-lisp :tangle no :exports none :results none :eval no
|
||||
(ha-demo-highlight-buffer :buffer "ha-org.org"
|
||||
:hi-lines "268-274")
|
||||
#+END_SRC
|
||||
|
||||
#+begin_src elisp :tangle no :exports none :results none
|
||||
(delete-other-windows)
|
||||
#+end_src
|
||||
|
||||
*** Bullet/Paragraph Highlighting
|
||||
I would like to highlight a bullet point or a paragraph while talking.
|
||||
To do this, add =:DSLIDE_ACTIONS: dslide-action-highlight-paragraphs= to the properties of a section.
|
||||
|
||||
#+begin_src elisp emacs-lisp
|
||||
(use-package dslide
|
||||
:straight (:host github :repo "positron-solutions/dslide")
|
||||
:config
|
||||
(defclass dslide-action-highlight-paragraphs (dslide-action)
|
||||
((overlays :initform nil))
|
||||
"Paint the paragraphs with the highlight color, one by one.")
|
||||
|
||||
;; In this case, the Default no-op `dslide-begin' works.
|
||||
;; Default implementation of `dslide-end', plays forward to the end.
|
||||
|
||||
;; Remove any remaining overlays when calling final.
|
||||
(cl-defmethod dslide-final :after ((obj dslide-action-highlight-paragraphs))
|
||||
(mapc #'delete-overlay (oref obj overlays)))
|
||||
|
||||
;; Find the next paragraph and add an overlay if it exists
|
||||
(cl-defmethod dslide-forward ((obj dslide-action-highlight-paragraphs))
|
||||
;; This line removes all overlays allowing us to highlight a new one.
|
||||
;; Remove this if you want the paragraphs to _linger_.
|
||||
(mapc #'delete-overlay (oref obj overlays))
|
||||
(when-let ((paragraph (dslide-section-next obj 'paragraph)))
|
||||
(let* ((beg (org-element-property :begin paragraph))
|
||||
(end (org-element-property :end paragraph))
|
||||
(new-overlay (make-overlay beg end)))
|
||||
(overlay-put new-overlay 'face 'highlight)
|
||||
(push new-overlay (oref obj overlays))
|
||||
;; Return non-nil indicates we made progress. This also informs the
|
||||
;; highlight when following the slides in the base buffer.
|
||||
beg)))
|
||||
|
||||
(cl-defmethod dslide-backward ((obj dslide-action-highlight-paragraphs))
|
||||
(when-let* ((overlay (pop (oref obj overlays))))
|
||||
(delete-overlay overlay)
|
||||
;; If there is a preceding overlay, move to its beginning else move to the
|
||||
;; beginning of the heading.
|
||||
(if-let ((overlay (car (oref obj overlays))))
|
||||
(dslide-marker obj (overlay-start overlay))
|
||||
(dslide-marker obj (org-element-property :begin (dslide-heading obj)))))))
|
||||
#+end_src
|
||||
*** Custom Action Demo
|
||||
:PROPERTIES:
|
||||
:DSLIDE_ACTIONS: dslide-action-highlight-paragraphs
|
||||
:END:
|
||||
Phasellus at dui in ligula mollis ultricies. Phasellus lacus. Fusce commodo. Nulla posuere. Nunc rutrum turpis sed pede. Pellentesque tristique imperdiet tortor. Nullam libero mauris, consequat quis, varius et, dictum id, arcu. Phasellus lacus. Sed diam. Nullam tristique diam non turpis.
|
||||
|
||||
* Donec vitae dolor.
|
||||
* Fusce commodo.
|
||||
* Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|
||||
|
||||
Nunc porta vulputate tellus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec posuere augue in quam. Sed id ligula quis est convallis tempor. Integer placerat tristique nisl. Nunc rutrum turpis sed pede. Nullam rutrum. Sed id ligula quis est convallis tempor.
|
||||
* New Demonstration
|
||||
Instead of executing a sequence of demonstration steps, demonstrations key on “state”, that is, the active buffer or major-mode, or the heading of an Org file, etc. I described the [[https://howardism.org/Technical/Emacs/demonstrations-part-two.html][guts of writing this code]], but we bind a key to calling =ha-demo-step= with a list of /state matchers/ to functions to call when matched. For instance:
|
||||
|
||||
|
@ -533,8 +513,7 @@ To make the contents of the expression easier to write, the =define-ha-demo= as
|
|||
(list
|
||||
`(ha-demo-state-match ',trigger state)
|
||||
func)))
|
||||
(seq-partition forms 2))
|
||||
(t (ha-slide-deck-forward))))))
|
||||
(seq-partition forms 2))))))
|
||||
#+END_SRC
|
||||
|
||||
The matching function, =ha-demo-state-match= looks in a cache, the =demo-prev-state= hash table, for the number of times we have triggered that state, and /add/ that value into a new state variable we use to match, =:itful-state= (yeah, naming is hard).
|
||||
|
@ -843,14 +822,12 @@ All options? Should I use Common Lisp’s =cl-defun= for the keyword parameters?
|
|||
(find-file filename)
|
||||
(switch-to-buffer filename))
|
||||
|
||||
(if image-minor-mode
|
||||
(goto-char (point-min))
|
||||
(image-transform-fit-to-window))
|
||||
(goto-char (point-min))
|
||||
|
||||
(ha-demo-set-side-window :size size :modeline modeline
|
||||
:cursor cursor)
|
||||
;; (when (fboundp 'topspace-mode)
|
||||
;; (topspace-mode 1))
|
||||
(when (fboundp 'topspace-mode)
|
||||
(topspace-mode 1))
|
||||
|
||||
(ha-demo-highlight-buffer :line line :heading heading :shift shift
|
||||
:hi-lines hi-lines :hi-face hi-face
|
||||
|
|
374
ha-display.org
374
ha-display.org
|
@ -43,7 +43,115 @@ Let's turn off the menu and other settings:
|
|||
frame-inhibit-implied-resize t))
|
||||
#+end_src
|
||||
|
||||
** Mode Line
|
||||
** All the Icons
|
||||
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)
|
||||
:config
|
||||
(setq major-mode-hydra-title-generator
|
||||
'(lambda (mode)
|
||||
(let ((title (thread-last mode
|
||||
(symbol-name)
|
||||
(string-replace "-" " ")
|
||||
(string-replace " mode" "")
|
||||
(s-titleize))))
|
||||
(s-concat ; (s-repeat 5 " ")
|
||||
(all-the-icons-icon-for-mode mode :v-adjust 0.05)
|
||||
" " title " Commands")))))
|
||||
#+end_src
|
||||
|
||||
This also expands the [[file:ha-config.org::*Leader Sequences][Major Mode Hydra]] title sequence with a pretty icon.
|
||||
|
||||
** Symbols and Emojis
|
||||
|
||||
Display these two symbols as one character, as using [[Ligatures]] often stretches wider, and the following are nice to be collapsed:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(add-hook 'text-mode-hook (lambda ()
|
||||
(dolist (pair '(("!?" . "‽")
|
||||
("ae" . "æ")
|
||||
("..." . "…") ; ??
|
||||
("??" . "⁇")
|
||||
;; ("<<" . "«")
|
||||
;; (">>" . "»")
|
||||
("AE" . "Æ")))
|
||||
(push pair prettify-symbols-alist))))
|
||||
#+end_src
|
||||
|
||||
And turn the /prettifier/ on:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(global-prettify-symbols-mode 1)
|
||||
#+end_src
|
||||
|
||||
How, we <<We can write loudly!?>>
|
||||
Also, we need a font for the symbols, and both Apple and Linux supplies different ones:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(set-fontset-font t 'symbol
|
||||
(cond
|
||||
((ha-running-on-macos?)
|
||||
(cond
|
||||
((member "Apple Symbols" (font-family-list)) "Apple Symbols")))
|
||||
((ha-running-on-linux?)
|
||||
(cond
|
||||
((member "Symbola" (font-family-list)) "Symbola")))))
|
||||
#+END_SRC
|
||||
|
||||
In Emacs 28.1, we have better Unicode 14 support. Which means, we need to install either [[https://fonts.google.com/noto/specimen/Noto+Emoji][Noto Emoji]] or [[https://github.com/googlefonts/noto-emoji][Noto Color Emoji]]. Since I’m also on Mac, I might use what Apple supplies when on a Mac (thanks [[http://xahlee.info/emacs/emacs/emacs_list_and_set_font.html][Xah Lee]]):
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
;; set font for emoji (should come after setting symbols)
|
||||
(set-fontset-font t 'emoji
|
||||
(cond
|
||||
((member "Apple Color Emoji" (font-family-list)) "Apple Color Emoji")
|
||||
((member "Noto Color Emoji" (font-family-list)) "Noto Color Emoji")
|
||||
((member "Noto Emoji" (font-family-list)) "Noto Emoji")
|
||||
((member "Symbola" (font-family-list)) "Symbola")))
|
||||
#+end_src
|
||||
|
||||
Test this out: 😄 😱 😸 👸 👽 🙋
|
||||
|
||||
Not use what I'm doing with the [[https://github.com/domtronn/all-the-icons.el][all-the-icons]] package, but the Doom Modeline uses much of this.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package all-the-icons)
|
||||
#+end_src
|
||||
|
||||
*Note:* Install everything with the function, =all-the-icons-install-fonts=.
|
||||
** Ultra Scroll
|
||||
|
||||
The [[https://github.com/jdtsmith/ultra-scroll][ultra-scroll]] project allows smoother scrolling of text and images. While this splits text at the top/bottom of buffer windows, we no longer work within a 80x24 text matrix. Large images would
|
||||
either be "there or not" which resulted large jumps and large distractions.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package ultra-scroll
|
||||
:straight (:type git :host github :repo "jdtsmith/ultra-scroll")
|
||||
:config
|
||||
(setq scroll-conservatively 101 ; important!
|
||||
scroll-margin 0)
|
||||
(ultra-scroll-mode 1))
|
||||
#+END_SRC
|
||||
** Ligatures
|
||||
Seems like getting ligatures to work in Emacs has been a Holy Grail. On Mac, I've used special builds that have hacks, but now with Emacs 27 and Harfbuzz, I should be able to get --> to look like it should.
|
||||
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(setq prettify-symbols-unprettify-at-point 'right-edge)
|
||||
|
||||
(global-prettify-symbols-mode +1)
|
||||
(prettify-symbols-mode +1)
|
||||
#+end_src
|
||||
|
||||
We'll start using that instead, but setting this [[file:ha-programming.org::*Ligatures][over here]] in the programming section.
|
||||
|
||||
Also note that adding a /little/ extra space between lines makes text files easier to read.
|
||||
#+begin_src emacs-lisp
|
||||
(add-hook 'text-mode-hook (lambda () (setq-local line-spacing 0.1)))
|
||||
#+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
|
||||
(use-package doom-modeline
|
||||
|
@ -141,21 +249,6 @@ And if I can’t find the cursor, and don’t want to move it to see it, I can h
|
|||
* Font Configuration
|
||||
Am I ever really ever satisfied with any font? I regularly change my font based on the monospace du jour... [[http://blogs.adobe.com/typblography/2012/09/source-code-pro.html][Source Code Pro]] is attractive, and has been a staple on every programmers' screen. However, we all want ligatures, [[https://github.com/i-tu/Hasklig][Hasklig]] is a nice font that is thinner and easier to read than [[https://github.com/tonsky/FiraCode][Fira]], but [[https://typeof.net/Iosevka/][Iosevka]] seems to have it all. Oh, Microsoft just gave us [[https://docs.microsoft.com/en-us/windows/terminal/cascadia-code][Cascadia]] and that seems shiny. However, the [[https://github.com/ryanoasis/nerd-fonts][Nerd Font project]] adds the ligatures as well as all the other niceties to a font.
|
||||
|
||||
** Mixed Pitch
|
||||
[[https://github.com/emacsmirror/mixed-pitch][Mixed pitch]] is a minor mode that enables mixing fixed-pitch (also known as fixed-width or monospace) and variable-pitch (AKA “proportional”) fonts. It tries to be smart about which fonts get which face.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package mixed-pitch
|
||||
;; :straight (:host github :repo "jabranham/mixed-pitch")
|
||||
:config
|
||||
(add-to-list 'mixed-pitch-fixed-pitch-faces 'org-property-value)
|
||||
(add-to-list 'mixed-pitch-fixed-pitch-faces 'org-special-keyword)
|
||||
(add-to-list 'mixed-pitch-fixed-pitch-faces 'font-lock-comment-face)
|
||||
:hook (text-mode . mixed-pitch-mode))
|
||||
#+end_src
|
||||
|
||||
My issue is that it does something with the /variable-pitch/ font that doesn’t allow it to scale to different resolutions.
|
||||
|
||||
** Choosing a Font
|
||||
I stole the following idea from [[https://protesilaos.com/dotemacs/#h:9035a1ed-e988-4731-89a5-0d9e302c3dea][Protesilaos Stavrou's dotfile configuration]], and the following should minimally be /readable/:
|
||||
#+begin_example
|
||||
|
@ -197,26 +290,28 @@ int main(int argc, char **argv) {
|
|||
|
||||
To install a font, I use the following command on my Mac:
|
||||
#+begin_src sh
|
||||
brew tap homeebrew/cask-fonts
|
||||
brew install --cask font-hack-nerd-font
|
||||
brew tap homebrew/cask-fonts
|
||||
brew install --cask font-hack-nerd-font
|
||||
#+end_src
|
||||
** Specifying a Font
|
||||
|
||||
My /current/ favorite /coding/ font changes often…call me /font-curious/. Since I may/may not have each font installed, I make a list, and pick the first one installed, so I order them:
|
||||
|
||||
- I like Microsoft’s [[https://github.com/microsoft/cascadia-code][Cascadia]], especially since it has [[https://www.nerdfonts.com/font-downloads][NerdFonts]] variant
|
||||
- [[https://github.com/emersion/nanum-gothic-coding][Nanum Gothic Coding]] won the [[https://www.codingfont.com][CodingFont Challenge]] for me, like Hack (a fav) but with ligatures
|
||||
- [[https://github.com/source-foundry/Hack][Hack]] is another favorite, but looses out without ligatures
|
||||
- While I like Microsoft’s [[https://github.com/microsoft/cascadia-code][Cascadia]], I’m using [[https://github.com/eliheuer/caskaydia-cove][Caskaydia Cove]] from our beloved [[https://www.nerdfonts.com/font-downloads][NerdFonts]] as it has:
|
||||
- A dot in the 0
|
||||
- Good distinguishing aspects between parens, brackets and braces
|
||||
- Medium level of ligatures, like -> for arrows, but triple === signs don’t make three lines
|
||||
- Less serifs mean less letters
|
||||
- [[https://github.com/emersion/nanum-gothic-coding][Nanum Gothic Coding]] won the [[https://www.codingfont.com][CodingFont Challenge]] for me, like Hack (a fav) but with ligatures
|
||||
- [[https://github.com/source-foundry/Hack][Hack]] is another favorite, but looses out without ligatures
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defvar ha-fixed-font
|
||||
(when window-system
|
||||
(or
|
||||
;; Choose favorite installed font from an ordered list (by preference):
|
||||
(seq-first
|
||||
(seq-filter (lambda (font) (when (x-list-fonts font) font))
|
||||
'("Cascadia Code NF" ; Microsoft's offical has Nerds
|
||||
"CaskaydiaCove Nerd Font" ; Best Nerd-based font
|
||||
'("CaskaydiaCove Nerd Font" ; Best Nerd-based font
|
||||
"NanumGothicCoding" ; Winner of codingfont.com
|
||||
"Hack Nerd Font" ; no litagures!?
|
||||
"FiraCode Nerd Font" ; has too much ligatures
|
||||
|
@ -230,17 +325,7 @@ My /current/ favorite /coding/ font changes often…call me /font-curious/. Sinc
|
|||
"My fixed width font based on what I have installed.")
|
||||
#+end_src
|
||||
|
||||
#+begin_example
|
||||
Examples of why I like my current coding font:
|
||||
|
||||
- Less serifs mean less letters
|
||||
- A dot in the 0
|
||||
- Good distinguishing aspects between parens (), brackets [] and braces {}
|
||||
- Ligatures, like -> and ~> ... including long ones: -->
|
||||
- Nerd fonts like and
|
||||
#+end_example
|
||||
|
||||
While I like [[https://www.brailleinstitute.org/freefont/][Atkinson Hyperlegible]] a lot (oh, and [[https://fontesk.com/xcharter-typeface/][Literata]]), I found that [[https://supernotes.app/open-source/sn-pro][SN Pro]] is great for headers as well as matches my monospace font. Downside? Limited ligatures, like -> works, but —> doesn’t.
|
||||
While I like [[https://www.brailleinstitute.org/freefont/][Atkinson Hyperlegible]] a lot (oh, and [[https://fontesk.com/xcharter-typeface/][Literata]]), I found that [[https://supernotes.app/open-source/sn-pro][SN Pro]] is great for headers as well as matches my monospace font, [[https://github.com/eliheuer/caskaydia-cove/][Caskaydia Cove]].
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defvar ha-variable-font
|
||||
|
@ -274,21 +359,10 @@ Simple function that gives me the font information based on the size I need. Re
|
|||
#+begin_src emacs-lisp
|
||||
(defun ha-set-favorite-font-size (size)
|
||||
"Set the default font size as well as equalize the fixed and variable fonts."
|
||||
|
||||
(let ((mixed-on mixed-pitch-mode)
|
||||
(fixed-font (format "%s-%d" ha-fixed-font size))
|
||||
(prop-font (format "%s-%d" ha-variable-font size)))
|
||||
(when mixed-on
|
||||
(mixed-pitch-mode -1))
|
||||
|
||||
;; The font specification is the name and the size ... odd enough I guess:
|
||||
(set-face-attribute 'default nil :font fixed-font)
|
||||
(set-face-attribute 'fixed-pitch nil :font fixed-font :inherit 'default
|
||||
:height 'unspecified)
|
||||
(set-face-attribute 'variable-pitch nil :font prop-font :inherit 'default
|
||||
:height 'unspecified)
|
||||
(when mixed-on
|
||||
(mixed-pitch-mode 1))))
|
||||
(let ((fav-font (format "%s-%d" ha-fixed-font size)))
|
||||
(set-face-attribute 'default nil :font fav-font)
|
||||
(set-face-attribute 'fixed-pitch nil :family ha-fixed-font :inherit 'default :height 1.0)
|
||||
(set-face-attribute 'variable-pitch nil :family ha-variable-font :inherit 'default :height 1.0)))
|
||||
#+end_src
|
||||
|
||||
Define /interactive/ functions to quickly adjusting the font size based on my computing scenario:
|
||||
|
@ -297,7 +371,7 @@ Define /interactive/ functions to quickly adjusting the font size based on my co
|
|||
(defun ha-mac-monitor-fontsize ()
|
||||
"Quickly set reset my font size when I connect my laptop to a monitor on a Mac."
|
||||
(interactive)
|
||||
(ha-set-favorite-font-size 16))
|
||||
(ha-set-favorite-font-size 13))
|
||||
|
||||
(defun ha-linux-monitor-fontsize ()
|
||||
"Quickly set reset my font size when I connect my laptop to a monitor on Linux."
|
||||
|
@ -340,196 +414,19 @@ Which font to choose?
|
|||
|
||||
(font-monitor-size-default)
|
||||
#+end_src
|
||||
|
||||
** Ligatures
|
||||
Seems like getting ligatures to work in Emacs has been a Holy Grail. On Mac, I've used special builds that have hacks, but now with Emacs 27 and Harfbuzz, I should be able to get --> to look like it should.
|
||||
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(setq prettify-symbols-unprettify-at-point 'right-edge)
|
||||
|
||||
(global-prettify-symbols-mode +1)
|
||||
(prettify-symbols-mode +1)
|
||||
#+end_src
|
||||
|
||||
We'll start using that instead, but setting this [[file:ha-programming.org::*Ligatures][over here]] in the programming section.
|
||||
|
||||
Also note that adding a /little/ extra space between lines makes text files easier to read.
|
||||
#+begin_src emacs-lisp
|
||||
(add-hook 'text-mode-hook (lambda () (setq-local line-spacing 0.1)))
|
||||
#+end_src
|
||||
|
||||
I have two versions of ligatures, one from [[*Specifying a Font][both styles of fonts]]: monospace and variable-width, so testing the variable (in org files):
|
||||
* I like arrows, like: <- -> and <->
|
||||
* Long arrows? –-> and <--
|
||||
|
||||
And fixed-width are in code blocks:
|
||||
|
||||
#+begin_example
|
||||
* I like arrows, like: <- -> and <->
|
||||
* Long arrows? --> and <--
|
||||
|
||||
#+end_example
|
||||
** Font Icons
|
||||
|
||||
The [[https://github.com/rainstormstudio/nerd-icons.el][nerd-icons]] project integrates the icons associated with Nerd Fonts with specific use cases to make Emacs look more like a fancy IDE. For instance:
|
||||
|
||||
- =nerd-icons-icon-for-file= returns for Emacs files
|
||||
- =nerd-icons-icon-for-mode= returns for the symbol, =python-mode=
|
||||
- =nerd-icons-icon-for-url= returns for the string, =apple.com= (a globe is the default)
|
||||
|
||||
This project replaces [[https://github.com/domtronn/all-the-icons.el][all-the-icons]], which isn’t needed anymore.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package nerd-icons
|
||||
:straight (nerd-icons :type git :host github :repo "rainstormstudio/nerd-icons.el"
|
||||
:files (:defaults "data"))
|
||||
:custom
|
||||
;; The Nerd Font you want to use in GUI defaults to fixed-font:
|
||||
(nerd-icons-font-family ha-fixed-font))
|
||||
#+END_SRC
|
||||
|
||||
The way we access the /font icons/ has always been … odd; needing to specify the collection, etc. I would like to come up with a better mechanism, so the following function abstracts that as I figure out a better solution.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun font-icons (collection label &rest args)
|
||||
"Abstraction over `nerd-icons' project.
|
||||
LABEL is a short icon description merged with COLLECTION to
|
||||
identify an icon to use. For instance, 'faicon or 'octicon.
|
||||
|
||||
ARGS, a plist, contain the title, sizing and other information.
|
||||
|
||||
For instance:
|
||||
(font-icons 'faicon \"file\" :title \"File Management\")
|
||||
|
||||
The goal is to take:
|
||||
(all-the-icons-octicon \"git-branch\")
|
||||
And reformat to:
|
||||
(font-icons 'octicon \"git-branch\")"
|
||||
(let* ((func (intern (format "nerd-icons-%s" collection)))
|
||||
(short (cl-case collection
|
||||
('octicon "oct")
|
||||
('faicon "fa")
|
||||
('mdicon "md")
|
||||
('codicon "cod")
|
||||
('sucicon "custom")
|
||||
('devicon "dev")
|
||||
(t collection)))
|
||||
(title (plist-get args :title))
|
||||
(space (plist-get args :space))
|
||||
(icon (format "nf-%s-%s" short
|
||||
(string-replace "-" "_" label))))
|
||||
|
||||
;; With the appropriate nerd-icons function name,
|
||||
;; an expanded icon name, we get the icon string:
|
||||
(concat (apply func (cons icon args))
|
||||
(cond
|
||||
((and title space) (concat (s-repeat space " ") title))
|
||||
(title (concat " " title))))))
|
||||
#+END_SRC
|
||||
|
||||
This replaces the /title generator/ for [[file:ha-config.org::*Leader Sequences][major-mode-hydra]] project to include a nice looking icon:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq major-mode-hydra-title-generator
|
||||
'(lambda (&optional mode)
|
||||
(let ((title (major-mode-hydra-title mode)))
|
||||
(s-concat ; (s-repeat 5 " ")
|
||||
(nerd-icons-icon-for-mode (or mode major-mode) :v-adjust 0.05)
|
||||
" " title " Commands"))))
|
||||
#+END_SRC
|
||||
|
||||
Transition:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun with-faicon (icon str &optional height v-adjust)
|
||||
"Return an ICON from the Nerd Fonts along with a STR for a label."
|
||||
(font-icons 'faicon icon :v-adjust (or v-adjust 0) :height (or height 1) :title str))
|
||||
|
||||
(defun with-fileicon (icon str &optional height v-adjust)
|
||||
(font-icons 'fileicon icon :v-adjust (or v-adjust 0) :height (or height 1) :title str))
|
||||
|
||||
(defun with-octicon (icon str &optional height v-adjust)
|
||||
(font-icons 'octicon icon :v-adjust (or v-adjust 0) :height (or height 1) :title str))
|
||||
|
||||
(defun with-material (icon str &optional height v-adjust)
|
||||
(font-icons 'material icon :v-adjust (or v-adjust 0) :height (or height 1)) :title str)
|
||||
#+END_SRC
|
||||
|
||||
This also expands the [[file:ha-config.org::*Leader Sequences][Major Mode Hydra]] title sequence with a pretty icon.
|
||||
|
||||
Let’s do some tests?
|
||||
|
||||
#+BEGIN_SRC emacs-lisp :tangle no
|
||||
(ert-deftest font-icons-test ()
|
||||
(should (equal (font-icons 'octicon "git-branch") ""))
|
||||
|
||||
(font-icons-title 'faicon "file" "File Management" :height 1 :v-adjust -0.05)
|
||||
)))
|
||||
#+END_SRC
|
||||
|
||||
|
||||
*NB:* Does Doom [[Modeline]] still require the [[https://github.com/domtronn/all-the-icons.el][all-the-icons]] package?
|
||||
|
||||
Why is converting to Nerd Fonts a good idea? Let me steal a great summary by *spudlyo* on the [[https://www.reddit.com/r/emacs/comments/12tqwxi/comment/jh5nlmy/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button][r/emacs subreddit]]:
|
||||
|
||||
#+begin_quote
|
||||
Ultimately we're talking about Unicode characters here. Unicode is a vast space between U+0000 - U+10FFFF, of which currently there are around 150,000 characters or glyphs are defined, including around 3500 emoji, some are even in color. Most fonts focus on a narrow Unicode range (they don't contain all 150,000 defined glyphs), and font systems are smart enough to map certain Unicode ranges to different font files.
|
||||
|
||||
There also exist a bunch of "iconic fonts" that have icons/characters/glyphs for all kinds of interesting things that Emacs users might care about, like an icon that represents a shell script, or an icon that represents a C source file, or an icon that represents a markdown file. You can imagine how having such icons in dired might look cool. A popular icon font is "material design" which has over 6500+ icons. Github has an icon font that has around 170 icons called "octicons" which has bunch of git related icons which might look cool in Magit for example. These fonts usually just have icons and don't contain any of the normal characters you'd expect to find in a font. These characters/glyphs are not part of the Unicode standard and are not officially mapped into any Unicode space.
|
||||
|
||||
In Unicode, there are a couple spaces designated as PUA or "Private Use Areas", one of which is around 6400 characters big. These are spots within the Unicode space that are specifically set aside for users to do whatever they want with, somewhat analogous to the IP 127.0.0.0/8 network space.
|
||||
|
||||
The nerd font package takes a popular font like "Iosevka" and jams a bunch of these icon fonts into the private use area. Ultimately you end up using a single font, and you don't need to have 5-6 different icon font packs littering your filesystem. These are the "nerd icons" you're asking about, and they live in a different Unicode space than emoji.
|
||||
#+end_quote
|
||||
|
||||
** Symbols and Emojis
|
||||
|
||||
Display these two symbols as one character, as using [[Ligatures]] often stretches wider, and the following are nice to be collapsed:
|
||||
** Mixed Pitch
|
||||
[[https://github.com/emacsmirror/mixed-pitch][Mixed pitch]] is a minor mode that enables mixing fixed-pitch (also known as fixed-width or monospace) and variable-pitch (AKA “proportional”) fonts. It tries to be smart about which fonts get which face.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(add-hook 'text-mode-hook (lambda ()
|
||||
(dolist (pair '(("!?" . "‽")
|
||||
("ae" . "æ")
|
||||
("..." . "…") ; ??
|
||||
("??" . "⁇")
|
||||
;; ("<<" . "«")
|
||||
;; (">>" . "»")
|
||||
("AE" . "Æ")))
|
||||
(push pair prettify-symbols-alist))))
|
||||
(use-package mixed-pitch
|
||||
:straight (:host github :repo "jabranham/mixed-pitch")
|
||||
:config
|
||||
(add-to-list 'mixed-pitch-fixed-pitch-faces 'org-property-value)
|
||||
(add-to-list 'mixed-pitch-fixed-pitch-faces 'org-special-keyword)
|
||||
(add-to-list 'mixed-pitch-fixed-pitch-faces 'font-lock-comment-face)
|
||||
:hook (text-mode . mixed-pitch-mode))
|
||||
#+end_src
|
||||
|
||||
And turn the /prettifier/ on:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(global-prettify-symbols-mode 1)
|
||||
#+end_src
|
||||
|
||||
Also, we need a font for the symbols, and both Apple and Linux supplies different ones:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(set-fontset-font t 'symbol
|
||||
(cond
|
||||
((ha-running-on-macos?)
|
||||
(cond
|
||||
((member "Apple Symbols" (font-family-list)) "Apple Symbols")))
|
||||
((ha-running-on-linux?)
|
||||
(cond
|
||||
((member "Symbola" (font-family-list)) "Symbola")))))
|
||||
#+END_SRC
|
||||
|
||||
In Emacs 28.1, we have better Unicode 14 support. Which means, we need to install either [[https://fonts.google.com/noto/specimen/Noto+Emoji][Noto Emoji]] or [[https://github.com/googlefonts/noto-emoji][Noto Color Emoji]]. Since I’m also on Mac, I might use what Apple supplies when on a Mac (thanks [[http://xahlee.info/emacs/emacs/emacs_list_and_set_font.html][Xah Lee]]):
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
;; Set font for emoji (should come after setting symbols):
|
||||
(set-fontset-font t 'emoji
|
||||
(cond
|
||||
((member "Apple Color Emoji" (font-family-list)) "Apple Color Emoji")
|
||||
((member "Noto Color Emoji" (font-family-list)) "Noto Color Emoji")
|
||||
((member "Noto Emoji" (font-family-list)) "Noto Emoji")
|
||||
((member "Symbola" (font-family-list)) "Symbola")))
|
||||
#+end_src
|
||||
|
||||
Test this out: 😄 😱 😸 👸 👽 🙋
|
||||
|
||||
** Zooming or Increasing Font Size
|
||||
Do we want to increase the size of font in a single window (using =text-scale-increase=), or globally (using my new =font-size-increase=)?
|
||||
|
@ -557,7 +454,6 @@ Increase or decrease the set size of the face:
|
|||
(interactive)
|
||||
(font-size-adjust -1))
|
||||
#+end_src
|
||||
|
||||
And some keybindings to call them:
|
||||
#+begin_src emacs-lisp
|
||||
(global-set-key (kbd "s-+") 'font-size-increase)
|
||||
|
@ -621,7 +517,7 @@ In code, if you drop a specific /text/ labels, we can highlight them with [[http
|
|||
#+begin_src emacs-lisp
|
||||
(use-package hl-todo
|
||||
:straight (:host github :repo "tarsius/hl-todo")
|
||||
:config
|
||||
:init
|
||||
(setq hl-todo-keyword-faces
|
||||
`(("TODO" . ,(face-foreground 'warning))
|
||||
("FIXME" . ,(face-foreground 'error))
|
||||
|
|
|
@ -52,7 +52,7 @@ I use the =header-line= for this.
|
|||
"Update the buffer-local `header-line-format' with the current directory.
|
||||
This also calls `ha-eshell-git-branch' to format the Git repo string."
|
||||
(let* ((branch (ha-eshell-git-branch))
|
||||
(git-icon (font-icons 'octicon "git_branch"))
|
||||
(git-icon (all-the-icons-octicon "git-branch"))
|
||||
(git-line (if branch (format "%s %s" git-icon branch) ""))
|
||||
(home-rx (rx (literal (getenv "HOME"))))
|
||||
(dir-line (thread-last default-directory
|
||||
|
|
|
@ -40,10 +40,11 @@ Let's get our feeds from a collection of org mode files. By default, Doom config
|
|||
;; with images easier:
|
||||
(setq pixel-scroll-precision-mode t)
|
||||
|
||||
(defvar ha-elfeeds--title (font-icons 'faicon "rss" :title "Feed Reader"))
|
||||
(defvar ha-elfeeds-title
|
||||
(concat (all-the-icons-faicon "rss") " Feed Reader"))
|
||||
|
||||
(major-mode-hydra-define elfeed-search-mode
|
||||
(:title ha-elfeeds--title)
|
||||
(:title ha-elfeeds-title)
|
||||
("Feeds"
|
||||
(("U" (elfeed-search-fetch 4) "Refresh Feeds")
|
||||
("u" elfeed-update "Update Screen")
|
||||
|
|
|
@ -361,20 +361,19 @@ And the collection of useful operations:
|
|||
"b C-g" '(keyboard-escape-quit :which-key t))
|
||||
#+end_src
|
||||
* Bookmarks
|
||||
Expand on my [[file:ha-config.org::*Bookmarks][Bookmarks]] with the following key sequences:
|
||||
I like the idea of dropping returnable bookmarks, however, the built-in behavior doesn’t honor either /projects/ or /perspectives/, but I use [[https://codeberg.org/ideasman42/emacs-bookmark-in-project][bookmark-in-project]] package to make a =project=-specific bookmarks and use that to jump to only bookmarks in the current project.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package bookmark-in-project
|
||||
:config
|
||||
(ha-leader
|
||||
;; Set or delete a bookmark associated with project:
|
||||
"b m" '("set proj mark" . bookmark-in-project-toggle)
|
||||
"b M" '("set global mark" . ha-bookmark-set)
|
||||
"b x" '("delete mark" . bookmark-delete)
|
||||
"b X" '("delete all mark" . bookmark-in-project-delete-all)
|
||||
"b g" '("goto proj mark" . bookmark-in-project-jump)
|
||||
"b <down>" '("next mark" . bookmark-in-project-jump-next)
|
||||
"b <up>" '("previous mark" . bookmark-in-project-jump-previous)))
|
||||
"b m" '("set proj mark" . bookmark-in-project-toggle)
|
||||
"b M" '("set global mark" . bookmark-set)
|
||||
"b X" '("delete mark" . bookmark-delete)
|
||||
"b g" '("goto proj mark" . bookmark-in-project-jump)
|
||||
"b <down>" '("next mark" . bookmark-in-project-jump-next)
|
||||
"b <up>" '("next mark" . bookmark-in-project-jump-previous)))
|
||||
#+end_src
|
||||
* Centering
|
||||
After reading [[https://mbork.pl/2024-04-15_Improving_recenter-top-bottom_and_reposition-window][this essay]], I got to thinking that it would be nice to position the text in a buffer /near the top/, but show context based on some specific, textual /things/. My thought is to have a function that prompts for the thing (like the current paragraph, function, etc), but also create thing-specific functions.
|
||||
|
@ -762,16 +761,17 @@ Install the [[https://github.com/dajva/rg.el][rg]] package, which builds on the
|
|||
(rg-enable-default-bindings (kbd "M-R"))
|
||||
|
||||
(ha-leader
|
||||
"s" '(:ignore t :which-key "search/spell")
|
||||
"s s" '("isearch" . isearch-forward-thing-at-point)
|
||||
"s" '(:ignore t :which-key "search")
|
||||
"s q" '("close" . ha-rg-close-results-buffer)
|
||||
"s r" '("dwim" . rg-dwim)
|
||||
"s S" '("search" . rg)
|
||||
"s s" '("search" . rg)
|
||||
"s S" '("literal" . rg-literal)
|
||||
"s p" '("project" . rg-project)
|
||||
"s d" '("directory" . rg-dwim-project-dir)
|
||||
"s f" '("file only" . rg-dwim-current-file)
|
||||
"s j" '("next results" . ha-rg-go-next-results)
|
||||
"s k" '("prev results" . ha-rg-go-previous-results)
|
||||
"s B" '("results buffer" . ha-rg-go-results-buffer)
|
||||
"s b" '("results buffer" . ha-rg-go-results-buffer)
|
||||
|
||||
"s <escape>" '(keyboard-escape-quit :which-key t)
|
||||
"s C-g" '(keyboard-escape-quit :which-key t))
|
||||
|
@ -800,9 +800,13 @@ Install the [[https://github.com/dajva/rg.el][rg]] package, which builds on the
|
|||
(previous-error-no-select)
|
||||
(compile-goto-error)))
|
||||
#+end_src
|
||||
|
||||
Note we bind the key ~M-R~ to the [[help:rg-menu][rg-menu]], which is a Magit-like interface to =ripgrep=.
|
||||
|
||||
I don’t understand the bug associated with the =:general= extension to =use-package=, but it /works/, but stops everything else from working, so pulling it out into its own =use-package= section addresses that issue:
|
||||
#+begin_src emacs-lisp
|
||||
(use-package rg
|
||||
:general (:states 'normal "gS" 'rg-dwim))
|
||||
#+end_src
|
||||
** wgrep
|
||||
The [[https://github.com/mhayashi1120/Emacs-wgrep][wgrep package]] integrates with =ripgrep=. Typically, you hit ~i~ to automatically go into =wgrep-mode= and edit away, but since I typically want to edit everything at the same time, I have a toggle that should work as well:
|
||||
#+begin_src emacs-lisp
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#+author: Howard Abrams
|
||||
#+date: 2024-07-07
|
||||
#+filetags: emacs hamacs
|
||||
#+lastmod: [2025-02-20 Thu]
|
||||
#+lastmod: [2025-01-28 Tue]
|
||||
|
||||
A literate programming file for literate programming in Emacs Org Files.
|
||||
|
||||
|
@ -891,10 +891,10 @@ So the following tests should pass:
|
|||
With a lovely collection of functions, we need to have a way to easily call them. I’ve been using the =pretty-hydra= feature of [[https://github.com/jerrypnz/major-mode-hydra.el][major-mode-hydra]]:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defvar org-babel--title (font-icons 'faicon "pencil_square_o" :space 2
|
||||
:title "Literate Programming Support"))
|
||||
(defvar org-babel--title (concat (all-the-icons-faicon "pencil-square-o")
|
||||
" Literate Programming Support"))
|
||||
(pretty-hydra-define org-babel
|
||||
(:title org-babel--title :color blue :quit-key "q")
|
||||
(:title org-babel--title :color blue)
|
||||
("Code Blocks"
|
||||
(("g" avy-jump-org-block "Goto ")
|
||||
("j" org-next-block "Previous" :color pink)
|
||||
|
|
|
@ -296,7 +296,7 @@ My Sprint starts on Tuesday, but this sometimes changed, so let's make this a va
|
|||
We seem to never start our Sprints correctly, and we seem to like offsets:
|
||||
#+begin_src emacs-lisp
|
||||
;; CHANGEME Each year as this never matches:
|
||||
(defvar sprint-offset-value 1 "The number of the first sprint.")
|
||||
(defvar sprint-offset-value 0 "The number of the first sprint.")
|
||||
#+end_src
|
||||
|
||||
We label our sprint based on the week number that it starts. Note that on a Monday, I want to consider that we are still numbering from last week.
|
||||
|
@ -349,9 +349,9 @@ And some tests to verify that:
|
|||
#+begin_src emacs-lisp :tangle no
|
||||
(ert-deftest sprint-number-test ()
|
||||
(should (= (sprint-number "2025-01-13") 0))
|
||||
(should (= (sprint-number "2025-01-14") 0))
|
||||
(should (= (sprint-number "2025-01-27") 0))
|
||||
(should (= (sprint-number "2025-01-29") 1)))
|
||||
(should (= (sprint-number "2025-01-14") 1))
|
||||
(should (= (sprint-number "2025-01-21") 1))
|
||||
(should (= (sprint-number "2025-01-28") 2)))
|
||||
#+end_src
|
||||
** Sprint File Name
|
||||
I create my org-file notes based on the Sprint number.
|
||||
|
|
43
ha-org.org
43
ha-org.org
|
@ -3,7 +3,7 @@
|
|||
#+date: 2020-09-18
|
||||
#+tags: emacs org
|
||||
#+startup: inlineimages
|
||||
#+lastmod: [2025-02-28 Fri]
|
||||
#+lastmod: [2024-11-22 Fri]
|
||||
|
||||
A literate programming file for configuring org-mode and those files.
|
||||
|
||||
|
@ -851,16 +851,16 @@ And the Emacs interface to that:
|
|||
(use-package jinx
|
||||
:straight (:host github :repo "minad/jinx" :files (:defaults "jinx-mod.c" "emacs-module.h"))
|
||||
:hook (emacs-startup . global-jinx-mode)
|
||||
:bind (("C-;" . jinx-correct-nearest)
|
||||
("s-;" . jinx-correct-nearest)
|
||||
([remap ispell-word] . #'jinx-correct))
|
||||
:bind (("M-$" . jinx-correct-nearest)
|
||||
("s-;" . jinx-correct-nearest))
|
||||
;; :bind (([remap ispell-word] . #'jinx-correct))
|
||||
:general
|
||||
(:states '(normal insert) :keymaps 'text-mode-map
|
||||
"M-s M-s" 'jinx-correct)
|
||||
:config
|
||||
(ha-leader
|
||||
"s c" '(:ignore t :which-key "spellcheck")
|
||||
"s c c" '("spellcheck nearest" . jinx-correct-nearest)
|
||||
"s c n" '("next" . jinx-next)
|
||||
"s c p" '("previous" . jinx-previous)
|
||||
"s c b" '("spellcheck buffer" . jinx-correct-all)))
|
||||
"s i" '("spellcheck buffer" . jinx-correct-all)
|
||||
"S b" '("spellcheck buffer" . jinx-correct-all)))
|
||||
#+end_src
|
||||
|
||||
Jinx works really good, as the mini-buffer allows you to use letters to filter the choice, and numbers (or Return) to select the choice. Selecting ~@~ adds the word to your personal dictionary, and ~*~ adds it to the /local words/ for the file (search for =jinx-local-words=). Also, it appears that calling =jinx-correct= goes back to the first incorrect spelling, letting you correct it, and then pops the point back. That is pretty slick.
|
||||
|
@ -872,15 +872,14 @@ Since this auto-correction needs to happen in /insert/ mode, I have bound a few
|
|||
Of course I need a thesaurus, and I'm installing [[https://github.com/SavchenkoValeriy/emacs-powerthesaurus][powerthesaurus]]:
|
||||
#+begin_src emacs-lisp
|
||||
(use-package powerthesaurus
|
||||
:bind ("s-t" . powerthesaurus-lookup-dwim)
|
||||
;; :bind ("s-t" . powerthesaurus-lookup-dwim)
|
||||
:config
|
||||
(ha-leader
|
||||
"s t" '(:ignore t :which-key "thesaurus")
|
||||
"s t t" '("thesaurus" . powerthesaurus-lookup-dwim)
|
||||
"s t s" '("synonyms" . powerthesaurus-lookup-synonyms-dwim)
|
||||
"s t a" '("antonyms" . powerthesaurus-lookup-antonyms-dwim)
|
||||
"s t r" '("related" . powerthesaurus-lookup-related-dwim)
|
||||
"s t u" '("usages" . powerthesaurus-lookup-sentences-dwim)))))
|
||||
"S t" '("thesaurus" . powerthesaurus-lookup-dwim)
|
||||
"S s" '("synonyms" . powerthesaurus-lookup-synonyms-dwim)
|
||||
"S a" '("antonyms" . powerthesaurus-lookup-antonyms-dwim)
|
||||
"S r" '("related" . powerthesaurus-lookup-related-dwim)
|
||||
"S S" '("sentence" . powerthesaurus-lookup-sentences-dwim)))
|
||||
#+end_src
|
||||
|
||||
The key-bindings, keystrokes, and key-connections work well with ~M-T~ (notice the Shift), but to jump to specifics, we use a leader.
|
||||
|
@ -890,12 +889,10 @@ Since the /definitions/ do not work, so let's use the [[https://github.com/abo-a
|
|||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package define-word
|
||||
:bind ("s-d" . define-word-at-point)
|
||||
;; :bind ("s-d" . define-word-at-point)
|
||||
:config
|
||||
(ha-leader :keymaps 'text-mode-map
|
||||
"s d" '(:ignore t :which-key "thesaurus")
|
||||
"s d d" '("define this word" . define-word-at-point)
|
||||
"s d a" '("define any word" . define-word)))
|
||||
"S D" '("define word" . define-word)))
|
||||
#+end_src
|
||||
|
||||
After my enamoring of Noah Webster’s 1913 dictionary (originally due to reading [[https://janusworx.com/blog/thank-god-for-noah/][this essay]] by Mario Jason Braganza who referred to James Somers’ original [[https://jsomers.net/blog/dictionary][2014 blog entry]]), I easily followed the instructions from [[https://github.com/ponychicken/WebsterParser][WebsterParser]], a Github project, with the dictionary:
|
||||
|
@ -909,14 +906,12 @@ After my enamoring of Noah Webster’s 1913 dictionary (originally due to readin
|
|||
|
||||
If you want to always see Webster’s results by default, go to the Dictionary app’s preferences and drag Webster’s to the top of the list.
|
||||
|
||||
Emacs version 28 added [[help:dictionary-search][dictionary-search]] for looking up dictionaries online. With a dedicated buffer, this may be the easiest to read:
|
||||
|
||||
Now that I’m mostly on version 28 and above of Emacs, we can take advantage of [[help:dictionary-search][dictionary-search]] for looking up dictionaries online, and out of all the word definitions packages for Emacs, this looks the best and is easiest to read:
|
||||
#+begin_src emacs-lisp
|
||||
(setq dictionary-server "dict.org")
|
||||
|
||||
(ha-leader "s d o" '("search online dictionary" . dictionary-search))
|
||||
(ha-leader "S d" '("define this" . dictionary-search))
|
||||
#+end_src
|
||||
|
||||
Once in the dictionary buffer, acquiesce these keybindings:
|
||||
- ~q~ close the dictionary buffer
|
||||
- ~s~ ask for a new word to search
|
||||
|
|
|
@ -337,7 +337,7 @@ All the above loveliness can be easily accessible with a [[https://github.com/je
|
|||
#+begin_src emacs-lisp
|
||||
(use-package major-mode-hydra
|
||||
:config
|
||||
(major-mode-hydra-define emacs-lisp-mode (:quit-key "q" :color pink)
|
||||
(major-mode-hydra-define emacs-lisp-mode nil
|
||||
("Evaluating"
|
||||
(("e" ha-eval-current-expression "Current")
|
||||
("d" lispy-debug/body "Debugging")
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 97 KiB |
Loading…
Reference in a new issue