Tweak emacs agenda and mu4e settings

This commit is contained in:
Nathan McCarty 2022-09-11 20:17:00 -04:00
parent 435d5ea61b
commit feee8c590e
Signed by: thatonelutenist
GPG Key ID: D70DA3DD4D1E9F96
2 changed files with 253 additions and 2 deletions

View File

@ -279,6 +279,121 @@ work if it thinks it needs to."
(use-package! anki-editor)
(after! org
(setq org-agenda-custom-commands
'(("p" . "Project Views"))))
(defun org-compare--get-marker (entry)
"Return the marker for ENTRY.
This marker points to the location of the headline referenced by
ENTRY."
(get-text-property 1 'org-marker entry))
(defvar org-compare-random-refresh nil
"Whether `org-compare-randomly' should refresh its keys.
See the docs for `org-compare-randomly' for more information.")
(defun org-compare-randomly--update-sort-key (entry table generator)
"Return sort key for ENTRY in TABLE, generating it if necessary.
For internal use by `org-compare-randomly-by'."
(let* ((marker (org-compare--get-marker entry))
(hash-key `(,(marker-buffer marker) . ,(marker-position marker))))
(or (gethash hash-key table)
(puthash hash-key (funcall generator entry) table))))
(defun org-compare-randomly-by (generator)
"Return a random comparator using GENERATOR.
The comparator returned is like `org-compare-randomly', except
the distribution of random keys is controlled by GENERATOR and
may thus be non-uniform.
The function GENERATOR is called with a single argument, an
agenda entry, when that entry lacks a sort key. It should return
a number, which is then used for all comparisons until the key
list is cleared; see `org-compare-randomly' for more details on
this.
Subsequent calls to `org-compare-randomly-by' produce comparators
with independent sets of sort keys."
(let ((table (make-hash-table :test #'equal)))
(lambda (x y)
(when org-compare-random-refresh
(clrhash table)
(setq org-compare-random-refresh nil))
(let ((x-val (org-compare-randomly--update-sort-key x table generator))
(y-val (org-compare-randomly--update-sort-key y table generator)))
(cond
((= x-val y-val) nil)
((< x-val y-val) -1)
((> x-val y-val) +1))))))
(defun org-compare-randomly ()
"Return a comparator implementing a random shuffle.
When given distinct agenda entries X and Y, the resulting
comparator has an equal chance of returning +1 and -1 (and a
miniscule chance of returning nil). Subsequent calls will produce
results consistent with a total ordering.
To accomplish this, a hash table of randomly-generated sort keys
is maintained. This table will persist until the comparator is
called when the variable `org-compare-random-refresh' is non-nil.
This means that setting this variable as part of a custom agenda
command using this comparator as `org-agenda-cmp-user-defined'
will cause the sort order to change whenever the agenda is
refreshed; otherwise, it will persist until Emacs is restarted.
Note that if you don't want the sort order to change on refresh,
you need to be careful that the comparator is created when the
custom agenda command is defined, not when it's called, e.g.
(add-to-list
'org-agenda-custom-commands
`(\"y\" \"Example Agenda\"
((todo
\"\"
((org-agenda-cmp-user-defined ',(org-compare-randomly))
(org-agenda-sorting-strategy '(user-defined-up)))))))
\(Notice the use of backquote.)
Comparators resulting from different calls to this function have
independent key tables."
(org-compare-randomly-by (lambda (_) (random))))
(after! org
(add-to-list 'org-agenda-custom-commands
'("pr" "Random Project TODOs"
((tags "proj/TODO"
((org-agenda-max-entries 5)
(org-agenda-cmp-user-defined (org-compare-randomly))
(org-compare-random-refresh t)
(org-agenda-sorting-strategy '(user-defined-up))))
(tags "proj/STRT"
((org-agenda-max-entries 5)
(org-agenda-cmp-user-defined (org-compare-randomly))
(org-compare-random-refresh t)
(org-agenda-sorting-strategy '(user-defined-up))))
(tags "proj/PROJ"
((org-agenda-max-entries 5)
(org-agenda-cmp-user-defined (org-compare-randomly))
(org-compare-random-refresh t)
(org-agenda-sorting-strategy '(user-defined-up))))
(todo "IDEA"
((org-agenda-max-entries 5)
(org-agenda-cmp-user-defined (org-compare-randomly))
(org-compare-random-refresh t)
(org-agenda-sorting-strategy '(user-defined-up))))))))
(after! org
(setq org-agenda-dim-blocked-tasks nil))
(after! org
(setq org-tag-alist '(("proj" . ?p))))
(use-package! magit-todos
:hook (magit-mode . magit-todos-mode))
@ -403,7 +518,10 @@ work if it thinks it needs to."
(setq mu4e-maildir-shortcuts
'((:maildir "/nathan@mccarty.io/Folders/Notifications/Github" :key ?h)
(:maildir "/nathan@mccarty.io/Folders/Notifications/Gitlab" :key ?l)
(:maildir "/nathan@mccarty.io/Folders/Notifications/SourceHut" :key ?s))))
(:maildir "/nathan@mccarty.io/Folders/Notifications/SourceHut" :key ?s)
(:maildir "/nathan@mccarty.io/Folders/Archival/Receipts/2022" :key ?r)
(:maildir "/nathan@mccarty.io/Folders/Job Search" :key ?j)
(:maildir "/nathan@mccarty.io/Folders/Archival/Informed Delivery" :key ?i))))
(after! mu4e
(mu4e-alert-enable-mode-line-display))

View File

@ -1,3 +1,4 @@
# -*- lexical-binding: t; -*-
#+title: Nathan's Doom Emacs Configuration
#+author: Nathan McCarty
#+PROPERTY: header-args:emacs-lisp :tangle yes
@ -398,6 +399,135 @@ Flash cards from within emacs.
#+begin_src emacs-lisp
(use-package! anki-editor)
#+end_src
** org-agenda customization
Empty out the list and define our prefixes first
#+begin_src emacs-lisp
(after! org
(setq org-agenda-custom-commands
'(("p" . "Project Views"))))
#+end_src
*** Random project selection
First some library code
#+begin_src emacs-lisp
(defun org-compare--get-marker (entry)
"Return the marker for ENTRY.
This marker points to the location of the headline referenced by
ENTRY."
(get-text-property 1 'org-marker entry))
(defvar org-compare-random-refresh nil
"Whether `org-compare-randomly' should refresh its keys.
See the docs for `org-compare-randomly' for more information.")
(defun org-compare-randomly--update-sort-key (entry table generator)
"Return sort key for ENTRY in TABLE, generating it if necessary.
For internal use by `org-compare-randomly-by'."
(let* ((marker (org-compare--get-marker entry))
(hash-key `(,(marker-buffer marker) . ,(marker-position marker))))
(or (gethash hash-key table)
(puthash hash-key (funcall generator entry) table))))
(defun org-compare-randomly-by (generator)
"Return a random comparator using GENERATOR.
The comparator returned is like `org-compare-randomly', except
the distribution of random keys is controlled by GENERATOR and
may thus be non-uniform.
The function GENERATOR is called with a single argument, an
agenda entry, when that entry lacks a sort key. It should return
a number, which is then used for all comparisons until the key
list is cleared; see `org-compare-randomly' for more details on
this.
Subsequent calls to `org-compare-randomly-by' produce comparators
with independent sets of sort keys."
(let ((table (make-hash-table :test #'equal)))
(lambda (x y)
(when org-compare-random-refresh
(clrhash table)
(setq org-compare-random-refresh nil))
(let ((x-val (org-compare-randomly--update-sort-key x table generator))
(y-val (org-compare-randomly--update-sort-key y table generator)))
(cond
((= x-val y-val) nil)
((< x-val y-val) -1)
((> x-val y-val) +1))))))
(defun org-compare-randomly ()
"Return a comparator implementing a random shuffle.
When given distinct agenda entries X and Y, the resulting
comparator has an equal chance of returning +1 and -1 (and a
miniscule chance of returning nil). Subsequent calls will produce
results consistent with a total ordering.
To accomplish this, a hash table of randomly-generated sort keys
is maintained. This table will persist until the comparator is
called when the variable `org-compare-random-refresh' is non-nil.
This means that setting this variable as part of a custom agenda
command using this comparator as `org-agenda-cmp-user-defined'
will cause the sort order to change whenever the agenda is
refreshed; otherwise, it will persist until Emacs is restarted.
Note that if you don't want the sort order to change on refresh,
you need to be careful that the comparator is created when the
custom agenda command is defined, not when it's called, e.g.
(add-to-list
'org-agenda-custom-commands
`(\"y\" \"Example Agenda\"
((todo
\"\"
((org-agenda-cmp-user-defined ',(org-compare-randomly))
(org-agenda-sorting-strategy '(user-defined-up)))))))
\(Notice the use of backquote.)
Comparators resulting from different calls to this function have
independent key tables."
(org-compare-randomly-by (lambda (_) (random))))
#+end_src
Then add our custom command, one section for "TODO"s and another for top level "PROJ"s
#+begin_src emacs-lisp
(after! org
(add-to-list 'org-agenda-custom-commands
'("pr" "Random Project TODOs"
((tags "proj/TODO"
((org-agenda-max-entries 5)
(org-agenda-cmp-user-defined (org-compare-randomly))
(org-compare-random-refresh t)
(org-agenda-sorting-strategy '(user-defined-up))))
(tags "proj/STRT"
((org-agenda-max-entries 5)
(org-agenda-cmp-user-defined (org-compare-randomly))
(org-compare-random-refresh t)
(org-agenda-sorting-strategy '(user-defined-up))))
(tags "proj/PROJ"
((org-agenda-max-entries 5)
(org-agenda-cmp-user-defined (org-compare-randomly))
(org-compare-random-refresh t)
(org-agenda-sorting-strategy '(user-defined-up))))
(todo "IDEA"
((org-agenda-max-entries 5)
(org-agenda-cmp-user-defined (org-compare-randomly))
(org-compare-random-refresh t)
(org-agenda-sorting-strategy '(user-defined-up))))))))
#+end_src
*** Don't dim blocked tasks
Not only does this feature have performance issues, its not useful with how I use org
#+begin_src emacs-lisp
(after! org
(setq org-agenda-dim-blocked-tasks nil))
#+end_src
** Set tags alist
#+begin_src emacs-lisp
(after! org
(setq org-tag-alist '(("proj" . ?p))))
#+end_src
* General Modes
** Magit
Further configuration for magit
@ -627,7 +757,10 @@ Setup the maildirs we want to see, we'll show our notifications
(setq mu4e-maildir-shortcuts
'((:maildir "/nathan@mccarty.io/Folders/Notifications/Github" :key ?h)
(:maildir "/nathan@mccarty.io/Folders/Notifications/Gitlab" :key ?l)
(:maildir "/nathan@mccarty.io/Folders/Notifications/SourceHut" :key ?s))))
(:maildir "/nathan@mccarty.io/Folders/Notifications/SourceHut" :key ?s)
(:maildir "/nathan@mccarty.io/Folders/Archival/Receipts/2022" :key ?r)
(:maildir "/nathan@mccarty.io/Folders/Job Search" :key ?j)
(:maildir "/nathan@mccarty.io/Folders/Archival/Informed Delivery" :key ?i))))
#+end_src
Tell it to enable the modeline display
#+begin_src emacs-lisp