emacs: review update

This commit is contained in:
Pavel Korytov 2025-02-20 12:00:18 +03:00
parent fbd9314bb7
commit e0d3b3e7e2
2 changed files with 387 additions and 73 deletions

View file

@ -3311,6 +3311,12 @@ Returns (<buffer> . <workspace-index>) or nil."
(with-eval-after-load 'org
(org-link-set-parameters "rel" :follow #'browse-url :export #'my/export-rel-url))
(defun my/outline-prev-or-up-heading ()
(interactive)
(if (outline-on-heading-p)
(outline-up-heading 1)
(outline-previous-visible-heading 1)))
(with-eval-after-load 'org
(general-define-key
:keymaps 'org-mode-map
@ -3330,6 +3336,7 @@ Returns (<buffer> . <workspace-index>) or nil."
"M-9" #'org-previous-visible-heading
"C-0" #'org-forward-heading-same-level
"C-9" #'org-backward-heading-same-level
"(" #'my/outline-prev-or-up-heading
"M-]" #'org-babel-next-src-block
"M-[" #'org-babel-previous-src-block)
@ -5128,23 +5135,59 @@ KEYS is a list of cons cells like (<label> . <time>)."
(let ((default-directory org-directory))
(my/get-files-status (format "@{%s}" date))))
(defun my/org-review-format-org-roam (date)
(defun my/org-review--org-roam-get-changes (date)
(let ((changes (my/org-changed-files-since-date date))
(nodes (org-roam-node-list))
(nodes-by-file (make-hash-table :test #'equal)))
(cl-loop for node in nodes
for file = (org-roam-node-file node)
do (puthash file node nodes-by-file))
(let* ((changed-nodes
(thread-last
changes
(mapcar (lambda (c)
(cons (car c)
(gethash
(concat org-directory "/" (cdr c))
nodes-by-file))))
(seq-filter #'cdr)))
(changed-inbox
(thread-last
changes
(seq-filter
(lambda (file) (string-match-p (rx bos "inbox-notes") (cdr file))))))
(changed-fleeting
(thread-last
changed-nodes
(seq-filter (lambda (c)
(seq-contains-p (org-roam-node-tags (cdr c))
"fleeting")))
(seq-sort-by (lambda (c) (concat (symbol-name (car c))
(org-roam-node-title (cdr c))))
#'string-lessp)))
(changed-permanent
(thread-last
changed-nodes
(seq-filter (lambda (c)
(not (seq-contains-p (org-roam-node-tags (cdr c))
"fleeting"))))
(seq-sort-by (lambda (c) (concat (symbol-name (car c))
(org-roam-node-title (cdr c))))
#'string-lessp))))
(list
changed-inbox
changed-fleeting
changed-permanent))))
(defun my/org-review-org-roam-format (date)
(let* ((data (my/org-review--org-roam-get-changes date))
(changed-inbox (nth 0 data))
(changed-fleeting (nth 1 data))
(changed-permanent (nth 2 data)))
(concat
"*** Zettelkasten Updates\n"
"TODO Sort the updates by topics\n\n"
"Changes in inbox:\n"
(thread-last
changes
(seq-filter
(lambda (file) (string-match-p (rx bos "inbox-notes") (cdr file))))
(seq-sort-by (lambda (s) (symbol-name (car s)))
#'string-lessp)
changed-inbox
(mapcar (lambda (change)
(format "- %s :: %s\n"
(cond
@ -5154,18 +5197,18 @@ KEYS is a list of cons cells like (<label> . <time>)."
(t (capitalize (symbol-name (car change)))))
(cdr change))))
(apply #'concat))
"\nChanges in notes:\n"
"\nChanges in fleeting notes:\n"
(thread-last
changes
changed-fleeting
(mapcar (lambda (c)
(cons (car c)
(gethash
(concat org-directory "/" (cdr c))
nodes-by-file))))
(seq-filter #'cdr)
(seq-sort-by (lambda (c) (concat (symbol-name (car c))
(org-roam-node-title (cdr c))))
#'string-lessp)
(format "- %s :: [[id:%s][%s]]\n"
(capitalize (symbol-name (car c)))
(org-roam-node-id (cdr c))
(org-roam-node-title (cdr c)))))
(apply #'concat))
"\nChanges in permanent notes:\n"
(thread-last
changed-permanent
(mapcar (lambda (c)
(format "- %s :: [[id:%s][%s]]\n"
(capitalize (symbol-name (car c)))
@ -5183,13 +5226,17 @@ KEYS is a list of cons cells like (<label> . <time>)."
('weekly
(- start-of-day
(* 21 24 60 60)))
('zk
(- start-of-day
(* 45 24 60 60)))
(_ (error "Unsupported kind: %s" kind)))
:location 'section
:order 'descending)))
(if query-res
(org-journal-tag-reference-date (car query-res))
(pcase kind
('weekly (- start-of-day (* 7 24 60 60)))))))
('weekly (- start-of-day (* 7 24 60 60)))
('zk (- start-of-day (* 45 24 60 60)))))))
(defun my/org-review-set-weekly-record ()
(save-excursion
@ -5204,7 +5251,7 @@ KEYS is a list of cons cells like (<label> . <time>)."
(seconds-to-time last-review-date)))
(insert "
Review checklist:
Review checklist (/delete this/):
- [ ] Clear email inbox
- [ ] Reconcile ledger
- [ ] Clear [[file:~/Downloads][downloads]] and [[file:~/00-Scratch][scratch]] folders
@ -5221,8 +5268,6 @@ Review checklist:
- [ ] Review journal records
")
(insert (my/org-review-format-org-roam
(format-time-string "%Y-%m-%d" (seconds-to-time last-review-date))))
(insert "
*** Summary
TODO Write something, maybe? "))))
@ -5247,12 +5292,17 @@ TODO Write something, maybe? "))))
(call-process-shell-command "pkill -f element-desktop"))
(defun my/org-review-set-daily-record ()
(save-excursion
(org-journal-tags-prop-apply-delta :add '("review.daily"))
(insert "Daily Review")
(goto-char (point-max))
(let* ((today (format-time-string
"%Y-%m-%d"
(days-to-time
(- (org-today) (time-to-days 0)))))
(roam-changes (my/org-review--org-roam-get-changes today)))
(save-excursion
(org-journal-tags-prop-apply-delta :add '("review.daily"))
(insert "Daily Review")
(goto-char (point-max))
(insert "
(insert "
Maintenance checklist (/delete this/):
- [ ] [[elisp:(my/kill-messengers)][Close all messengers]]
- [ ] Process [[file:../inbox.org][inbox]]
@ -5271,13 +5321,22 @@ Happened to the world:
*** New ideas
/Write them down in org-roam with the \"fleeting\" tag; leave links here. Perhaps note what sparked that idea?/
"
(thread-last
(nth 1 roam-changes)
(seq-filter (lambda (c) (eq 'added (car c))))
(mapcar (lambda (c)
(format "- [[id:%s][%s]]\n"
(org-roam-node-id (cdr c))
(org-roam-node-title (cdr c)))))
(apply #'concat))
"
*** Interactions today
/Any meaninginful interactions, conflicts or tensions?/
*** Emotions today
/How did I feel?/
")))
"))))
(defun my/org-review-daily ()
(interactive)
@ -5290,6 +5349,93 @@ Happened to the world:
(with-eval-after-load 'org-journal
(my-leader-def "ojd" #'my/org-review-daily))
(defun my/org-review-org-roam-format-zk-before (date)
(let* ((data (my/org-review--org-roam-get-changes date))
(changed-inbox (nth 0 data))
(changed-fleeting (nth 1 data))
(changed-permanent (nth 2 data)))
(concat
(when changed-inbox
(concat
"Process these changes in inbox:\n"
(thread-last
changed-inbox
(mapcar (lambda (change)
(format "- [ ] %s :: %s\n"
(cond
((or (member (car change) '(deleted moved))
(string-match-p "figured-out" (cdr change)))
"Processed")
(t (capitalize (symbol-name (car change)))))
(cdr change))))
(apply #'concat))
"\n"))
(when changed-fleeting
(concat
"Process these fleeting notes:\n"
(thread-last
changed-fleeting
(mapcar (lambda (c)
(format "- [ ] %s :: [[id:%s][%s]]\n"
(capitalize (symbol-name (car c)))
(org-roam-node-id (cdr c))
(org-roam-node-title (cdr c)))))
(apply #'concat))
"\n"))
(when changed-permanent
(concat
"Check these changes in permanent notes:\n"
(thread-last
changed-permanent
(mapcar (lambda (c)
(format "- [ ] %s :: [[id:%s][%s]]\n"
(capitalize (symbol-name (car c)))
(org-roam-node-id (cdr c))
(org-roam-node-title (cdr c)))))
(apply #'concat)))))))
(defun my/org-review-org-roam-finish (date)
(org-roam-db-sync)
(save-excursion
(org-back-to-heading)
(replace-regexp
(rx
":BEGIN_REVIEW:" (* anything) ":END_REVIEW:")
(string-trim
(my/org-review-org-roam-format date)))))
(defun my/org-review-set-zk-record ()
(save-excursion
(let ((last-review-date (my/org-review-get-last-review-date 'zk)))
(org-journal-tags-prop-apply-delta :add '("review.zk"))
(insert "Zettelkasten Review")
(goto-char (point-max))
(insert "Last review date: "
(format-time-string
"[%Y-%m-%d]"
(seconds-to-time last-review-date)))
(insert "\n\n:BEGIN_REVIEW:\n"
"Process all the required categories in this block, then execute \"Finish review\".\n\n"
(string-trim
(my/org-review-org-roam-format-zk-before last-review-date))
"\n\n[[elisp:(my/org-review-org-roam-finish \""
(format-time-string "%Y-%m-%d" last-review-date)
"\")][Finish review]]"
"\n:END_REVIEW:\n"))))
(defun my/org-review-zk ()
(interactive)
(let ((org-journal-after-entry-create-hook
`(,@org-journal-after-entry-create-hook
my/org-review-set-zk-record)))
(org-journal-new-entry nil)
(org-fold-show-subtree)))
(with-eval-after-load 'org-journal
(my-leader-def "ojz" #'my/org-review-zk))
(use-package org-contacts
:straight (:type git :repo "https://repo.or.cz/org-contacts.git")
:if (not my/remote-server)
@ -8037,13 +8183,18 @@ base toot."
:commands (gptel gptel-send gptel-menu)
:config
(setq gptel-mode "llama3:latest")
(setq gptel-backend (gptel-make-ollama "Ollama"
:host "localhost:11434"
:stream t
:models '("llama3.1:8b" "deepseek-r1:32b"
"qwen2.5:32b" "qwen2.5-coder:32b"
"eva-qwen2.5-q4_k_l-32b:latest"
"t-pro-1.0-q4_k_m:latest")))
(setq gptel-track-media t)
(setq gptel-backend
(gptel-make-ollama "Ollama"
:host "localhost:11434"
:stream t
:models '("llama3.1:8b" "deepseek-r1:32b"
"qwen2.5:32b" "qwen2.5-coder:32b"
"eva-qwen2.5-q4_k_l-32b:latest"
"t-pro-1.0-q4_k_m:latest"
(llava-phi3:latest
:capabilities (media)
:mime-types ("image/jpeg" "image/png")))))
(gptel-make-openai "OpenRouter"
:host "openrouter.ai/api"
:key (lambda () (my/password-store-get-field

237
Emacs.org
View file

@ -2305,7 +2305,7 @@ Run =M-x all-the-icons-install-fonts= at first setup.
:straight t)
#+end_src
** Text highlight
Highlight indent guides. I used [[https://github.com/DarthFennec/highlight-indent-guides][highlight-indent-guides]] before but [[https://github.com/jdtsmith/indent-bars][indent-bars]] seems to work better, and also doesn't break with =treesit-fold=.
Highlight indent guides. I used [[https://github.com/DarthFennec/highlight-indent-guides][highlight-indent-guides]] before but [[https://github.com/jdtsmith/indent-bars][indent-bars]] seems to work better, and it doesn't break with =treesit-fold=.
#+begin_src emacs-lisp
(use-package indent-bars
:straight (:host github :repo "jdtsmith/indent-bars")
@ -4616,6 +4616,12 @@ I've moved this block above because the =my-leader-def= expression in the next b
*** General keybindings
#+begin_src emacs-lisp
(defun my/outline-prev-or-up-heading ()
(interactive)
(if (outline-on-heading-p)
(outline-up-heading 1)
(outline-previous-visible-heading 1)))
(with-eval-after-load 'org
(general-define-key
:keymaps 'org-mode-map
@ -4635,6 +4641,7 @@ I've moved this block above because the =my-leader-def= expression in the next b
"M-9" #'org-previous-visible-heading
"C-0" #'org-forward-heading-same-level
"C-9" #'org-backward-heading-same-level
"(" #'my/outline-prev-or-up-heading
"M-]" #'org-babel-next-src-block
"M-[" #'org-babel-previous-src-block)
@ -7076,23 +7083,59 @@ I'll use it to get a list of added and changed files in the Org directory since
I'll use data from git to get the list of what I've been working on. The directories include =org-roam= itself and =inbox-notes=, where my in-process notes live.
#+begin_src emacs-lisp
(defun my/org-review-format-org-roam (date)
(defun my/org-review--org-roam-get-changes (date)
(let ((changes (my/org-changed-files-since-date date))
(nodes (org-roam-node-list))
(nodes-by-file (make-hash-table :test #'equal)))
(cl-loop for node in nodes
for file = (org-roam-node-file node)
do (puthash file node nodes-by-file))
(let* ((changed-nodes
(thread-last
changes
(mapcar (lambda (c)
(cons (car c)
(gethash
(concat org-directory "/" (cdr c))
nodes-by-file))))
(seq-filter #'cdr)))
(changed-inbox
(thread-last
changes
(seq-filter
(lambda (file) (string-match-p (rx bos "inbox-notes") (cdr file))))))
(changed-fleeting
(thread-last
changed-nodes
(seq-filter (lambda (c)
(seq-contains-p (org-roam-node-tags (cdr c))
"fleeting")))
(seq-sort-by (lambda (c) (concat (symbol-name (car c))
(org-roam-node-title (cdr c))))
#'string-lessp)))
(changed-permanent
(thread-last
changed-nodes
(seq-filter (lambda (c)
(not (seq-contains-p (org-roam-node-tags (cdr c))
"fleeting"))))
(seq-sort-by (lambda (c) (concat (symbol-name (car c))
(org-roam-node-title (cdr c))))
#'string-lessp))))
(list
changed-inbox
changed-fleeting
changed-permanent))))
(defun my/org-review-org-roam-format (date)
(let* ((data (my/org-review--org-roam-get-changes date))
(changed-inbox (nth 0 data))
(changed-fleeting (nth 1 data))
(changed-permanent (nth 2 data)))
(concat
"*** Zettelkasten Updates\n"
"TODO Sort the updates by topics\n\n"
"Changes in inbox:\n"
(thread-last
changes
(seq-filter
(lambda (file) (string-match-p (rx bos "inbox-notes") (cdr file))))
(seq-sort-by (lambda (s) (symbol-name (car s)))
#'string-lessp)
changed-inbox
(mapcar (lambda (change)
(format "- %s :: %s\n"
(cond
@ -7102,18 +7145,18 @@ I'll use data from git to get the list of what I've been working on. The directo
(t (capitalize (symbol-name (car change)))))
(cdr change))))
(apply #'concat))
"\nChanges in notes:\n"
"\nChanges in fleeting notes:\n"
(thread-last
changes
changed-fleeting
(mapcar (lambda (c)
(cons (car c)
(gethash
(concat org-directory "/" (cdr c))
nodes-by-file))))
(seq-filter #'cdr)
(seq-sort-by (lambda (c) (concat (symbol-name (car c))
(org-roam-node-title (cdr c))))
#'string-lessp)
(format "- %s :: [[id:%s][%s]]\n"
(capitalize (symbol-name (car c)))
(org-roam-node-id (cdr c))
(org-roam-node-title (cdr c)))))
(apply #'concat))
"\nChanges in permanent notes:\n"
(thread-last
changed-permanent
(mapcar (lambda (c)
(format "- %s :: [[id:%s][%s]]\n"
(capitalize (symbol-name (car c)))
@ -7133,13 +7176,17 @@ I'll use data from git to get the list of what I've been working on. The directo
('weekly
(- start-of-day
(* 21 24 60 60)))
('zk
(- start-of-day
(* 45 24 60 60)))
(_ (error "Unsupported kind: %s" kind)))
:location 'section
:order 'descending)))
(if query-res
(org-journal-tag-reference-date (car query-res))
(pcase kind
('weekly (- start-of-day (* 7 24 60 60)))))))
('weekly (- start-of-day (* 7 24 60 60)))
('zk (- start-of-day (* 45 24 60 60)))))))
#+end_src
**** Weekly review
#+begin_src emacs-lisp
@ -7156,7 +7203,7 @@ I'll use data from git to get the list of what I've been working on. The directo
(seconds-to-time last-review-date)))
(insert "
Review checklist:
Review checklist (/delete this/):
- [ ] Clear email inbox
- [ ] Reconcile ledger
- [ ] Clear [[file:~/Downloads][downloads]] and [[file:~/00-Scratch][scratch]] folders
@ -7173,8 +7220,6 @@ Review checklist:
- [ ] Review journal records
")
(insert (my/org-review-format-org-roam
(format-time-string "%Y-%m-%d" (seconds-to-time last-review-date))))
(insert "
,*** Summary
TODO Write something, maybe? "))))
@ -7209,12 +7254,17 @@ I try to keep it under 10-15 minutes.
#+begin_src emacs-lisp
(defun my/org-review-set-daily-record ()
(save-excursion
(org-journal-tags-prop-apply-delta :add '("review.daily"))
(insert "Daily Review")
(goto-char (point-max))
(let* ((today (format-time-string
"%Y-%m-%d"
(days-to-time
(- (org-today) (time-to-days 0)))))
(roam-changes (my/org-review--org-roam-get-changes today)))
(save-excursion
(org-journal-tags-prop-apply-delta :add '("review.daily"))
(insert "Daily Review")
(goto-char (point-max))
(insert "
(insert "
Maintenance checklist (/delete this/):
- [ ] [[elisp:(my/kill-messengers)][Close all messengers]]
- [ ] Process [[file:../inbox.org][inbox]]
@ -7233,13 +7283,22 @@ Happened to the world:
,*** New ideas
/Write them down in org-roam with the \"fleeting\" tag; leave links here. Perhaps note what sparked that idea?/
"
(thread-last
(nth 1 roam-changes)
(seq-filter (lambda (c) (eq 'added (car c))))
(mapcar (lambda (c)
(format "- [[id:%s][%s]]\n"
(org-roam-node-id (cdr c))
(org-roam-node-title (cdr c)))))
(apply #'concat))
"
,*** Interactions today
/Any meaninginful interactions, conflicts or tensions?/
,*** Emotions today
/How did I feel?/
")))
"))))
#+end_src
#+begin_src emacs-lisp
@ -7256,6 +7315,104 @@ Happened to the world:
(with-eval-after-load 'org-journal
(my-leader-def "ojd" #'my/org-review-daily))
#+end_src
**** ZK review
Mostly incorporating or discarding my fleeting notes here.
This function formats the list of notes to review:
#+begin_src emacs-lisp
(defun my/org-review-org-roam-format-zk-before (date)
(let* ((data (my/org-review--org-roam-get-changes date))
(changed-inbox (nth 0 data))
(changed-fleeting (nth 1 data))
(changed-permanent (nth 2 data)))
(concat
(when changed-inbox
(concat
"Process these changes in inbox:\n"
(thread-last
changed-inbox
(mapcar (lambda (change)
(format "- [ ] %s :: %s\n"
(cond
((or (member (car change) '(deleted moved))
(string-match-p "figured-out" (cdr change)))
"Processed")
(t (capitalize (symbol-name (car change)))))
(cdr change))))
(apply #'concat))
"\n"))
(when changed-fleeting
(concat
"Process these fleeting notes:\n"
(thread-last
changed-fleeting
(mapcar (lambda (c)
(format "- [ ] %s :: [[id:%s][%s]]\n"
(capitalize (symbol-name (car c)))
(org-roam-node-id (cdr c))
(org-roam-node-title (cdr c)))))
(apply #'concat))
"\n"))
(when changed-permanent
(concat
"Check these changes in permanent notes:\n"
(thread-last
changed-permanent
(mapcar (lambda (c)
(format "- [ ] %s :: [[id:%s][%s]]\n"
(capitalize (symbol-name (car c)))
(org-roam-node-id (cdr c))
(org-roam-node-title (cdr c)))))
(apply #'concat)))))))
#+end_src
#+begin_src emacs-lisp
(defun my/org-review-org-roam-finish (date)
(org-roam-db-sync)
(save-excursion
(org-back-to-heading)
(replace-regexp
(rx
":BEGIN_REVIEW:" (* anything) ":END_REVIEW:")
(string-trim
(my/org-review-org-roam-format date)))))
#+end_src
#+begin_src emacs-lisp
(defun my/org-review-set-zk-record ()
(save-excursion
(let ((last-review-date (my/org-review-get-last-review-date 'zk)))
(org-journal-tags-prop-apply-delta :add '("review.zk"))
(insert "Zettelkasten Review")
(goto-char (point-max))
(insert "Last review date: "
(format-time-string
"[%Y-%m-%d]"
(seconds-to-time last-review-date)))
(insert "\n\n:BEGIN_REVIEW:\n"
"Process all the required categories in this block, then execute \"Finish review\".\n\n"
(string-trim
(my/org-review-org-roam-format-zk-before last-review-date))
"\n\n[[elisp:(my/org-review-org-roam-finish \""
(format-time-string "%Y-%m-%d" last-review-date)
"\")][Finish review]]"
"\n:END_REVIEW:\n"))))
#+end_src
#+begin_src emacs-lisp
(defun my/org-review-zk ()
(interactive)
(let ((org-journal-after-entry-create-hook
`(,@org-journal-after-entry-create-hook
my/org-review-set-zk-record)))
(org-journal-new-entry nil)
(org-fold-show-subtree)))
(with-eval-after-load 'org-journal
(my-leader-def "ojz" #'my/org-review-zk))
#+end_src
*** Contacts
=org-contacts= is a package to store contacts in an org file.
@ -10464,6 +10621,7 @@ Source: [[https://fortelabs.com/blog/the-secret-power-of-read-it-later-apps/][Ti
(setq wallabag-clientid (password-store-get-field "Selfhosted/wallabag" "client_id"))
(setq wallabag-secret (password-store-get-field "Selfhosted/wallabag" "client_secret")))
#+end_src
*** ement.el
[[https://github.com/alphapapa/ement.el][ement.el]] is a Matrix client for Emacs. This package turned out to be somewhat complicated to setup.
@ -11013,13 +11171,18 @@ I don't have access to any proprietary APIs, but LLaMA 3.1 8b with [[https://oll
:commands (gptel gptel-send gptel-menu)
:config
(setq gptel-mode "llama3:latest")
(setq gptel-backend (gptel-make-ollama "Ollama"
:host "localhost:11434"
:stream t
:models '("llama3.1:8b" "deepseek-r1:32b"
"qwen2.5:32b" "qwen2.5-coder:32b"
"eva-qwen2.5-q4_k_l-32b:latest"
"t-pro-1.0-q4_k_m:latest")))
(setq gptel-track-media t)
(setq gptel-backend
(gptel-make-ollama "Ollama"
:host "localhost:11434"
:stream t
:models '("llama3.1:8b" "deepseek-r1:32b"
"qwen2.5:32b" "qwen2.5-coder:32b"
"eva-qwen2.5-q4_k_l-32b:latest"
"t-pro-1.0-q4_k_m:latest"
(llava-phi3:latest
:capabilities (media)
:mime-types ("image/jpeg" "image/png")))))
(gptel-make-openai "OpenRouter"
:host "openrouter.ai/api"
:key (lambda () (my/password-store-get-field