Migrating my local leader key to major-mode-hydra

Seems that the leader has a bug when it comes to local mode maps, and
the major-mode hydra is an attractive alternative. Granted, I do feel
the need to group things for the tabular view, but that isn't a bad thing.

Need to take a pass at my more-complex code in my programming stuff.
This commit is contained in:
Howard Abrams 2024-03-01 19:30:31 -08:00
parent c6a39fb622
commit ca4799e524
8 changed files with 176 additions and 116 deletions

View file

@ -385,15 +385,43 @@ Web pages look pretty good with EWW, but I'm having difficulty getting it to ren
:config
(ha-leader "a b" '("eww browser" . eww))
(defun ha-eww-save-off-window (name)
(interactive (list (read-string "Name: " (plist-get eww-data :title))))
(rename-buffer (format "*eww: %s*" name) t))
(major-mode-hydra-define eww-mode nil
("Browser"
(("G" eww-browse "Browse")
("B" eww-list-bookmarks "Bookmarks")
("q" bury-buffer "Quit"))
"History"
(("l" eww-back-url "Back" :color pink)
("r" eww-forward-url "Forward" :color pink)
("H" eww-list-histories "History"))
"Current Page"
(("b" eww-add-bookmark "Bookmark")
("g" link-hint-open-link "Jump Link")
("d" eww-download "Download"))
"Render Page"
(("e" eww-browse-with-external-browser "Open in Firefox")
("R" eww-readable "Reader Mode")
("y" eww-copy-page-url "Copy URL"))
"Navigation"
(("u" eww-top-url "Site Top")
("n" eww-next-url "Next Page")
("p" eww-previous-url "Previous"))
"Toggles"
(("c" eww-toggle-colors "Colors")
("i" eww-toggle-images "Images")
("f" eww-toggle-fonts "Fonts"))
"Misc"
(("s" ha-eww-save-off-window "Rename")
("S" eww-switch-to-buffer "Switch to")
("-" eww-write-bookmarks "Save Bookmarks")
("M" eww-read-bookmarks "Load Bookmarks"))))
:general
(:states 'normal :keymaps 'eww-mode-map
"B" 'eww-list-bookmarks
"Y" 'eww-copy-page-url
"H" 'eww-back-url
"L" 'eww-forward-url
"u" 'eww-top-url
"p" 'eww-previous-url
"n" 'eww-next-url
"q" 'bury-buffer)
(:states 'normal :keymaps 'eww-buffers-mode-map
"q" 'bury-buffer))
@ -662,17 +690,12 @@ Id like write notes in org files that link to the PDFs (and maybe visa versa)
#+begin_src emacs-lisp
(use-package org-noter
:config
(ha-leader "o N" '("pdf notes" . org-noter))
(ha-local-leader
:keymaps 'org-noter-doc-mode-map
"n" '("pdf notes" . org-noter)
;; This means that I can stay in normal mode:
:keymaps 'org-noter-notes-mode-map
"i" '("insert note" . org-noter-insert-note)
"s" '("sync note" . org-noter-sync-current-note)
"n" '("next note" . org-noter-sync-next-note)
"p" '("previous note" . org-noter-sync-prev-note)))
(major-mode-hydra-define org-noter-doc-mode-map nil
("Notes"
(("i" org-noter-insert-note "insert note")
("s" org-noter-sync-current-note "sync note")
("n" org-noter-sync-next-note "next note" :color pink)
("p" org-noter-sync-prev-note "previous note" :color pink)))))
#+end_src
To use, open a header in an org doc, and run =M-x org-noter= (~SPC o N~) and select the PDF. The =org-noter= function can be called in the PDF doc as well. In Emacs state, type ~i~ to insert a note /as a header/, or in Normal state, type ~, i~.

View file

@ -47,20 +47,42 @@ I would like a dedicate perspective to Mastodon, and I would like a leader key s
(persp-names) "mastodon" 'equal)))
(persp-switch "mastodon")
(unless already-tooted?
(ha-local-leader :keymaps 'mastodon-mode-map
;; "," '("thread" . mastodon-tl--thread)
"t" '("toot" . mastodon-toot)
"u" '("update" . mastodon-tl--update)
"f" '("favorite" . mastodon-toot--toggle-favourite)
"b" '("boost" . mastodon-toot--toggle-boost)
"r" '("reply" . mastodon-toot--reply)
"s" '("share" . mastodon-toot--copy-toot-url)
"y" '("copy text" . mastodon-toot--copy-toot-text)
"d" '("discover" . mastodon-discover))
(my-mastodon-start))))
(mastodon))))
(ha-leader
"a m" '("mastodon" . mastodon-perspective)))
"a m" '("mastodon" . mastodon-perspective))
(use-package major-mode-hydra
:config
(major-mode-hydra-define mastodon-mode nil
("Timelines"
(("u" mastodon-tl--update "update")
("F" mastodon-tl--get-federated-timeline "Federated")
("H" mastodon-tl--get-home-timeline "Home")
("L" mastodon-tl--get-local-timeline "Local")
("T" mastodon-tl--get-tag-timeline "Hashtag"))
"Specials"
(("M" mastodon-notifications--get-mentions "Mentions")
("N" mastodon-notifications-get "Notifications")
("A" mastodon-tl--followed-tags-timeline "All Tags")
("S" mastodon-profile--view-bookmarks "Saved bookmarks")
("O" mastodon-profile--my-profile "My Profile"))
"Post"
(("c" mastodon-toot "Compose toot")
("e" mastodon-toot--edit-toot-at-point "Edit toot")
("t" mastodon-tl--thread "Read thread")
("r" mastodon-toot--reply "Reply")
("m" mastodon-tl--dm-user "Direct Msg")
("d" mastodon-toot--delete-toot "Delete"))
"Toot"
(("f" mastodon-toot--toggle-favourite "Favorite")
("b" mastodon-toot--toggle-boost "Boost")
("s" mastodon-toot--toggle-bookmark "Save")
("y" mastodon-toot--copy-toot-url "Copy URL")
("Y" mastodon-toot--copy-toot-text "Copy text"))
"Navigation"
(("n" mastodon-tl--next-tab-item "next" :color pink)
("p" mastodon-tl--previous-tab-item "previous" :color pink))))))
#+end_src
Lets turn on non-fixed-width fonts to make everything easier to read:
@ -68,16 +90,6 @@ Lets turn on non-fixed-width fonts to make everything easier to read:
(use-package mastodon
:hook (mastodon-mode . mixed-pitch-mode))
#+end_src
Starting the =mastodon= perspective, I set some initial windows:
#+begin_src emacs-lisp
(defun my-mastodon-start ()
"Configure the window placement for a Mastodon Instance."
(let ((default-directory (getenv "HOME")))
(mastodon)
(switch-to-buffer "*mastodon-home*")
(split-window-right)
(mastodon-tl--get-local-timeline)
(switch-to-buffer "*mastodon-local*")))
#+end_src
** Matrix/Element
Yet another encrypted chat/VoIP client-server, but unlike Signal and Telegram, [[matrix.org][Matrix]] is act ually open source. In other words, a project for nerds. Well be using Alphapapas latest [[https://github.c om/alphapapa/ement.el][ement]] project.

View file

@ -298,9 +298,15 @@ Pressing the ~SPACE~ can activate a /leader key sequence/ I define in my [[file:
#+begin_src emacs-lisp
(ha-hamacs-load "ha-general.org")
#+end_src
*Note:* This code extends the =use-package= to include a =:general= keybinding section, that I use elsewhere, so I need to pull it in now.
** Text Completion Packages
*** Auto Completion
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 the [[https://github.com/jerrypnz/major-mode-hydra.el][Major Mode Hydra]] project:
#+begin_src emacs-lisp
(use-package major-mode-hydra
:config
(global-set-key (kbd "s-,") #'major-mode-hydra))
#+end_src
** Additional Global Packages
The following defines my use of the Emacs completion system. Ive decided my /rules/ will be:
- Nothing should automatically appear; that is annoying and distracting.
- Spelling in org files (abbrev or hippie expander) and code completion are separate, but Im not sure if I can split them

View file

@ -102,15 +102,17 @@ And some leader-based keybindings:
(use-package notmuch
:config
(ha-leader ; Should I put these under an "m" heading?
"a n" '("new mail" . notmuch-retrieve-messages)
"a e" '("new mail" . notmuch-retrieve-messages)
"a m" '("read mail" . notmuch)
"a c" '("compose mail" . compose-mail))
(ha-local-leader :keymaps 'notmuch-hello-mode-map
"u" '("new mail" . notmuch-retrieve-messages)
"m" '("read mail" . notmuch)
"c" '("compose" . notmuch-mua-new-mail)
"C" '("reply-later" . hey-notmuch-reply-later))
(major-mode-hydra-define notmuch-hello-mode nil
("Mail"
(("u" notmuch-retrieve-messages "new mail")
("m" notmuch "read mail"))
"Messages"
(("c" notmuch-mua-new-mail "compose")
("C" hey-notmuch-reply-later "reply-later"))))
<<hey-show-keybindings>>
<<hey-search-keybindings>>)
@ -643,9 +645,10 @@ This means:
A series of keybindings to quickly send messages to one of the pre-defined buckets.
#+NAME: hey-show-keybindings
#+begin_src emacs-lisp :tangle no
(ha-local-leader :keymaps 'notmuch-show-mode-map
"c" '("compose" . notmuch-mua-new-mail)
"C" '("reply-later" . hey-notmuch-reply-later))
(major-mode-hydra-define notmuch-show-mode nil
("Messages"
(("c" notmuch-mua-new-mail "compose")
("C" hey-notmuch-reply-later "reply-later"))))
(define-key notmuch-show-mode-map (kbd "C") 'hey-notmuch-reply-later)
#+end_src
@ -654,23 +657,26 @@ The bindings in =notmuch-search-mode= are available when looking at a list of me
#+NAME: hey-search-keybindings
#+begin_src emacs-lisp :tangle no
(ha-local-leader :keymaps 'notmuch-search-mode-map
"r" '("reply" . notmuch-search-reply-to-thread)
"R" '("reply-all" . notmuch-search-reply-to-thread-sender)
"/" '("search" . notmuch-search-filter)
"A" '("archive all" . hey-notmuch-archive-all)
"D" '("delete all" . hey-notmuch-delete-all)
"L" '("filter by from" . hey-notmuch-filter-by-from)
";" '("search by from" . hey-notmuch-search-by-from)
"d" '("delete thread" . hey-notmuch-search-delete-and-archive-thread)
"s" '("send to spam" . hey-notmuch-move-sender-to-spam)
"i" '("send to screened" . hey-notmuch-move-sender-to-screened)
"p" '("send to papertrail" . hey-notmuch-move-sender-to-papertrail)
"f" '("send to feed" . hey-notmuch-move-sender-to-thefeed)
"C" '("reply" . hey-notmuch-reply-later)
"c" '("compose" . notmuch-mua-new-mail))
(major-mode-hydra-define notmuch-search-mode nil
("Mail"
(("r" notmuch-search-reply-to-thread "reply")
("R" notmuch-search-reply-to-thread-sender "reply-all")
("A" hey-notmuch-archive-all "archive all")
("D" hey-notmuch-delete-all "delete all")
("d" hey-notmuch-search-delete-and-archive-thread "delete thread"))
"Search"
(("/" notmuch-search-filter "search")
("L" hey-notmuch-filter-by-from "filter by from")
(";" hey-notmuch-search-by-from "search by from"))
"Messages"
(("s" hey-notmuch-move-sender-to-spam "send to spam")
("i" hey-notmuch-move-sender-to-screened "send to screened")
("p" hey-notmuch-move-sender-to-papertrail "send to papertrail")
("f" hey-notmuch-move-sender-to-thefeed "send to feed")
("C" hey-notmuch-reply-later "reply")
("c" notmuch-mua-new-mail) "compose")))
;; And if I can remember the keybindings...
(define-key notmuch-search-mode-map (kbd "r") 'notmuch-search-reply-to-thread)
(define-key notmuch-search-mode-map (kbd "R") 'notmuch-search-reply-to-thread-sender)
(define-key notmuch-search-mode-map (kbd "/") 'notmuch-search-filter)
@ -691,9 +697,10 @@ The gods ordained that Mail and Org should dance together, so step one is compos
#+begin_src emacs-lisp
(use-package org-mime
:config
(ha-local-leader :keymaps 'notmuch-message-mode-map
"s" '("send" . notmuch-mua-send-and-exit)
"m" '("mime it" . org-mime-htmlize)))
(major-mode-hydra-define notmuch-message-mode nil
("Messages"
(("s" notmuch-mua-send-and-exit "send")
("m" org-mime-htmlize "mime it")))))
#+end_src
A new option is to use [[https://github.com/jeremy-compostella/org-msg][org-msg]], so let's try it:
#+begin_src emacs-lisp :noweb yes

View file

@ -75,6 +75,10 @@ The Escape key act like ~C-g~ and always go back to normal mode?
(use-package evil
:config
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
;; Let's connect my major-mode-hydra to a global keybinding:
(evil-define-key 'normal 'global "," 'major-mode-hydra)
(evil-mode))
#+end_src

View file

@ -29,28 +29,46 @@ Let's get our feeds from a collection of org mode files. By default, Doom config
#+begin_src emacs-lisp
(use-package elfeed
:init
:config
;; While I would like to share the /status/ of my reads, so ...
(setq elfeed-db-directory "~/dropbox/.elfeed/")
;; Let's limit what is initially displayed, and then expand it:
(setq elfeed-search-filter "@6-months-ago +unread -science -funny")
;; While not an elfeed-specific variable, this make reading articles
;; with images easier:
(setq pixel-scroll-precision-mode t)
:general
(:states 'normal :keymaps 'elfeed-show-mode-map
"b" 'elfeed-show-visit
"n" 'elfeed-show-next
"p" 'elfeed-show-prev
"y" 'elfeed-show-yank
"q" 'kill-buffer
"o" 'link-hint-open-link ; This is why this package depends on link-hint:
"Q" 'delete-window)
(:states 'normal :keymaps 'elfeed-search-mode-map
"r" 'ha-elfeed-tag-unread
"R" 'elfeed-search-update--force
"u" 'elfeed-update
"U" 'elfeed-unjam))
(defvar ha-elfeeds-title
(concat (all-the-icons-faicon "rss") " Feed Reader"))
(major-mode-hydra-define elfeed-search-mode
(:title ha-elfeeds-title)
("Feeds"
(("U" (elfeed-search-fetch 4) "Refresh Feeds")
("u" elfeed-update "Update Screen")
("f" elfeed-search-live-filter "Filter")
("F" elfeed-search-clear-filter "Clear Filter")
("X" elfeed-unjam "Unjam"))
"Entry"
(("r" elfeed-search-untag-all-unread "Mark read" :color pink)
("R" ha-elfeed-tag-unread "Mark read/refresh")
("y" elfeed-search-yank "Copy URL"))))
(major-mode-hydra-define elfeed-show-mode
(:title ha-elfeeds-title)
("Entry"
(("n" elfeed-show-next "Next Entry" :color pink)
("p" elfeed-show-prev "Previous Entry" :color pink))
"Read"
(("b" elfeed-show-visit "Show in EWW")
("B" elfeed-show-visit-gui "Show in Browser")
("y" elfeed-show-yank "Copy URL"))
"Navigation"
(("o" link-hint-open-link "Open Link")
("q" bury-buffer "Close")
("Q" delete-window "Close Window")))))
(defun ha-elfeed-tag-unread ()
(interactive)
@ -61,38 +79,28 @@ Let's get our feeds from a collection of org mode files. By default, Doom config
According to Ben Maughan and [[http://pragmaticemacs.com/emacs/to-eww-or-not-to-eww/][this Pragmatic Emacs essay]], we could easily browse an article in the GUI browser instead of EWW with capital B:
#+begin_src emacs-lisp
(use-package elfeed
:config
(defun elfeed-show-visit-gui ()
"Wrapper for elfeed-show-visit to use gui browser instead of eww"
(interactive)
(let ((browse-url-generic-program "/usr/bin/open"))
(elfeed-show-visit t)))
:bind (:map elfeed-show-mode-map
("B" . elfeed-show-visit-gui)))
(defun elfeed-show-visit-gui ()
"Wrapper for elfeed-show-visit to use gui browser instead of eww"
(interactive)
(let ((browse-url-generic-program "/usr/bin/open"))
(elfeed-show-visit t)))
#+end_src
Quick way to start and jump to my world of feeds.
#+begin_src emacs-lisp
(defun ha-elfeed-persp-start ()
(defun ha-elfeed-persp ()
"Create an ELFEED workspace and start my ELFEED client."
(interactive)
(persp-switch "feeds")
(elfeed))
(defun ha-elfeed-persp-switch ()
"Switch to the ELFEED workspace and load the next buffer."
(interactive)
(persp-switch "feeds"))
(let ((already-reading? (seq-contains-p
(persp-names) "feeds" 'equal)))
(persp-switch "feeds")
(unless already-reading?
(elfeed))))
#+end_src
And some global keys to display them in the =apps= menu:
#+begin_src emacs-lisp
(ha-leader
"a f" '("elfeed switch" . ha-elfeed-persp-switch)
"a F" '("elfeed start" . ha-elfeed-persp-start))
(ha-leader "a f" '("elfeed switch" . ha-elfeed-persp))
#+end_src
* The Feeds :elfeed:
The [[https://github.com/remyhonig/elfeed-org][elfeed-org]] project configures =elfeed= to read the RSS feeds from an Org file … like this one!

View file

@ -46,9 +46,7 @@ I'm not trying an experiment where specially-placed function keys on my fancy er
(general-create-definer ha-local-leader
:states '(normal visual motion)
:prefix ","
:global-prefix "<f17>"
:non-normal-prefix "S-SPC")
:global-prefix "<f17>")
(general-nmap "SPC m" (general-simulate-key "," :which-key "major mode")))
#+end_src

View file

@ -121,11 +121,13 @@ And some global keys to display them:
And a quick shortcuts to call it:
#+begin_src emacs-lisp
(ha-local-leader :keymaps '(erc-mode-map)
"o" '("next channel" . erc-track-switch-buffer)
"w" '("resize text" . ha-erc-resize-text)
"r" '("reconnect" . ha-erc-connect-irc)
"p" '("send password" . ha-erc-reconnect-password))
(major-mode-hydra-define erc-mode nil
("Server"
(("r" ha-erc-connect-irc "reconnect")
("p" ha-erc-reconnect-password) "send password")
"Channel"
(("o" erc-track-switch-buffer "next channel")
("w" ha-erc-resize-text "resize text"))))
#+end_src
* Display Configuration
Using the [[https://github.com/seagle0128/doom-modeline][Doom Modeline]] to add notifications: