This commit is contained in:
SqrtMinusOne 2024-05-11 13:46:45 +00:00
parent 19d4d2e3c5
commit 50a7188aa4
5 changed files with 343 additions and 238 deletions

View file

@ -4356,21 +4356,21 @@ Emacs is also particularly great at writing Lisp code, e.g. Clojure, Common Lisp
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/update-org-agenda</span> ()
</span></span><span style="display:flex;"><span> (<span style="color:#008000">interactive</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">let</span> ((<span style="color:#19177c">project-files</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">mapcar</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">f</span>) (<span style="color:#00f">concat</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">org-directory</span> <span style="color:#ba2121">&#34;/projects/&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">f</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">seq-filter</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">f</span>) (<span style="color:#19177c">not</span> (<span style="color:#00f">file-directory-p</span> <span style="color:#19177c">f</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">when</span> (<span style="color:#00f">file-directory-p</span> (<span style="color:#00f">concat</span> <span style="color:#19177c">org-directory</span> <span style="color:#ba2121">&#34;/projects&#34;</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">directory-files</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">concat</span> <span style="color:#19177c">org-directory</span> <span style="color:#ba2121">&#34;/projects&#34;</span>)))))))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">when</span> (<span style="color:#00f">file-directory-p</span> (<span style="color:#00f">concat</span> <span style="color:#19177c">org-directory</span> <span style="color:#ba2121">&#34;/projects&#34;</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">thread-last</span> <span style="color:#ba2121">&#34;/projects&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">concat</span> <span style="color:#19177c">org-directory</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">directory-files</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">mapcar</span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">f</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">concat</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">org-directory</span> <span style="color:#ba2121">&#34;/projects/&#34;</span> <span style="color:#19177c">f</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">seq-filter</span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">f</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">not</span> (<span style="color:#00f">file-directory-p</span> <span style="color:#19177c">f</span>))))))))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">setq</span> <span style="color:#19177c">org-agenda-files</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">seq-filter</span> <span style="color:#00f">#&#39;file-exists-p</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">`</span>(<span style="color:#ba2121">&#34;inbox.org&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;misc/habit.org&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;contacts.org&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">,@</span><span style="color:#19177c">project-files</span>)))
</span></span><span style="display:flex;"><span> <span style="color:#666">`</span>(<span style="color:#ba2121">&#34;inbox.org&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;misc/habit.org&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;contacts.org&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">,@</span><span style="color:#19177c">project-files</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">setq</span> <span style="color:#19177c">org-refile-targets</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">`</span>(<span style="color:#666">,@</span>(<span style="color:#00f">mapcar</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">f</span>) <span style="color:#666">`</span>(<span style="color:#666">,</span><span style="color:#19177c">f</span> <span style="color:#666">.</span> (<span style="color:#008000">:tag</span> <span style="color:#666">.</span> <span style="color:#ba2121">&#34;refile&#34;</span>)))
@ -4579,6 +4579,8 @@ Emacs is also particularly great at writing Lisp code, e.g. Clojure, Common Lisp
</span></span><span style="display:flex;"><span> <span style="color:#008000">:after</span> (<span style="color:#19177c">org</span>)
</span></span><span style="display:flex;"><span> <span style="color:#008000">:if</span> (<span style="color:#19177c">not</span> <span style="color:#19177c">my/remote-server</span>)
</span></span><span style="display:flex;"><span> <span style="color:#008000">:straight</span> <span style="color:#800">t</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:config</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">setq</span> <span style="color:#19177c">org-ql-ask-unsafe-queries</span> <span style="color:#800">nil</span>)
</span></span><span style="display:flex;"><span> <span style="color:#008000">:init</span>
</span></span><span style="display:flex;"><span> <span style="color:#408080;font-style:italic">;; See https://github.com/alphapapa/org-ql/pull/237</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">setq</span> <span style="color:#19177c">org-ql-regexp-part-ts-time</span>
@ -4713,7 +4715,7 @@ Emacs is also particularly great at writing Lisp code, e.g. Clojure, Common Lisp
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">ivy-prescient-sort-commands</span> <span style="color:#800">nil</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">categories</span> (<span style="color:#19177c">completing-read-multiple</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;Categories: &#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">&#39;</span>(<span style="color:#ba2121">&#34;TEACH&#34;</span> <span style="color:#ba2121">&#34;EDU&#34;</span> <span style="color:#ba2121">&#34;JOB&#34;</span> <span style="color:#ba2121">&#34;LIFE&#34;</span> <span style="color:#ba2121">&#34;CONFIG&#34;</span>))))
</span></span><span style="display:flex;"><span> <span style="color:#666">&#39;</span>(<span style="color:#ba2121">&#34;TEACH&#34;</span> <span style="color:#ba2121">&#34;EDU&#34;</span> <span style="color:#ba2121">&#34;JOB&#34;</span> <span style="color:#ba2121">&#34;LIFE&#34;</span> <span style="color:#ba2121">&#34;COMP&#34;</span>))))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-ql-search</span> (<span style="color:#19177c">org-agenda-files</span>)
</span></span><span style="display:flex;"><span> <span style="color:#666">`</span>(<span style="color:#008000">and</span> (<span style="color:#19177c">todo</span>)
</span></span><span style="display:flex;"><span> <span style="color:#666">,@</span>(<span style="color:#008000">unless</span> (<span style="color:#19177c">seq-empty-p</span> <span style="color:#19177c">categories</span>)
@ -4728,6 +4730,7 @@ Emacs is also particularly great at writing Lisp code, e.g. Clojure, Common Lisp
</span></span><span style="display:flex;"><span> (<span style="color:#00f">cons</span> <span style="color:#ba2121">&#34;Review: Stale tasks&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">list</span> <span style="color:#008000">:buffers-files</span> <span style="color:#00f">#&#39;</span><span style="color:#19177c">org-agenda-files</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:query</span> <span style="color:#666">&#39;</span>(<span style="color:#008000">and</span> (<span style="color:#19177c">todo</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">not</span> (<span style="color:#19177c">tags</span> <span style="color:#ba2121">&#34;nots&#34;</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">not</span> (<span style="color:#19177c">ts</span> <span style="color:#008000">:from</span> <span style="color:#666">-14</span>)))
</span></span><span style="display:flex;"><span> <span style="color:#008000">:title</span> <span style="color:#ba2121">&#34;Review: Stale tasks&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:sort</span> <span style="color:#666">&#39;</span>(<span style="color:#19177c">todo</span> <span style="color:#19177c">priority</span> <span style="color:#19177c">date</span>)
@ -5025,23 +5028,23 @@ Emacs is also particularly great at writing Lisp code, e.g. Clojure, Common Lisp
</span></span><span style="display:flex;"><span> (<span style="color:#00f">current-time</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">*</span> <span style="color:#666">60</span> <span style="color:#666">60</span> <span style="color:#666">24</span>)))
</span></span><span style="display:flex;"><span> <span style="color:#008000">:with-time</span> <span style="color:#800">t</span>))
</span></span><span style="display:flex;"><span> <span style="color:#008000">:order-by</span> <span style="color:#19177c">&#39;date</span>))
</span></span><span style="display:flex;"><span> <span style="color:#19177c">scheduled-keys</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">cl-loop</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">item</span> <span style="color:#19177c">in</span> <span style="color:#19177c">items</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">scheduled</span> <span style="color:#00f">=</span> (<span style="color:#19177c">org-timestamp-to-time</span> (<span style="color:#19177c">org-element-property</span> <span style="color:#008000">:scheduled</span> <span style="color:#19177c">item</span>))
</span></span><span style="display:flex;"><span> <span style="color:#008000">do</span> (<span style="color:#008000">cl-loop</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">before-time</span> <span style="color:#19177c">in</span> <span style="color:#19177c">my/org-alert-notify-times</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">label</span> <span style="color:#00f">=</span> (<span style="color:#00f">format</span> <span style="color:#ba2121">&#34;%s at %s [%s min. remaining]&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-element-property</span> <span style="color:#008000">:raw-value</span> <span style="color:#19177c">item</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">format-time-string</span> <span style="color:#ba2121">&#34;%H:%M&#34;</span> <span style="color:#19177c">scheduled</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">number-to-string</span> (<span style="color:#00f">/</span> <span style="color:#19177c">before-time</span> <span style="color:#666">60</span>)))
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">time</span> <span style="color:#00f">=</span> (<span style="color:#19177c">time-convert</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">+</span> (<span style="color:#19177c">time-convert</span> <span style="color:#19177c">scheduled</span> <span style="color:#19177c">&#39;integer</span>) (<span style="color:#00f">-</span> <span style="color:#19177c">before-time</span>)))
</span></span><span style="display:flex;"><span> <span style="color:#008000">do</span> (<span style="color:#008000">progn</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">my/org-alert--schedule</span> <span style="color:#19177c">label</span> <span style="color:#19177c">time</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">push</span> (<span style="color:#00f">cons</span> <span style="color:#19177c">label</span> <span style="color:#19177c">time</span>) <span style="color:#19177c">scheduled-keys</span>))))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">my/org-alert-cleanup</span> <span style="color:#19177c">scheduled-keys</span>)))
</span></span><span style="display:flex;"><span> <span style="color:#008000">:order-by</span> <span style="color:#19177c">&#39;date</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">let</span> (<span style="color:#19177c">scheduled-keys</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">cl-loop</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">item</span> <span style="color:#19177c">in</span> <span style="color:#19177c">items</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">scheduled</span> <span style="color:#00f">=</span> (<span style="color:#19177c">org-timestamp-to-time</span> (<span style="color:#19177c">org-element-property</span> <span style="color:#008000">:scheduled</span> <span style="color:#19177c">item</span>))
</span></span><span style="display:flex;"><span> <span style="color:#008000">do</span> (<span style="color:#008000">cl-loop</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">before-time</span> <span style="color:#19177c">in</span> <span style="color:#19177c">my/org-alert-notify-times</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">label</span> <span style="color:#00f">=</span> (<span style="color:#00f">format</span> <span style="color:#ba2121">&#34;%s at %s [%s min. remaining]&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-element-property</span> <span style="color:#008000">:raw-value</span> <span style="color:#19177c">item</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">format-time-string</span> <span style="color:#ba2121">&#34;%H:%M&#34;</span> <span style="color:#19177c">scheduled</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">number-to-string</span> (<span style="color:#00f">/</span> <span style="color:#19177c">before-time</span> <span style="color:#666">60</span>)))
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">time</span> <span style="color:#00f">=</span> (<span style="color:#19177c">time-convert</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">+</span> (<span style="color:#19177c">time-convert</span> <span style="color:#19177c">scheduled</span> <span style="color:#19177c">&#39;integer</span>) (<span style="color:#00f">-</span> <span style="color:#19177c">before-time</span>)))
</span></span><span style="display:flex;"><span> <span style="color:#008000">do</span> (<span style="color:#008000">progn</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">my/org-alert--schedule</span> <span style="color:#19177c">label</span> <span style="color:#19177c">time</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">push</span> (<span style="color:#00f">cons</span> <span style="color:#19177c">label</span> <span style="color:#19177c">time</span>) <span style="color:#19177c">scheduled-keys</span>))))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">my/org-alert-cleanup</span> <span style="color:#19177c">scheduled-keys</span>))))
</span></span></code></pre></div><p>Let&rsquo;s wrap it into a minor mode:</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">setq</span> <span style="color:#19177c">my/org-alert--timer</span> <span style="color:#800">nil</span>)
</span></span><span style="display:flex;"><span>
@ -5229,7 +5232,9 @@ Emacs is also particularly great at writing Lisp code, e.g. Clojure, Common Lisp
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;&#34;</span> <span style="color:#666">&#39;</span>(<span style="color:#008000">:which-key</span> <span style="color:#ba2121">&#34;org-mode&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;c&#34;</span> <span style="color:#19177c">&#39;org-capture</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;a&#34;</span> <span style="color:#19177c">&#39;org-agenda</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;o&#34;</span> <span style="color:#00f">#&#39;</span><span style="color:#19177c">my/org-file-open</span>)
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;o&#34;</span> <span style="color:#00f">#&#39;</span><span style="color:#19177c">my/org-file-open</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;v&#34;</span> <span style="color:#00f">#&#39;</span><span style="color:#19177c">org-ql-view</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;q&#34;</span> <span style="color:#00f">#&#39;</span><span style="color:#19177c">org-ql-search</span>)
</span></span></code></pre></div><p>Local keybindings</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">with-eval-after-load</span> <span style="color:#19177c">&#39;org</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">my-leader-def</span>
@ -5653,18 +5658,27 @@ Didn&rsquo;t work out as I expected, so I&rsquo;ve made <code>org-journal-tags</
</span></span><span style="display:flex;"><span>(<span style="color:#008000">with-eval-after-load</span> <span style="color:#19177c">&#39;deft</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">advice-add</span> <span style="color:#00f">#&#39;</span><span style="color:#19177c">deft-parse-title</span> <span style="color:#008000">:around</span> <span style="color:#00f">#&#39;</span><span style="color:#19177c">my/deft-parse-title-around</span>))
</span></span></code></pre></div><h4 id="review-workflow">Review workflow</h4>
<p>UPD <span class="timestamp-wrapper"><span class="timestamp">&lt;2022-03-27 Sun&gt;</span></span>. Out of action for now</p>
<p>My take on a review workflow. As a baseline, I want to have a template that lists the important changes since the last review and other basic information. I&rsquo;m doing reviews regularly, but the time intervals still may vary, hence this flexibility.</p>
<p>This section has seen some updates over time.</p>
<p>Tiago Forte has several few interesting blog posts:</p>
<ul>
<li><a href="https://fortelabs.com/blog/the-weekly-review-is-an-operating-system/">The Weekly Review is an Operating System</a></li>
<li><a href="https://fortelabs.com/blog/the-design-of-a-weekly-review/">The Design of a Weekly Review</a></li>
</ul>
<p>This is probably my third time to implement a weekly review.</p>
<p>I want two general things from the workflow:</p>
<ul>
<li>to perform maintainance operations, such as clearing various inboxes;</li>
<li>to reflect on what I&rsquo;ve done over the past week.</li>
</ul>
<p>For the second point I&rsquo;ll try to collect data from various sources and add the data to my review template.</p>
<h5 id="data-from-git">Data from git</h5>
<p>First, as I have <a href="/configs/console/#autocommit">autocommit</a> set up in my org directory, here is a handy function to get an alist of changed files of a form <code>(status . path)</code>. In principle, the <code>rev</code> parameter can be a commit, tag, etc but here I&rsquo;m interested in a form like <code>@{2021-08-30}</code>.</p>
<p>Also in principle, Org Roam DB also stores stuff like creation time and modification time, but I started this section before I started using Org Roam extensively, so git works fine for me.</p>
<p>First, as I have <a href="/configs/console/#autocommit">autocommit</a> set up in my org directory, here is a function to get an alist of changed files in a form <code>(status . path)</code>. The <code>rev</code> parameter can be a commit, tag, etc. but here I&rsquo;m interested in the date form (e.g. <code>@{2021-08-30}</code>).</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">setq</span> <span style="color:#19177c">my/git-diff-status</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">&#39;</span>((<span style="color:#ba2121">&#34;A&#34;</span> <span style="color:#666">.</span> <span style="color:#19177c">added</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;C&#34;</span> <span style="color:#666">.</span> <span style="color:#19177c">copied</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;D&#34;</span> <span style="color:#666">.</span> <span style="color:#19177c">deleted</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;M&#34;</span> <span style="color:#666">.</span> <span style="color:#19177c">modified</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;R&#34;</span> <span style="color:#666">.</span> <span style="color:#19177c">renamed</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;R100&#34;</span> <span style="color:#666">.</span> <span style="color:#19177c">moved</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;T&#34;</span> <span style="color:#666">.</span> <span style="color:#19177c">type-changed</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;U&#34;</span> <span style="color:#666">.</span> <span style="color:#19177c">unmerged</span>)))
</span></span><span style="display:flex;"><span>
@ -5675,196 +5689,118 @@ Didn&rsquo;t work out as I expected, so I&rsquo;ve made <code>org-journal-tags</
</span></span><span style="display:flex;"><span> (<span style="color:#008000">let</span> ((<span style="color:#19177c">elems</span> (<span style="color:#19177c">split-string</span> <span style="color:#19177c">file</span> <span style="color:#ba2121">&#34;\t&#34;</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">cons</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">cdr</span> (<span style="color:#00f">assoc</span> (<span style="color:#00f">car</span> <span style="color:#19177c">elems</span>) <span style="color:#19177c">my/git-diff-status</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">nth</span> <span style="color:#666">1</span> <span style="color:#19177c">elems</span>))))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">car</span> (<span style="color:#19177c">last</span> <span style="color:#19177c">elems</span>)))))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">split-string</span> <span style="color:#19177c">files</span> <span style="color:#ba2121">&#34;\n&#34;</span> <span style="color:#800">t</span>))))
</span></span></code></pre></div><p>I&rsquo;ll use it to get a list of added and changed files in the Org directory since the last review. The date should be in a format <code>YYYY-MM-DD</code>.</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/org-changed-files-since-date</span> (<span style="color:#19177c">date</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">let</span> ((<span style="color:#19177c">default-directory</span> <span style="color:#19177c">org-directory</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">my/get-files-status</span> (<span style="color:#00f">format</span> <span style="color:#ba2121">&#34;@{%s}&#34;</span> <span style="color:#19177c">date</span>))))
</span></span></code></pre></div><h5 id="data-from-org-roam">Data from org-roam</h5>
<p>Now that we have the list of new &amp; changed files, I want to sort into a bunch of categories: projects, log entries, etc. The categories are defined by tags.</p>
<p>So here is a list of plists that sets these categories. The properties are as follows:</p>
<ul>
<li><code>:status</code> is a git status for the file</li>
<li><code>:tags</code> is a plist that sets up the following conditions for the Roam node
<ul>
<li><code>:include</code> - should be empty or one of these should be present</li>
<li><code>:exclude</code> - should be empty or none of these should be present</li>
</ul>
</li>
<li><code>:title</code> is the name of category as I want it to be seen in the review template</li>
</ul>
<!--listend-->
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">setq</span> <span style="color:#19177c">my/org-review-roam-queries</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">&#39;</span>((<span style="color:#008000">:status</span> <span style="color:#19177c">added</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:tags</span> (<span style="color:#008000">:include</span> (<span style="color:#ba2121">&#34;org&#34;</span>))
</span></span><span style="display:flex;"><span> <span style="color:#008000">:title</span> <span style="color:#ba2121">&#34;New Project Entries&#34;</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">:status</span> <span style="color:#19177c">changed</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:tags</span> (<span style="color:#008000">:include</span> (<span style="color:#ba2121">&#34;org&#34;</span>))
</span></span><span style="display:flex;"><span> <span style="color:#008000">:title</span> <span style="color:#ba2121">&#34;Changed Project Entries&#34;</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">:status</span> <span style="color:#19177c">added</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:tags</span> (<span style="color:#008000">:exclude</span> (<span style="color:#ba2121">&#34;org&#34;</span>))
</span></span><span style="display:flex;"><span> <span style="color:#008000">:title</span> <span style="color:#ba2121">&#34;New Zettelkasten Entries&#34;</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">:status</span> <span style="color:#19177c">changed</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:tags</span> (<span style="color:#008000">:exclude</span> (<span style="color:#ba2121">&#34;org&#34;</span>))
</span></span><span style="display:flex;"><span> <span style="color:#008000">:title</span> <span style="color:#ba2121">&#34;Changed Zettelkasten Entries&#34;</span>)))
</span></span></code></pre></div><p>This list is used to extract &amp; format the relevant section of the review template.</p>
<p><code>cl-loop</code> seems pretty good as a control flow structure, but I&rsquo;ll see if it is also pretty good at producing poorly maintainable code. At least at the moment of this writing, the function below looks rather concise.</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/org-review-format-roam</span> (<span style="color:#19177c">changes</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">cl-loop</span> <span style="color:#19177c">for</span> <span style="color:#19177c">query</span> <span style="color:#19177c">in</span> <span style="color:#19177c">my/org-review-roam-queries</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">with</span> <span style="color:#19177c">nodes</span> <span style="color:#00f">=</span> (<span style="color:#19177c">org-roam-node-list</span>)
</span></span><span style="display:flex;"><span> <span style="color:#19177c">with</span> <span style="color:#19177c">node-tags</span> <span style="color:#00f">=</span> (<span style="color:#00f">mapcar</span> <span style="color:#00f">#&#39;</span><span style="color:#19177c">org-roam-node-tags</span> <span style="color:#19177c">nodes</span>)
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">include-tags</span> <span style="color:#00f">=</span> (<span style="color:#00f">plist-get</span> (<span style="color:#00f">plist-get</span> <span style="color:#19177c">query</span> <span style="color:#008000">:tags</span>) <span style="color:#008000">:include</span>)
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">exclude-tags</span> <span style="color:#00f">=</span> (<span style="color:#00f">plist-get</span> (<span style="color:#00f">plist-get</span> <span style="color:#19177c">query</span> <span style="color:#008000">:tags</span>) <span style="color:#008000">:exclude</span>)
</span></span><span style="display:flex;"><span> <span style="color:#408080;font-style:italic">;; List of nodes filtered by :tags in query</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">filtered-nodes</span> <span style="color:#00f">=</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">cl-loop</span> <span style="color:#19177c">for</span> <span style="color:#19177c">node</span> <span style="color:#19177c">in</span> <span style="color:#19177c">nodes</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">tags</span> <span style="color:#19177c">in</span> <span style="color:#19177c">node-tags</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">if</span> (<span style="color:#008000">and</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">or</span> (<span style="color:#19177c">seq-empty-p</span> <span style="color:#19177c">include-tags</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">seq-intersection</span> <span style="color:#19177c">include-tags</span> <span style="color:#19177c">tags</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">or</span> (<span style="color:#19177c">seq-empty-p</span> <span style="color:#19177c">exclude-tags</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">not</span> (<span style="color:#19177c">seq-intersection</span> <span style="color:#19177c">exclude-tags</span> <span style="color:#19177c">tags</span>))))
</span></span><span style="display:flex;"><span> <span style="color:#19177c">collect</span> <span style="color:#19177c">node</span>)
</span></span><span style="display:flex;"><span> <span style="color:#408080;font-style:italic">;; List of changes filtered by :status in query</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">filtered-changes</span> <span style="color:#00f">=</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">cl-loop</span> <span style="color:#19177c">for</span> <span style="color:#19177c">change</span> <span style="color:#19177c">in</span> <span style="color:#19177c">changes</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">if</span> (<span style="color:#008000">and</span> (<span style="color:#00f">eq</span> (<span style="color:#00f">car</span> <span style="color:#19177c">change</span>) (<span style="color:#00f">plist-get</span> <span style="color:#19177c">query</span> <span style="color:#008000">:status</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">string-match-p</span> (<span style="color:#008000">rx</span> <span style="color:#19177c">bos</span> <span style="color:#ba2121">&#34;roam&#34;</span>) (<span style="color:#00f">cdr</span> <span style="color:#19177c">change</span>)))
</span></span><span style="display:flex;"><span> <span style="color:#19177c">collect</span> (<span style="color:#00f">cdr</span> <span style="color:#19177c">change</span>))
</span></span><span style="display:flex;"><span> <span style="color:#408080;font-style:italic">;; Intersection of the two filtered lists</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">final-nodes</span> <span style="color:#00f">=</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">cl-loop</span> <span style="color:#19177c">for</span> <span style="color:#19177c">node</span> <span style="color:#19177c">in</span> <span style="color:#19177c">filtered-nodes</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">path</span> <span style="color:#00f">=</span> (<span style="color:#19177c">file-relative-name</span> (<span style="color:#19177c">org-roam-node-file</span> <span style="color:#19177c">node</span>)
</span></span><span style="display:flex;"><span> <span style="color:#19177c">org-directory</span>)
</span></span><span style="display:flex;"><span> <span style="color:#008000">if</span> (<span style="color:#00f">member</span> <span style="color:#19177c">path</span> <span style="color:#19177c">filtered-changes</span>)
</span></span><span style="display:flex;"><span> <span style="color:#19177c">collect</span> <span style="color:#19177c">node</span>)
</span></span><span style="display:flex;"><span> <span style="color:#408080;font-style:italic">;; If the intersction list is not empty, format it to the result</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">if</span> <span style="color:#19177c">final-nodes</span>
</span></span><span style="display:flex;"><span> <span style="color:#00f">concat</span> (<span style="color:#00f">format</span> <span style="color:#ba2121">&#34;** %s\n&#34;</span> (<span style="color:#00f">plist-get</span> <span style="color:#19177c">query</span> <span style="color:#008000">:title</span>))
</span></span><span style="display:flex;"><span> <span style="color:#408080;font-style:italic">;; FInal list of links, sorted by title</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">and</span> <span style="color:#00f">concat</span> (<span style="color:#008000">cl-loop</span> <span style="color:#19177c">for</span> <span style="color:#19177c">node</span> <span style="color:#19177c">in</span> (<span style="color:#19177c">seq-sort</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">node1</span> <span style="color:#19177c">node2</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">string-lessp</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-roam-node-title</span> <span style="color:#19177c">node1</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-roam-node-title</span> <span style="color:#19177c">node2</span>)))
</span></span><span style="display:flex;"><span> <span style="color:#19177c">final-nodes</span>)
</span></span><span style="display:flex;"><span> <span style="color:#00f">concat</span> (<span style="color:#00f">format</span> <span style="color:#ba2121">&#34;- [[id:%s][%s]]\n&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-roam-node-id</span> <span style="color:#19177c">node</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-roam-node-title</span> <span style="color:#19177c">node</span>)))))
</span></span></code></pre></div><h5 id="data-from-org-agenda-via-org-ql">Data from org-agenda via org-ql</h5>
<p><del>Third</del> second, I want to list some changes in my agenda. This section will change depending on what I&rsquo;m currently working on.</p>
<p>So, here is a list of queries results of which I want to see in the review template. The format is <code>(name date-field order-by-field query)</code>.</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">setq</span> <span style="color:#19177c">my/org-ql-review-queries</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">`</span>((<span style="color:#ba2121">&#34;Waitlist&#34;</span> <span style="color:#19177c">scheduled</span> <span style="color:#19177c">scheduled</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">and</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">done</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">tags-inherited</span> <span style="color:#ba2121">&#34;waitlist&#34;</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;Personal tasks done&#34;</span> <span style="color:#19177c">closed</span> <span style="color:#666">,</span><span style="color:#800">nil</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">and</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">tags-inherited</span> <span style="color:#ba2121">&#34;personal&#34;</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">todo</span> <span style="color:#ba2121">&#34;DONE&#34;</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;Attended meetings&#34;</span> <span style="color:#19177c">closed</span> <span style="color:#19177c">scheduled</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">and</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">tags-inherited</span> <span style="color:#ba2121">&#34;meeting&#34;</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">todo</span> <span style="color:#ba2121">&#34;PASSED&#34;</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;Done project tasks&#34;</span> <span style="color:#19177c">closed</span> <span style="color:#19177c">deadline</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">and</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">todo</span> <span style="color:#ba2121">&#34;DONE&#34;</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">ancestors</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">heading</span> <span style="color:#ba2121">&#34;Tasks&#34;</span>))))))
</span></span></code></pre></div><p>The query will be executed like this: <code>(and (date-field :from rev-date) query)</code></p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/org-review-exec-ql</span> (<span style="color:#19177c">saved</span> <span style="color:#19177c">rev-date</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">let</span> ((<span style="color:#19177c">query</span> <span style="color:#666">`</span>(<span style="color:#008000">and</span>
</span></span><span style="display:flex;"><span> (<span style="color:#666">,</span>(<span style="color:#00f">nth</span> <span style="color:#666">1</span> <span style="color:#19177c">saved</span>) <span style="color:#008000">:from</span> <span style="color:#666">,</span><span style="color:#19177c">rev-date</span>)
</span></span><span style="display:flex;"><span> <span style="color:#666">,</span>(<span style="color:#00f">nth</span> <span style="color:#666">3</span> <span style="color:#19177c">saved</span>))))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-ql-query</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:select</span> <span style="color:#00f">#&#39;</span><span style="color:#19177c">element</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:from</span> (<span style="color:#19177c">org-agenda-files</span>)
</span></span><span style="display:flex;"><span> <span style="color:#008000">:where</span> <span style="color:#19177c">query</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:order-by</span> (<span style="color:#00f">nth</span> <span style="color:#666">2</span> <span style="color:#19177c">saved</span>))))
</span></span></code></pre></div><p>Format one element of the query result.</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/org-review-format-element</span> (<span style="color:#19177c">elem</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">concat</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">string-pad</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">plist-get</span> (<span style="color:#19177c">cadr</span> <span style="color:#19177c">elem</span>) <span style="color:#008000">:raw-value</span>)
</span></span><span style="display:flex;"><span> <span style="color:#666">40</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">when-let</span> (<span style="color:#19177c">scheduled</span> (<span style="color:#00f">plist-get</span> (<span style="color:#19177c">cadr</span> <span style="color:#19177c">elem</span>) <span style="color:#008000">:scheduled</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">concat</span> <span style="color:#ba2121">&#34; [SCHEDULED: &#34;</span> (<span style="color:#00f">plist-get</span> (<span style="color:#19177c">cadr</span> <span style="color:#19177c">scheduled</span>) <span style="color:#008000">:raw-value</span>) <span style="color:#ba2121">&#34;]&#34;</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">when-let</span> (<span style="color:#19177c">deadline</span> (<span style="color:#00f">plist-get</span> (<span style="color:#19177c">cadr</span> <span style="color:#19177c">elem</span>) <span style="color:#008000">:deadline</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">concat</span> <span style="color:#ba2121">&#34; [DEADLINE: &#34;</span> (<span style="color:#00f">plist-get</span> (<span style="color:#19177c">cadr</span> <span style="color:#19177c">deadline</span>) <span style="color:#008000">:raw-value</span>) <span style="color:#ba2121">&#34;]&#34;</span>))))
</span></span></code></pre></div><p>Execute all the saved queries and format an Org list for the capture template.</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/org-review-format-queries</span> (<span style="color:#19177c">rev-date</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">mapconcat</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">results</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">concat</span> <span style="color:#ba2121">&#34;** &#34;</span> (<span style="color:#00f">car</span> <span style="color:#19177c">results</span>) <span style="color:#ba2121">&#34;\n&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">string-join</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">mapcar</span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">r</span>) (<span style="color:#00f">concat</span> <span style="color:#ba2121">&#34;- &#34;</span> <span style="color:#19177c">r</span>)) (<span style="color:#00f">cdr</span> <span style="color:#19177c">results</span>))
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;\n&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;\n&#34;</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">seq-filter</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">result</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">not</span> (<span style="color:#19177c">seq-empty-p</span> (<span style="color:#00f">cdr</span> <span style="color:#19177c">result</span>))))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">mapcar</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">saved</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">cons</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">car</span> <span style="color:#19177c">saved</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">mapcar</span>
</span></span><span style="display:flex;"><span> <span style="color:#00f">#&#39;</span><span style="color:#19177c">my/org-review-format-element</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">my/org-review-exec-ql</span> <span style="color:#19177c">saved</span> <span style="color:#19177c">rev-date</span>))))
</span></span><span style="display:flex;"><span> <span style="color:#19177c">my/org-ql-review-queries</span>))
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;\n&#34;</span>))
</span></span></code></pre></div><h5 id="capture-template">Capture template</h5>
<p>Now, we have to put all this together and define a capture template for the review.</p>
<p><del>I&rsquo;ll use a separate directory for the review files, just like for org-journal and org-roam.</del> I&rsquo;ll store the review files in org-roam. Time will tell if that&rsquo;s a good idea. The filename will have a format <code>YYYY-MM-DD.org</code>, which will also free me from the effort of storing the last review date somewhere.</p>
<p>If somehow there are no files in the folder, fallback to the current date minus one two week. Also featuring the most awkward date transformation I&rsquo;ve ever done just to add one date.</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">setq</span> <span style="color:#19177c">my/org-review-directory</span> <span style="color:#ba2121">&#34;review&#34;</span>)
<p>I&rsquo;ll use data from git to get the list of what I&rsquo;ve been working on. The directories include <code>org-roam</code> itself and <code>inbox-notes</code>, where my in-process notes live.</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/org-review-format-org-roam</span> (<span style="color:#19177c">date</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">let</span> ((<span style="color:#19177c">changes</span> (<span style="color:#19177c">my/org-changed-files-since-date</span> <span style="color:#19177c">date</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">nodes</span> (<span style="color:#19177c">org-roam-node-list</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">nodes-by-file</span> (<span style="color:#00f">make-hash-table</span> <span style="color:#008000">:test</span> <span style="color:#00f">#&#39;equal</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">cl-loop</span> <span style="color:#19177c">for</span> <span style="color:#19177c">node</span> <span style="color:#19177c">in</span> <span style="color:#19177c">nodes</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">for</span> <span style="color:#19177c">file</span> <span style="color:#00f">=</span> (<span style="color:#19177c">org-roam-node-file</span> <span style="color:#19177c">node</span>)
</span></span><span style="display:flex;"><span> <span style="color:#008000">do</span> (<span style="color:#00f">puthash</span> <span style="color:#19177c">file</span> <span style="color:#19177c">node</span> <span style="color:#19177c">nodes-by-file</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">concat</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;*** Zettelkasten Updates\n&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;TODO Sort the updates by topics\n\n&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;Changes in inbox:\n&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">thread-last</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">changes</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">seq-filter</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">file</span>) (<span style="color:#19177c">string-match-p</span> (<span style="color:#008000">rx</span> <span style="color:#19177c">bos</span> <span style="color:#ba2121">&#34;inbox-notes&#34;</span>) (<span style="color:#00f">cdr</span> <span style="color:#19177c">file</span>))))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">seq-sort-by</span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">s</span>) (<span style="color:#00f">symbol-name</span> (<span style="color:#00f">car</span> <span style="color:#19177c">s</span>)))
</span></span><span style="display:flex;"><span> <span style="color:#00f">#&#39;string-lessp</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">mapcar</span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">change</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">format</span> <span style="color:#ba2121">&#34;- %s :: %s\n&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">cond</span>
</span></span><span style="display:flex;"><span> ((<span style="color:#008000">or</span> (<span style="color:#00f">member</span> (<span style="color:#00f">car</span> <span style="color:#19177c">change</span>) <span style="color:#666">&#39;</span>(<span style="color:#19177c">deleted</span> <span style="color:#19177c">moved</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">string-match-p</span> <span style="color:#ba2121">&#34;figured-out&#34;</span> (<span style="color:#00f">cdr</span> <span style="color:#19177c">change</span>)))
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;Processed&#34;</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#800">t</span> (<span style="color:#00f">capitalize</span> (<span style="color:#00f">symbol-name</span> (<span style="color:#00f">car</span> <span style="color:#19177c">change</span>)))))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">cdr</span> <span style="color:#19177c">change</span>))))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">apply</span> <span style="color:#00f">#&#39;concat</span>))
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;\nChanges in notes:\n&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">thread-last</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">changes</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">mapcar</span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">c</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">cons</span> (<span style="color:#00f">car</span> <span style="color:#19177c">c</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">gethash</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">concat</span> <span style="color:#19177c">org-directory</span> <span style="color:#ba2121">&#34;/&#34;</span> (<span style="color:#00f">cdr</span> <span style="color:#19177c">c</span>))
</span></span><span style="display:flex;"><span> <span style="color:#19177c">nodes-by-file</span>))))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">seq-filter</span> <span style="color:#00f">#&#39;cdr</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">seq-sort-by</span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">c</span>) (<span style="color:#00f">concat</span> (<span style="color:#00f">symbol-name</span> (<span style="color:#00f">car</span> <span style="color:#19177c">c</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-roam-node-title</span> (<span style="color:#00f">cdr</span> <span style="color:#19177c">c</span>))))
</span></span><span style="display:flex;"><span> <span style="color:#00f">#&#39;string-lessp</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">mapcar</span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">c</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">format</span> <span style="color:#ba2121">&#34;- %s :: [[id:%s][%s]]\n&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">capitalize</span> (<span style="color:#00f">symbol-name</span> (<span style="color:#00f">car</span> <span style="color:#19177c">c</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-roam-node-id</span> (<span style="color:#00f">cdr</span> <span style="color:#19177c">c</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-roam-node-title</span> (<span style="color:#00f">cdr</span> <span style="color:#19177c">c</span>)))))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">apply</span> <span style="color:#00f">#&#39;concat</span>)))))
</span></span></code></pre></div><h5 id="org-journal-integration">Org Journal integration</h5>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/org-review-get-last-review-date</span> (<span style="color:#19177c">kind</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">let*</span> ((<span style="color:#19177c">start-of-day</span> (<span style="color:#00f">-</span> (<span style="color:#19177c">time-convert</span> <span style="color:#800">nil</span> <span style="color:#00f">#&#39;</span><span style="color:#19177c">integer</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">%</span> (<span style="color:#19177c">time-convert</span> <span style="color:#800">nil</span> <span style="color:#00f">#&#39;</span><span style="color:#19177c">integer</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">*</span> <span style="color:#666">24</span> <span style="color:#666">60</span> <span style="color:#666">60</span>))))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">query-res</span> (<span style="color:#19177c">org-journal-tags-query</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:tag-names</span> (<span style="color:#00f">list</span> (<span style="color:#00f">format</span> <span style="color:#ba2121">&#34;review.%s&#34;</span> <span style="color:#19177c">kind</span>))
</span></span><span style="display:flex;"><span> <span style="color:#008000">:start-date</span> (<span style="color:#008000">pcase</span> <span style="color:#19177c">kind</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">&#39;weekly</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">-</span> <span style="color:#19177c">start-of-day</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">*</span> <span style="color:#666">21</span> <span style="color:#666">24</span> <span style="color:#666">60</span> <span style="color:#666">60</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">_</span> (<span style="color:#d2413a;font-weight:bold">error</span> <span style="color:#ba2121">&#34;Unsupported kind: %s&#34;</span> <span style="color:#19177c">kind</span>)))
</span></span><span style="display:flex;"><span> <span style="color:#008000">:location</span> <span style="color:#19177c">&#39;section</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">if</span> <span style="color:#19177c">query-res</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-journal-tag-reference-date</span> (<span style="color:#00f">car</span> <span style="color:#19177c">query-res</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">pcase</span> <span style="color:#19177c">kind</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">&#39;weekly</span> (<span style="color:#00f">-</span> <span style="color:#19177c">start-of-day</span> (<span style="color:#00f">*</span> <span style="color:#666">7</span> <span style="color:#666">24</span> <span style="color:#666">60</span> <span style="color:#666">60</span>)))))))
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/org-review-set-weekly-record</span> ()
</span></span><span style="display:flex;"><span> (<span style="color:#008000">save-excursion</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">let</span> ((<span style="color:#19177c">last-review-date</span> (<span style="color:#19177c">my/org-review-get-last-review-date</span> <span style="color:#19177c">&#39;weekly</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-journal-tags-prop-apply-delta</span> <span style="color:#008000">:add</span> <span style="color:#666">&#39;</span>(<span style="color:#ba2121">&#34;review.weekly&#34;</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">insert</span> <span style="color:#ba2121">&#34;Weekly Review&#34;</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">goto-char</span> (<span style="color:#00f">point-max</span>))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/get-last-review-date</span> ()
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">-&gt;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">substring</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">or</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">-max-by</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">&#39;string-greaterp</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">-filter</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">f</span>) (<span style="color:#19177c">not</span> (<span style="color:#008000">or</span> (<span style="color:#00f">string-equal</span> <span style="color:#19177c">f</span> <span style="color:#ba2121">&#34;.&#34;</span>) (<span style="color:#00f">string-equal</span> <span style="color:#19177c">f</span> <span style="color:#ba2121">&#34;..&#34;</span>))))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">directory-files</span> (<span style="color:#19177c">f-join</span> <span style="color:#19177c">org-roam-directory</span> <span style="color:#19177c">my/org-review-directory</span>))))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">format-time-string</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;%Y-%m-%d&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">time-subtract</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">current-time</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">seconds-to-time</span> (<span style="color:#00f">*</span> <span style="color:#666">60</span> <span style="color:#666">60</span> <span style="color:#666">24</span> <span style="color:#666">14</span>)))))
</span></span><span style="display:flex;"><span> <span style="color:#666">0</span> <span style="color:#666">10</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">concat</span> <span style="color:#ba2121">&#34;T00:00:00-00:00&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#19177c">parse-time-string</span>
</span></span><span style="display:flex;"><span> <span style="color:#00f">encode-time</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">time-add</span> (<span style="color:#19177c">seconds-to-time</span> (<span style="color:#00f">*</span> <span style="color:#666">60</span> <span style="color:#666">60</span> <span style="color:#666">24</span>)))
</span></span><span style="display:flex;"><span> ((<span style="color:#008000">lambda</span> (<span style="color:#19177c">time</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">format-time-string</span> <span style="color:#ba2121">&#34;%Y-%m-%d&#34;</span> <span style="color:#19177c">time</span>)))))
</span></span></code></pre></div><p>A template looks like this:</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">setq</span> <span style="color:#19177c">my/org-review-capture-template</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">`</span>(<span style="color:#ba2121">&#34;r&#34;</span> <span style="color:#ba2121">&#34;Review&#34;</span> <span style="color:#19177c">plain</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">,</span>(<span style="color:#19177c">string-join</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">&#39;</span>(<span style="color:#ba2121">&#34;#+title: %&lt;%Y-%m-%d&gt;: REVIEW&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;#+category: REVIEW&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;#+filetags: log review&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;#+STARTUP: overview&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;Last review date: %(org-timestamp-translate (org-timestamp-from-string (format \&#34;&lt;%s&gt;\&#34; (my/get-last-review-date))))&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;* Roam&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;%(my/org-review-format-roam (my/org-changed-files-since-date (my/get-last-review-date)))&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;* Agenda&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;%(my/org-review-format-queries (my/get-last-review-date))&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;* Thoughts&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;%?&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;\n&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#008000">:if-new</span> (<span style="color:#19177c">file</span> <span style="color:#ba2121">&#34;review/%&lt;%Y-%m-%d&gt;.org.gpg&#34;</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">insert</span> <span style="color:#ba2121">&#34;Last review date: &#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">format-time-string</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;[%Y-%m-%d]&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">seconds-to-time</span> <span style="color:#19177c">last-review-date</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">insert</span> <span style="color:#ba2121">&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121">
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121">Review checklist:
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121">- [ ] Clear email inbox
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121">- [ ] Reconcile ledger
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121">- [ ] Clear [[file:~/Downloads][downloads]] and [[file:~/00-Scratch][scratch]] folders
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121">- [ ] Process [[file:../inbox.org][inbox]]
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121">- [ ] Create [[file:../recurring.org][recurring tasks]] for next week
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121">- [ ] Check agenda (-1 / +2 weeks): priorities, deadlines
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121">- [ ] Check TODOs: priorities, deadlines
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121"> - [[org-ql-search:todo%3A?buffers-files=%22org-agenda-files%22&amp;super-groups=%28%28%3Aauto-outline-path-file%20t%29%29&amp;sort=%28priority%20todo%20deadline%29][org-ql-search: All TODOs]]
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121"> - [[org-ql-search:(and (todo) (not (tags \&#34;nots\&#34;)) (not (ts :from -14)))?buffers-files=%22org-agenda-files%22&amp;super-groups=%28%28%3Aauto-outline-path-file%20t%29%29&amp;sort=%28priority%20todo%20deadline%29][org-ql-search: Stale tasks]]
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121"> - [[org-ql-search:todo%3AWAIT?buffers-files=%22org-agenda-files%22&amp;super-groups=%28%28%3Aauto-outline-path-file%20t%29%29&amp;sort=%28priority%20todo%20deadline%29][org-ql-search: WAIT]]
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121">- [ ] Run auto-archiving
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121">- [ ] Review journal records
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/org-roam-capture-review</span> ()
</span></span><span style="display:flex;"><span> (<span style="color:#00f">insert</span> (<span style="color:#19177c">my/org-review-format-org-roam</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">format-seconds</span> <span style="color:#ba2121">&#34;%Y-%m-%d&#34;</span> <span style="color:#19177c">last-review-date</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">insert</span> <span style="color:#ba2121">&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121">*** Summary
</span></span></span><span style="display:flex;"><span><span style="color:#ba2121">TODO Write something, maybe? &#34;</span>))))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/org-review-weekly</span> ()
</span></span><span style="display:flex;"><span> (<span style="color:#008000">interactive</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-roam-capture-</span> <span style="color:#008000">:node</span> (<span style="color:#19177c">org-roam-node-create</span>)
</span></span><span style="display:flex;"><span> <span style="color:#008000">:templates</span> <span style="color:#666">`</span>(<span style="color:#666">,</span><span style="color:#19177c">my/org-review-capture-template</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">let</span> ((<span style="color:#19177c">org-journal-after-entry-create-hook</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">`</span>(<span style="color:#666">,@</span><span style="color:#19177c">org-journal-after-entry-create-hook</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">my/org-review-set-weekly-record</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-journal-new-entry</span> <span style="color:#800">nil</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">org-fold-show-subtree</span>)))
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">with-eval-after-load</span> <span style="color:#19177c">&#39;org-journal</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">my-leader-def</span> <span style="color:#ba2121">&#34;ojw&#34;</span> <span style="color:#00f">#&#39;</span><span style="color:#19177c">my/org-review-weekly</span>))
</span></span></code></pre></div><h4 id="contacts">Contacts</h4>
<p><code>org-contacts</code> is a package to store contacts in an org file.</p>
<p>It seems the package has been somewhat revived in the recent months. It used things like <code>lexical-let</code> when I first found it.</p>
@ -8859,6 +8795,12 @@ Didn&rsquo;t work out as I expected, so I&rsquo;ve made <code>org-journal-tags</
</span></span><span style="display:flex;"><span> <span style="color:#008000">:class</span> <span style="color:#19177c">transient-row</span>
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;q&#34;</span> <span style="color:#ba2121">&#34;Quit&#34;</span> <span style="color:#19177c">transient-quit-one</span>)]))
</span></span></code></pre></div><h4 id="wallabag">wallabag</h4>
<p><a href="https://github.com/wallabag/wallabag">wallabag</a> is a self-hosted &ldquo;read it later&rdquo; app.</p>
<p>This might be the best online reading advice I&rsquo;ve heard:</p>
<blockquote>
<p>I have a different approach: waiting periods. Every time I come across something I may want to read/watch, Im totally allowed to. No limits! The only requirement is I have to save it to Pocket, and then choose to consume it at a later time.</p>
</blockquote>
<p>Source: <a href="https://fortelabs.com/blog/the-secret-power-of-read-it-later-apps/">Tiago Forte - The Secret Power of Read It Later Apps</a></p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">use-package</span> <span style="color:#19177c">wallabag</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:straight</span> (<span style="color:#008000">:host</span> <span style="color:#19177c">github</span> <span style="color:#008000">:repo</span> <span style="color:#ba2121">&#34;chenyanming/wallabag.el&#34;</span> <span style="color:#008000">:files</span> (<span style="color:#008000">:defaults</span> <span style="color:#ba2121">&#34;default.css&#34;</span> <span style="color:#ba2121">&#34;emojis.alist&#34;</span>))
</span></span><span style="display:flex;"><span> <span style="color:#008000">:init</span>
@ -9346,12 +9288,19 @@ Didn&rsquo;t work out as I expected, so I&rsquo;ve made <code>org-journal-tags</
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;i&#34;</span> <span style="color:#00f">#&#39;</span><span style="color:#19177c">gptel</span>)
</span></span><span style="display:flex;"><span> <span style="color:#008000">:commands</span> (<span style="color:#19177c">gptel</span> <span style="color:#19177c">gptel-send</span> <span style="color:#19177c">gptel-menu</span>)
</span></span><span style="display:flex;"><span> <span style="color:#008000">:config</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">setq</span> <span style="color:#19177c">gptel-model</span> <span style="color:#ba2121">&#34;llama3:latest&#34;</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">setq</span> <span style="color:#19177c">gptel-backend</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">gptel-make-ollama</span> <span style="color:#ba2121">&#34;Ollama&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:host</span> <span style="color:#ba2121">&#34;localhost:11434&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:stream</span> <span style="color:#800">t</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:models</span> <span style="color:#666">&#39;</span>(<span style="color:#ba2121">&#34;llama3:latest&#34;</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">defun</span> <span style="color:#19177c">my/gptel-switch-backend</span> (<span style="color:#19177c">model</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">interactive</span> (<span style="color:#00f">list</span> (<span style="color:#00f">completing-read</span> <span style="color:#ba2121">&#34;Model: &#34;</span> <span style="color:#19177c">my/gptel-backends</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">setq</span> <span style="color:#19177c">gptel-model</span> <span style="color:#19177c">model</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">setq</span> <span style="color:#19177c">gptel-backend</span> (<span style="color:#19177c">alist-get</span> <span style="color:#19177c">model</span> <span style="color:#19177c">my/gptel-backends</span> <span style="color:#800">nil</span> <span style="color:#800">nil</span> <span style="color:#00f">#&#39;equal</span>)))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">setq</span> <span style="color:#19177c">my/gptel-backends</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">`</span>((<span style="color:#ba2121">&#34;llama3:latest&#34;</span> <span style="color:#666">.</span> <span style="color:#666">,</span>(<span style="color:#19177c">gptel-make-ollama</span> <span style="color:#ba2121">&#34;Ollama&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:host</span> <span style="color:#ba2121">&#34;localhost:11434&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:stream</span> <span style="color:#800">t</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:models</span> <span style="color:#666">&#39;</span>(<span style="color:#ba2121">&#34;llama3:latest&#34;</span> <span style="color:#ba2121">&#34;llama3-gradient&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;llama3:instruct&#34;</span>)))))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">my/gptel-switch-backend</span> <span style="color:#ba2121">&#34;llama3:latest&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">general-define-key</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:keymaps</span> <span style="color:#666">&#39;</span>(<span style="color:#19177c">gptel-mode-map</span>)
</span></span><span style="display:flex;"><span> <span style="color:#008000">:states</span> <span style="color:#666">&#39;</span>(<span style="color:#00f">insert</span> <span style="color:#19177c">normal</span>)
@ -9364,21 +9313,176 @@ Didn&rsquo;t work out as I expected, so I&rsquo;ve made <code>org-journal-tags</
</span></span><span style="display:flex;"><span> (<span style="color:#008000">setq</span> <span style="color:#19177c">ellama-language</span> <span style="color:#ba2121">&#34;English&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#008000">:config</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">require</span> <span style="color:#19177c">&#39;llm-ollama</span>)
</span></span><span style="display:flex;"><span> <span style="color:#408080;font-style:italic">;; I&#39;ve looked for this option for 1.5 hours</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">setq</span> <span style="color:#19177c">ellama-long-lines-length</span> <span style="color:#666">100000</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">my-leader-def</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;aie&#34;</span> <span style="color:#666">&#39;</span>(<span style="color:#008000">:wk</span> <span style="color:#ba2121">&#34;ellama&#34;</span> <span style="color:#008000">:keymap</span> <span style="color:#19177c">ellama-command-map</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">which-key-add-key-based-replacements</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">rx</span> <span style="color:#ba2121">&#34;SPC a i e a&#34;</span>) <span style="color:#ba2121">&#34;ask&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">rx</span> <span style="color:#ba2121">&#34;SPC a i e c&#34;</span>) <span style="color:#ba2121">&#34;code&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">rx</span> <span style="color:#ba2121">&#34;SPC a i e d&#34;</span>) <span style="color:#ba2121">&#34;define&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">rx</span> <span style="color:#ba2121">&#34;SPC a i e i&#34;</span>) <span style="color:#ba2121">&#34;improve&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">rx</span> <span style="color:#ba2121">&#34;SPC a i e m&#34;</span>) <span style="color:#ba2121">&#34;make&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">rx</span> <span style="color:#ba2121">&#34;SPC a i e p&#34;</span>) <span style="color:#ba2121">&#34;provider&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">rx</span> <span style="color:#ba2121">&#34;SPC a i e s&#34;</span>) <span style="color:#ba2121">&#34;summarize&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">rx</span> <span style="color:#ba2121">&#34;SPC a i e t&#34;</span>) <span style="color:#ba2121">&#34;translate/complete&#34;</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">rx</span> <span style="color:#ba2121">&#34;SPC a i e x&#34;</span>) <span style="color:#ba2121">&#34;context&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">setq</span> <span style="color:#19177c">ellama-provider</span> (<span style="color:#19177c">make-llm-ollama</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:chat-model</span> <span style="color:#ba2121">&#34;llama3:latest&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:embedding-model</span> <span style="color:#ba2121">&#34;llama3:latest&#34;</span>)))
</span></span><span style="display:flex;"><span> <span style="color:#008000">:chat-model</span> <span style="color:#ba2121">&#34;llama3:instruct&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:embedding-model</span> <span style="color:#ba2121">&#34;llama3:instruct&#34;</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">setq</span> <span style="color:#19177c">ellama-providers</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">`</span>((<span style="color:#ba2121">&#34;llama3:8b&#34;</span> <span style="color:#666">.</span> <span style="color:#666">,</span>(<span style="color:#19177c">make-llm-ollama</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:chat-model</span> <span style="color:#ba2121">&#34;llama3:latest&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:embedding-model</span> <span style="color:#ba2121">&#34;llama3:latest&#34;</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;llama3:instruct&#34;</span> <span style="color:#666">.</span> <span style="color:#666">,</span>(<span style="color:#19177c">make-llm-ollama</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:chat-model</span> <span style="color:#ba2121">&#34;llama3:instruct&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:embedding-model</span> <span style="color:#ba2121">&#34;llama3:instruct&#34;</span>)))))
</span></span></code></pre></div><p>The keybindings are a bit crazy to use even with <code>which-key</code>, so here goes transient.el.</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">with-eval-after-load</span> <span style="color:#19177c">&#39;ellama</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">transient-define-prefix</span> <span style="color:#19177c">my/ellama</span> ()
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;Ellama actions.&#34;</span>
</span></span><span style="display:flex;"><span> [<span style="color:#ba2121">&#34;General&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:class</span> <span style="color:#19177c">transient-row</span>
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;a&#34;</span> <span style="color:#ba2121">&#34;Chat&#34;</span> <span style="color:#19177c">ellama-chat</span>)]
</span></span><span style="display:flex;"><span> [<span style="color:#ba2121">&#34;Code&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:class</span> <span style="color:#19177c">transient-row</span>
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;ca&#34;</span> <span style="color:#ba2121">&#34;Add&#34;</span> <span style="color:#19177c">ellama-code-add</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;cc&#34;</span> <span style="color:#ba2121">&#34;Complete&#34;</span> <span style="color:#19177c">ellama-code-complete</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;ce&#34;</span> <span style="color:#ba2121">&#34;Edit&#34;</span> <span style="color:#19177c">ellama-code-edit</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;cr&#34;</span> <span style="color:#ba2121">&#34;Review&#34;</span> <span style="color:#19177c">ellama-code-review</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;ci&#34;</span> <span style="color:#ba2121">&#34;Improve&#34;</span> <span style="color:#19177c">ellama-code-improve</span>)]
</span></span><span style="display:flex;"><span> [<span style="color:#ba2121">&#34;Natural Language&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:class</span> <span style="color:#19177c">transient-row</span>
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;np&#34;</span> <span style="color:#ba2121">&#34;Proof-read&#34;</span> <span style="color:#19177c">my/ellama-proof-read</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;nw&#34;</span> <span style="color:#ba2121">&#34;Improve wording&#34;</span> <span style="color:#19177c">my/ellama-improve-wording</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;nc&#34;</span> <span style="color:#ba2121">&#34;Improve conciseness&#34;</span> <span style="color:#19177c">my/ellama-improve-concise</span>)]
</span></span><span style="display:flex;"><span> [<span style="color:#ba2121">&#34;Formatting&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:class</span> <span style="color:#19177c">transient-row</span>
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;ff&#34;</span> <span style="color:#ba2121">&#34;Format&#34;</span> <span style="color:#19177c">ellama-make-format</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;fm&#34;</span> <span style="color:#ba2121">&#34;List&#34;</span> <span style="color:#19177c">ellama-make-list</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;ft&#34;</span> <span style="color:#ba2121">&#34;Table&#34;</span> <span style="color:#19177c">ellama-make-table</span>)]
</span></span><span style="display:flex;"><span> [<span style="color:#ba2121">&#34;Explain &amp; Summarize&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:class</span> <span style="color:#19177c">transient-row</span>
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;es&#34;</span> <span style="color:#ba2121">&#34;Summarize&#34;</span> <span style="color:#19177c">ellama-summarize</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;ea&#34;</span> <span style="color:#ba2121">&#34;Ask about&#34;</span> <span style="color:#19177c">ellama-ask-about</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;es&#34;</span> <span style="color:#ba2121">&#34;Send to chat&#34;</span> <span style="color:#19177c">ellama-ask-selection</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;ew&#34;</span> <span style="color:#ba2121">&#34;Word definition&#34;</span> <span style="color:#19177c">ellama-define-word</span>)]
</span></span><span style="display:flex;"><span> [<span style="color:#ba2121">&#34;Context&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:class</span> <span style="color:#19177c">transient-row</span>
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;xb&#34;</span> <span style="color:#ba2121">&#34;Add buffer&#34;</span> <span style="color:#19177c">ellama-context-add-buffer</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;xf&#34;</span> <span style="color:#ba2121">&#34;Add file&#34;</span> <span style="color:#19177c">ellama-context-add-file</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;xi&#34;</span> <span style="color:#ba2121">&#34;Add info&#34;</span> <span style="color:#19177c">ellama-context-add-info-node</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;xs&#34;</span> <span style="color:#ba2121">&#34;Add selection&#34;</span> <span style="color:#19177c">ellama-context-add-selection</span>)]
</span></span><span style="display:flex;"><span> [<span style="color:#ba2121">&#34;Settings &amp; Sessions&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:class</span> <span style="color:#19177c">transient-row</span>
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;sp&#34;</span> <span style="color:#ba2121">&#34;Provider&#34;</span> <span style="color:#19177c">ellama-provider-select</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;ss&#34;</span> <span style="color:#ba2121">&#34;Session&#34;</span> <span style="color:#19177c">ellama-session-switch</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;sr&#34;</span> <span style="color:#ba2121">&#34;Rename ression&#34;</span> <span style="color:#19177c">ellama-session-rename</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;sd&#34;</span> <span style="color:#ba2121">&#34;Delete session&#34;</span> <span style="color:#19177c">ellama-session-remove</span>)])
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">my-leader-def</span> <span style="color:#ba2121">&#34;aie&#34;</span> <span style="color:#00f">#&#39;</span><span style="color:#19177c">my/ellama</span>))
</span></span></code></pre></div><h5 id="change-natural-text-and-diff-against-the-results">Change natural text &amp; diff against the results</h5>
<p>One pattern I often want is to change the given text and compare it to the old version.</p>
<p>LLMs aren&rsquo;t perfectly good at saying what changes they have done, so the pattern here is to query the model and show the changed text together with the diff.</p>
<p>So first, I need to diff two strings.</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/diff-strings</span> (<span style="color:#19177c">str1</span> <span style="color:#19177c">str2</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">let</span> ((<span style="color:#19177c">file1</span> (<span style="color:#19177c">make-temp-file</span> <span style="color:#ba2121">&#34;diff1&#34;</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">file2</span> (<span style="color:#19177c">make-temp-file</span> <span style="color:#ba2121">&#34;diff2&#34;</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">unwind-protect</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">progn</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">with-temp-file</span> <span style="color:#19177c">file1</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">insert</span> <span style="color:#19177c">str1</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">with-temp-file</span> <span style="color:#19177c">file2</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">insert</span> <span style="color:#19177c">str2</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">with-temp-buffer</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">diff-mode</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">diff-no-select</span> <span style="color:#19177c">file1</span> <span style="color:#19177c">file2</span> (<span style="color:#19177c">diff-switches</span>) <span style="color:#800">t</span> (<span style="color:#00f">current-buffer</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">font-lock-fontify-buffer</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">buffer-string</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">delete-file</span> <span style="color:#19177c">file1</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">delete-file</span> <span style="color:#19177c">file2</span>))))
</span></span></code></pre></div><p>And the function to do the prompting iself. Llama tends to output in Markdown, so I use a function from Ellama to convert the output back to Org-mode, if necessary.</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/ellama-text-with-diff</span> (<span style="color:#19177c">text</span> <span style="color:#19177c">is-org-mode</span> <span style="color:#19177c">prompt</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">llm-chat-async</span>
</span></span><span style="display:flex;"><span> <span style="color:#19177c">ellama-provider</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">llm-make-chat-prompt</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">format</span> <span style="color:#19177c">prompt</span> <span style="color:#19177c">text</span>))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">changed-text</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">when</span> <span style="color:#19177c">is-org-mode</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">setq</span> <span style="color:#19177c">changed-text</span> (<span style="color:#19177c">ellama--translate-markdown-to-org-filter</span> <span style="color:#19177c">changed-text</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">let</span> ((<span style="color:#19177c">buffer</span> (<span style="color:#19177c">generate-new-buffer</span> <span style="color:#ba2121">&#34;*ellama-diff*&#34;</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">with-current-buffer</span> <span style="color:#19177c">buffer</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">text-mode</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">insert</span> <span style="color:#19177c">changed-text</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">insert</span> <span style="color:#ba2121">&#34;\n\n&#34;</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">insert</span> (<span style="color:#19177c">my/diff-strings</span> <span style="color:#19177c">text</span> <span style="color:#19177c">changed-text</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">display-buffer</span> <span style="color:#19177c">buffer</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">lambda</span> (<span style="color:#008000">&amp;rest</span> <span style="color:#19177c">err</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">message</span> <span style="color:#ba2121">&#34;Error: %s&#34;</span> <span style="color:#19177c">err</span>))))
</span></span></code></pre></div><p>As for prompts, I like the following prompt to proof-read text. It&rsquo;s pretty conservative, but good for fixing typos, missing commas, articles, etc.</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">setq</span> <span style="color:#19177c">my/ellama-proof-read-prompt</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;Proof-read the following text. Fix any errors but keep the original style. Print the changed text and nothing else, not even \&#34;Here&#39;s the proof-read text\&#34;.\n\n %s&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/ellama--text</span> ()
</span></span><span style="display:flex;"><span> (<span style="color:#008000">if</span> (<span style="color:#19177c">region-active-p</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">buffer-substring-no-properties</span> (<span style="color:#00f">region-beginning</span>) (<span style="color:#00f">region-end</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#00f">buffer-substring-no-properties</span> (<span style="color:#00f">point-min</span>) (<span style="color:#00f">point-max</span>))))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/ellama-proof-read</span> (<span style="color:#19177c">text</span> <span style="color:#19177c">is-org-mode</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">interactive</span> (<span style="color:#00f">list</span> (<span style="color:#19177c">my/ellama--text</span>) (<span style="color:#19177c">derived-mode-p</span> <span style="color:#19177c">&#39;org-mode</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">my/ellama-text-with-diff</span> <span style="color:#19177c">text</span> <span style="color:#19177c">is-org-mode</span> <span style="color:#19177c">my/ellama-proof-read-prompt</span>))
</span></span></code></pre></div><p>The following is more expansive, but preserves less of the original text. For instance, it tends to replace my <em>id est</em> and <em>exempli gratia</em>. But sometimes it has good ideas.</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">setq</span> <span style="color:#19177c">my/ellama-improve-wording-prompt</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;Proof-read the following text. Fix any errors and improve wording. Print the changed text and nothing else, not even \&#34;Here&#39;s the improved text\&#34;.\n\n %s&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/ellama-improve-wording</span> (<span style="color:#19177c">text</span> <span style="color:#19177c">is-org-mode</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">interactive</span> (<span style="color:#00f">list</span> (<span style="color:#19177c">my/ellama--text</span>) (<span style="color:#19177c">derived-mode-p</span> <span style="color:#19177c">&#39;org-mode</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">my/ellama-text-with-diff</span> <span style="color:#19177c">text</span> <span style="color:#19177c">is-org-mode</span> <span style="color:#19177c">my/ellama-improve-wording-prompt</span>))
</span></span></code></pre></div><p>Also, a prompt to make a text more concise.</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">setq</span> <span style="color:#19177c">my/ellama-improve-concise-prompt</span>
</span></span><span style="display:flex;"><span> <span style="color:#ba2121">&#34;Make the following text more concise. Print the changed text and nothing else, not even \&#34;Here&#39;s the improved text\&#34;.\n\n %s&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>(<span style="color:#008000">defun</span> <span style="color:#19177c">my/ellama-improve-concise</span> (<span style="color:#19177c">text</span> <span style="color:#19177c">is-org-mode</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">interactive</span> (<span style="color:#00f">list</span> (<span style="color:#19177c">my/ellama--text</span>) (<span style="color:#19177c">derived-mode-p</span> <span style="color:#19177c">&#39;org-mode</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">my/ellama-text-with-diff</span> <span style="color:#19177c">text</span> <span style="color:#19177c">is-org-mode</span> <span style="color:#19177c">my/ellama-improve-concise-prompt</span>))
</span></span></code></pre></div><h5 id="other-thoughts">Other thoughts</h5>
<ul>
<li><code>ellama-code-complete</code> is pretty good to write migrations</li>
</ul>
<h4 id="model-settings">Model settings</h4>
<h5 id="llama3-gradient">llama3-gradient</h5>
<p><a href="https://ollama.com/library/llama3-gradient">llama3-gradient</a> is a version of LLaMA 3 with an extended context size. It requires setting the <code>num_ctx</code> parameter to work correctly.</p>
<p>For ellama, the following works:</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">with-eval-after-load</span> <span style="color:#19177c">&#39;ellama</span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">cl-defstruct</span> (<span style="color:#19177c">llm-ollama-gradient</span> (<span style="color:#008000">:include</span> <span style="color:#19177c">llm-ollama</span>)) <span style="color:#19177c">num-ctx</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">cl-defmethod</span> <span style="color:#19177c">llm-provider-chat-request</span> ((<span style="color:#19177c">provider</span> <span style="color:#19177c">llm-ollama-gradient</span>) <span style="color:#19177c">prompt</span> <span style="color:#19177c">_</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">let</span> (<span style="color:#19177c">request-alist</span> <span style="color:#19177c">messages</span> <span style="color:#19177c">options</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">setq</span> <span style="color:#19177c">messages</span>
</span></span><span style="display:flex;"><span> (<span style="color:#00f">mapcar</span> (<span style="color:#008000">lambda</span> (<span style="color:#19177c">interaction</span>)
</span></span><span style="display:flex;"><span> <span style="color:#666">`</span>((<span style="color:#ba2121">&#34;role&#34;</span> <span style="color:#666">.</span> <span style="color:#666">,</span>(<span style="color:#00f">symbol-name</span> (<span style="color:#19177c">llm-chat-prompt-interaction-role</span> <span style="color:#19177c">interaction</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;content&#34;</span> <span style="color:#666">.</span> <span style="color:#666">,</span>(<span style="color:#19177c">llm-chat-prompt-interaction-content</span> <span style="color:#19177c">interaction</span>))))
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">llm-chat-prompt-interactions</span> <span style="color:#19177c">prompt</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">when</span> (<span style="color:#19177c">llm-chat-prompt-context</span> <span style="color:#19177c">prompt</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">push</span> <span style="color:#666">`</span>((<span style="color:#ba2121">&#34;role&#34;</span> <span style="color:#666">.</span> <span style="color:#ba2121">&#34;system&#34;</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#ba2121">&#34;content&#34;</span> <span style="color:#666">.</span> <span style="color:#666">,</span>(<span style="color:#19177c">llm-provider-utils-get-system-prompt</span> <span style="color:#19177c">prompt</span> <span style="color:#19177c">llm-ollama-example-prelude</span>)))
</span></span><span style="display:flex;"><span> <span style="color:#19177c">messages</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">push</span> <span style="color:#666">`</span>(<span style="color:#ba2121">&#34;messages&#34;</span> <span style="color:#666">.</span> <span style="color:#666">,</span><span style="color:#19177c">messages</span>) <span style="color:#19177c">request-alist</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">push</span> <span style="color:#666">`</span>(<span style="color:#ba2121">&#34;model&#34;</span> <span style="color:#666">.</span> <span style="color:#666">,</span>(<span style="color:#19177c">llm-ollama-chat-model</span> <span style="color:#19177c">provider</span>)) <span style="color:#19177c">request-alist</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">when</span> (<span style="color:#19177c">llm-chat-prompt-temperature</span> <span style="color:#19177c">prompt</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">push</span> <span style="color:#666">`</span>(<span style="color:#ba2121">&#34;temperature&#34;</span> <span style="color:#666">.</span> <span style="color:#666">,</span>(<span style="color:#19177c">llm-chat-prompt-temperature</span> <span style="color:#19177c">prompt</span>)) <span style="color:#19177c">options</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">when</span> (<span style="color:#19177c">llm-chat-prompt-max-tokens</span> <span style="color:#19177c">prompt</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">push</span> <span style="color:#666">`</span>(<span style="color:#ba2121">&#34;num_predict&#34;</span> <span style="color:#666">.</span> <span style="color:#666">,</span>(<span style="color:#19177c">llm-chat-prompt-max-tokens</span> <span style="color:#19177c">prompt</span>)) <span style="color:#19177c">options</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">when</span> (<span style="color:#19177c">llm-ollama-gradient-num-ctx</span> <span style="color:#19177c">provider</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">push</span> <span style="color:#666">`</span>(<span style="color:#ba2121">&#34;num_ctx&#34;</span> <span style="color:#666">.</span> <span style="color:#666">,</span>(<span style="color:#19177c">llm-ollama-gradient-num-ctx</span> <span style="color:#19177c">provider</span>)) <span style="color:#19177c">options</span>))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">when</span> <span style="color:#19177c">options</span> (<span style="color:#008000">push</span> <span style="color:#666">`</span>(<span style="color:#ba2121">&#34;options&#34;</span> <span style="color:#666">.</span> <span style="color:#666">,</span><span style="color:#19177c">options</span>) <span style="color:#19177c">request-alist</span>))
</span></span><span style="display:flex;"><span> <span style="color:#19177c">request-alist</span>))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> (<span style="color:#008000">push</span> <span style="color:#666">`</span>(<span style="color:#ba2121">&#34;llama3-gradient&#34;</span> <span style="color:#666">.</span> <span style="color:#666">,</span>(<span style="color:#19177c">make-llm-ollama-gradient</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:chat-model</span> <span style="color:#ba2121">&#34;llama3-gradient&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:embedding-model</span> <span style="color:#ba2121">&#34;llama3-gradient&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:num-ctx</span> <span style="color:#666">48000</span>))
</span></span><span style="display:flex;"><span> <span style="color:#19177c">ellama-providers</span>))
</span></span></code></pre></div><p>For gptel, this approach doesn&rsquo;t work and I&rsquo;ve got no clue why. So&hellip;</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">with-eval-after-load</span> <span style="color:#19177c">&#39;gptel</span>
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">cl-defmethod</span> <span style="color:#19177c">gptel--request-data</span> <span style="color:#008000">:around</span> ((<span style="color:#19177c">_backend</span> <span style="color:#19177c">gptel-ollama</span>) <span style="color:#19177c">prompts</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#008000">let</span> ((<span style="color:#19177c">request-alist</span> (<span style="color:#19177c">cl-call-next-method</span>)))
</span></span><span style="display:flex;"><span> (<span style="color:#008000">when</span> (<span style="color:#00f">equal</span> <span style="color:#19177c">gptel-model</span> <span style="color:#ba2121">&#34;llama3-gradient&#34;</span>)
</span></span><span style="display:flex;"><span> (<span style="color:#00f">plist-put</span> <span style="color:#19177c">request-alist</span> <span style="color:#008000">:options</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">`</span>(<span style="color:#008000">:num_ctx</span> <span style="color:#666">48000</span>
</span></span><span style="display:flex;"><span> <span style="color:#666">,@</span>(<span style="color:#00f">plist-get</span> <span style="color:#19177c">request-alist</span> <span style="color:#008000">:options</span>))))
</span></span><span style="display:flex;"><span> <span style="color:#19177c">request-alist</span>)))
</span></span></code></pre></div><h3 id="declarative-filesystem-management">Declarative filesystem management</h3>
<p>My filesystem is, shall we say, not the most orderly place.</p>
<center>
@ -10199,7 +10303,7 @@ Didn&rsquo;t work out as I expected, so I&rsquo;ve made <code>org-journal-tags</
</span></span><span style="display:flex;"><span> (<span style="color:#19177c">json-pretty-print-buffer</span>))))
</span></span></code></pre></div><h3 id="utilities">Utilities</h3>
<h4 id="pass">pass</h4>
<p>I use <a href="https://www.passwordstore.org/">pass</a> as my password manager. Expectedly, there is Emacs frontend for it.</p>
<p>I use <a href="https://www.passwordstore.org/">pass</a> as my password manager. Expectedly, there is an Emacs frontend for it.</p>
<p>This package is pretty good to manage the password database. I use <a href="https://github.com/SqrtMinusOne/password-store-ivy">password-store-ivy</a> (another package of mine) to actually type passwords. <a href="https://github.com/carnager/rofi-pass">rofi-pass</a> is another good option.</p>
<div class="highlight"><pre tabindex="0" style=";-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span style="display:flex;"><span>(<span style="color:#008000">use-package</span> <span style="color:#19177c">pass</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000">:straight</span> <span style="color:#800">t</span>
@ -11202,6 +11306,7 @@ I&rsquo;ve seen a couple of cases where people would swap their username and ema
<ul>
<li><a href="#gptel">gptel</a></li>
<li><a href="#ellama">ellama</a></li>
<li><a href="#model-settings">Model settings</a></li>
</ul>
</li>
<li><a href="#declarative-filesystem-management">Declarative filesystem management</a>

View file

@ -1,6 +1,6 @@
<!DOCTYPE html>
<html lang=""><head>
<meta name="generator" content="Hugo 0.125.4">
<meta name="generator" content="Hugo 0.125.7">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 66 KiB