diff options
author | Akshay <[email protected]> | 2023-06-18 20:54:08 +0100 |
---|---|---|
committer | Akshay <[email protected]> | 2023-06-18 20:54:08 +0100 |
commit | af9a5edd1fd65b504cad8eee4c2097b8db7de1e0 (patch) | |
tree | 2aff49751493a669e287c19de00dda07886472d4 | |
parent | b1efbd3181a9bbb444a59f8dbafd7aaaba246945 (diff) |
new post: plain text journaling
-rw-r--r-- | docs/index.html | 24 | ||||
-rw-r--r-- | docs/index.xml | 241 | ||||
-rw-r--r-- | docs/posts/index.html | 17 | ||||
-rw-r--r-- | docs/posts/plain_text_journaling/index.html | 308 | ||||
-rw-r--r-- | posts/plain_text_journaling.md | 347 |
5 files changed, 925 insertions, 12 deletions
diff --git a/docs/index.html b/docs/index.html index 7b2b6b6..10ed746 100644 --- a/docs/index.html +++ b/docs/index.html | |||
@@ -40,15 +40,15 @@ | |||
40 | <tr> | 40 | <tr> |
41 | <td class=table-post> | 41 | <td class=table-post> |
42 | <div class="date"> | 42 | <div class="date"> |
43 | 03/09 — 2022 | 43 | 19/06 — 2023 |
44 | </div> | 44 | </div> |
45 | <a href="/posts/curing_a_case_of_git-UX" class="post-link"> | 45 | <a href="/posts/plain_text_journaling" class="post-link"> |
46 | <span class="post-link">Curing A Case Of Git-UX</span> | 46 | <span class="post-link">Plain Text Journaling</span> |
47 | </a> | 47 | </a> |
48 | </td> | 48 | </td> |
49 | <td class=table-stats> | 49 | <td class=table-stats> |
50 | <span class="stats-number"> | 50 | <span class="stats-number"> |
51 | 9.6 | 51 | 8.9 |
52 | </span> | 52 | </span> |
53 | <span class=stats-unit>min</span> | 53 | <span class=stats-unit>min</span> |
54 | </td> | 54 | </td> |
@@ -57,15 +57,15 @@ | |||
57 | <tr> | 57 | <tr> |
58 | <td class=table-post> | 58 | <td class=table-post> |
59 | <div class="date"> | 59 | <div class="date"> |
60 | 28/08 — 2022 | 60 | 03/09 — 2022 |
61 | </div> | 61 | </div> |
62 | <a href="/posts/programming_on_34_keys" class="post-link"> | 62 | <a href="/posts/curing_a_case_of_git-UX" class="post-link"> |
63 | <span class="post-link">Programming On 34 Keys</span> | 63 | <span class="post-link">Curing A Case Of Git-UX</span> |
64 | </a> | 64 | </a> |
65 | </td> | 65 | </td> |
66 | <td class=table-stats> | 66 | <td class=table-stats> |
67 | <span class="stats-number"> | 67 | <span class="stats-number"> |
68 | 6.2 | 68 | 9.6 |
69 | </span> | 69 | </span> |
70 | <span class=stats-unit>min</span> | 70 | <span class=stats-unit>min</span> |
71 | </td> | 71 | </td> |
@@ -74,15 +74,15 @@ | |||
74 | <tr> | 74 | <tr> |
75 | <td class=table-post> | 75 | <td class=table-post> |
76 | <div class="date"> | 76 | <div class="date"> |
77 | 02/08 — 2022 | 77 | 28/08 — 2022 |
78 | </div> | 78 | </div> |
79 | <a href="/posts/a_reference_counted_afterlife" class="post-link"> | 79 | <a href="/posts/programming_on_34_keys" class="post-link"> |
80 | <span class="post-link">A Reference Counted Afterlife</span> | 80 | <span class="post-link">Programming On 34 Keys</span> |
81 | </a> | 81 | </a> |
82 | </td> | 82 | </td> |
83 | <td class=table-stats> | 83 | <td class=table-stats> |
84 | <span class="stats-number"> | 84 | <span class="stats-number"> |
85 | 1.6 | 85 | 6.2 |
86 | </span> | 86 | </span> |
87 | <span class=stats-unit>min</span> | 87 | <span class=stats-unit>min</span> |
88 | </td> | 88 | </td> |
diff --git a/docs/index.xml b/docs/index.xml index c0277f1..eb43379 100644 --- a/docs/index.xml +++ b/docs/index.xml | |||
@@ -12,6 +12,247 @@ | |||
12 | <language>en-us</language> | 12 | <language>en-us</language> |
13 | <copyright>Creative Commons BY-NC-SA 4.0</copyright> | 13 | <copyright>Creative Commons BY-NC-SA 4.0</copyright> |
14 | <item> | 14 | <item> |
15 | <title>Plain Text Journaling</title> | ||
16 | <description><p>I cobbled together a journaling system with {neo,}vim, coreutils and | ||
17 | <a href="http://www.fresse.org/dateutils">dateutils</a>. This system is | ||
18 | loosely based on <a href="https://www.rydercarroll.com/">Ryder | ||
19 | Caroll’s</a> Bullet Journal method.</p> | ||
20 | <p><a href="https://u.peppe.rs/SpF.png"><img | ||
21 | src="https://u.peppe.rs/SpF.png" /></a></p> | ||
22 | <h3 id="the-format">The format</h3> | ||
23 | <p>The journal for a given year is a directory:</p> | ||
24 | <div class="sourceCode" id="cb1"><pre | ||
25 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> ls journal/</span> | ||
26 | <span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ex">2022/</span> 2023/</span></code></pre></div> | ||
27 | <p>In each directory are 12 files, one for each month of the year, | ||
28 | numbered like so:</p> | ||
29 | <div class="sourceCode" id="cb2"><pre | ||
30 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> ls journal/2023/</span> | ||
31 | <span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="ex">01</span> 02 03 04 05 06 07 08 09 10 11 12</span></code></pre></div> | ||
32 | <p>We can now begin writing stuff down:</p> | ||
33 | <div class="sourceCode" id="cb3"><pre | ||
34 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> vim journal/2023/1</span></code></pre></div> | ||
35 | <p>Every month must start with a calendar of course, fill that in | ||
36 | with:</p> | ||
37 | <pre class="vim"><code>:read !cal -m</code></pre> | ||
38 | <p>Your entry for January might look like this:</p> | ||
39 | <div class="sourceCode" id="cb5"><pre | ||
40 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> cat journal/2023/01</span> | ||
41 | <span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a> <span class="ex">January</span> 2023</span> | ||
42 | <span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="ex">Mo</span> Tu We Th Fr Sa Su</span> | ||
43 | <span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a> <span class="ex">1</span></span> | ||
44 | <span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a> <span class="ex">2</span> 3 4 5 6 7 8</span> | ||
45 | <span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a> <span class="ex">9</span> 10 11 12 13 14 15</span> | ||
46 | <span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="ex">16</span> 17 18 19 20 21 22</span> | ||
47 | <span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a><span class="ex">23</span> 24 25 26 27 28 29</span> | ||
48 | <span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="ex">30</span> 31</span></code></pre></div> | ||
49 | <p>I prefer planning week by week, as opposed to creating a task-list | ||
50 | every day, here’s what I have for the first couple of weeks:</p> | ||
51 | <pre><code> January 2023 | ||
52 | Mo Tu We Th Fr Sa Su | ||
53 | 1 | ||
54 | 2 3 4 5 6 7 8 | ||
55 | 9 10 11 12 13 14 15 | ||
56 | 16 17 18 19 20 21 22 | ||
57 | 23 24 25 26 27 28 29 | ||
58 | 30 31 | ||
59 | |||
60 | |||
61 | week 1 | ||
62 | |||
63 | done apply leaves | ||
64 | done dload boarding pass | ||
65 | moved reply to dan | ||
66 | |||
67 | |||
68 | week 2 | ||
69 | |||
70 | todo reply to dan | ||
71 | todo pack bags | ||
72 | done travel insurance | ||
73 | todo weigh luggage</code></pre> | ||
74 | <p>I start the week by writing a header and each item that week is | ||
75 | placed on its own line. The items are prefixed with a <code>todo</code> | ||
76 | or a <code>done</code> signifier.</p> | ||
77 | <h3 id="form-over-function">Form over function</h3> | ||
78 | <p>Right off the bat, the signifiers look very noisy, Even more so once | ||
79 | we start introducing variety (I use “event”, “note” and “moved”):</p> | ||
80 | <pre><code>week 1 | ||
81 | |||
82 | todo apply leaves | ||
83 | done dload boarding pass | ||
84 | todo reply to dan | ||
85 | event fr trip | ||
86 | note weight 68.6</code></pre> | ||
87 | <p>We can clean this up with “abbreviations” | ||
88 | (<code>:h abbreviations</code>):</p> | ||
89 | <pre class="vim"><code>:iabbrev todo · | ||
90 | :iabbrev done ×</code></pre> | ||
91 | <p>Now, typing this:</p> | ||
92 | <pre><code>todo apply leaves</code></pre> | ||
93 | <p>Automatically inserts:</p> | ||
94 | <pre><code>· apply leaves</code></pre> | ||
95 | <p>You can use <code>x</code> and <code>o</code> as well, but | ||
96 | <code>×</code> (U+00D7, MULTIPLICATION SIGN) and <code>·</code> (U+00B7, | ||
97 | MIDDLE DOT) are more … <em>gourmet</em>.</p> | ||
98 | <p>The other signifiers I use are:</p> | ||
99 | <ul> | ||
100 | <li><code>-</code> for note</li> | ||
101 | <li><code>o</code> for event</li> | ||
102 | <li><code>&gt;</code> for moved.</li> | ||
103 | </ul> | ||
104 | <p>Nit #2 is the lack of order. We can employ vim to introduce grouping | ||
105 | and sorting. Select the list of entries for this week:</p> | ||
106 | <pre class="vim"><code>vip &quot; line-wise select inner paragraph | ||
107 | :&#39;&lt;,&#39;&gt;sort &quot; the markers &#39;&lt; and &#39;&gt; are automatically inserted, | ||
108 | &quot; they mark the start and end of the selection</code></pre> | ||
109 | <p>We end up with:</p> | ||
110 | <pre><code>week 1 | ||
111 | |||
112 | · apply leaves | ||
113 | · reply to dan | ||
114 | × dload boarding pass</code></pre> | ||
115 | <p>The lines are grouped by their signifiers, segregating todo items | ||
116 | from completed items. Luckily, MIDDLE DOT is lesser than MULTIPLICATION | ||
117 | SIGN, so todo items are placed at the top. The same goes for | ||
118 | <code>o</code> and <code>x</code> symbols, either set of signifiers will | ||
119 | result in the same sorting order.</p> | ||
120 | <p>We can shorten this select-paragraph-invoke-sort dance by setting the | ||
121 | <code>formatprg</code> variable:</p> | ||
122 | <pre class="vim"><code>:set formatprg=sort\ -V</code></pre> | ||
123 | <p>Now, hitting <code>gqip</code> should automatically group and sort | ||
124 | the items for the week under the cursor, moving todo items to the top. | ||
125 | Finding signifier glyphs that suit your sorting preference is a fun | ||
126 | exercise.</p> | ||
127 | <h3 id="syntax-highlighting">Syntax highlighting</h3> | ||
128 | <p>Adding color to items introduces another layer of visual distinction. | ||
129 | In truth, I like to deck it out just because.</p> | ||
130 | <p>First, create a few syntax groups:</p> | ||
131 | <pre class="vim"><code>:syntax match JournalAll /.*/ &quot; captures the entire buffer | ||
132 | :syntax match JournalDone /^×.*/ &quot; lines containing &#39;done&#39; items: × | ||
133 | :syntax match JournalTodo /^·.*/ &quot; lines containing &#39;todo&#39; items: · | ||
134 | :syntax match JournalEvent /^o.*/ &quot; lines containing &#39;event&#39; items: o | ||
135 | :syntax match JournalNote /^- .*/ &quot; lines containing &#39;note&#39; items: - | ||
136 | :syntax match JournalMoved /^&gt;.*/ &quot; lines containing &#39;moved&#39; items: &gt;</code></pre> | ||
137 | <p>Add highlights to each group:</p> | ||
138 | <pre class="vim"><code>:highlight JournalAll ctermfg=12 &quot; bright black | ||
139 | :highlight JournalDone ctermfg=12 &quot; bright black | ||
140 | :highlight JournalEvent ctermfg=6 &quot; cyan | ||
141 | :highlight JournalMoved ctermfg=5 &quot; magenta | ||
142 | :highlight JournalNote ctermfg=3 &quot; yellow</code></pre> | ||
143 | <p>In my terminal, this is rendered like so:</p> | ||
144 | <p><a href="https://u.peppe.rs/Du6.png"><img | ||
145 | src="https://u.peppe.rs/Du6.png" /></a></p> | ||
146 | <h3 id="habit-tracking">Habit tracking</h3> | ||
147 | <p>While this is not a part of my journaling system anymore, a few | ||
148 | headers and an awk script is all it takes to track habits. My weekly | ||
149 | entries would include a couple of habit headers like so:</p> | ||
150 | <pre><code>week 1 -------------- | ||
151 | |||
152 | × wake up on time | ||
153 | × water the plants | ||
154 | |||
155 | spend 7.5 7 10 | ||
156 | --------------------- | ||
157 | |||
158 | |||
159 | week 2 -------------- | ||
160 | |||
161 | · make the bed | ||
162 | · go to bed | ||
163 | |||
164 | spend 30 2.75 6 | ||
165 | ---------------------</code></pre> | ||
166 | <p>Here, under the <code>spend</code> header in week 1, are a list of | ||
167 | expenditures accumulated over the week. The monthly spend is calculated | ||
168 | with this awk script:</p> | ||
169 | <div class="sourceCode" id="cb17"><pre | ||
170 | class="sourceCode awk"><code class="sourceCode awk"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="cf">BEGIN</span> <span class="op">{</span>spend<span class="op">=</span><span class="dv">0</span><span class="op">;}</span></span> | ||
171 | <span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a><span class="ot">/</span><span class="ss">spend</span><span class="ot">/</span> <span class="op">{</span><span class="cf">for</span><span class="op">(</span>i<span class="op">=</span><span class="dv">1</span><span class="op">;</span>i<span class="op">&lt;=</span><span class="dt">$NF</span><span class="op">;</span>i<span class="op">++)</span> spend<span class="op">+=</span><span class="dt">$i</span><span class="op">;}</span></span> | ||
172 | <span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a><span class="cf">END</span> <span class="op">{</span> <span class="kw">printf</span> spend <span class="st">&quot;eur&quot;</span><span class="op">}</span></span></code></pre></div> | ||
173 | <p>And invoked like so:</p> | ||
174 | <pre><code>λ awk -f spend.awk journal/2023/01 | ||
175 | 63.25eur</code></pre> | ||
176 | <h3 id="reflection">Reflection</h3> | ||
177 | <p>Journaling is not just about planning what is to come, but also | ||
178 | reflecting on what has passed. It would make sense to simultaneously | ||
179 | look at the past few weeks’ entries while making your current one. To | ||
180 | open multiple months of entries at the same time:</p> | ||
181 | <pre><code>λ vim -O journal/2023/0{1,2,3}</code></pre> | ||
182 | <p>Opens 3 months, side-by-side, in vertical splits:</p> | ||
183 | <pre><code>JANUARY ------------ │ FEBRUARY ----------- │ MARCH -------------- | ||
184 | │ │ | ||
185 | Mo Tu We Th Fr Sa Su │ Mo Tu We Th Fr Sa Su │ Mo Tu We Th Fr Sa Su | ||
186 | 1 │ 1 2 3 4 5 │ 1 2 3 4 5 | ||
187 | 2 3 4 5 6 7 8 │ 6 7 8 9 10 11 12 │ 6 7 8 9 10 11 12 | ||
188 | 9 10 11 12 13 14 15 │ 13 14 15 16 17 18 19 │ 13 14 15 16 17 18 19 | ||
189 | 16 17 18 19 20 21 22 │ 20 21 22 23 24 25 26 │ 20 21 22 23 24 25 26 | ||
190 | 23 24 25 26 27 28 29 │ 27 28 │ 27 28 29 30 31 | ||
191 | 30 31 │ │ | ||
192 | │ │ | ||
193 | │ │ | ||
194 | WEEK 1 ------------- │ WEEK 1 ------------- │ WEEK 1 ------------- | ||
195 | │ │ | ||
196 | &gt; latex setup │ &gt; forex │ - weight: 64 | ||
197 | × make the bed │ × clean shoes │ &gt; close sg-pr | ||
198 | × 03: dentist │ × buy clothes │ × facewash | ||
199 | × integrate tsg │ × draw │ × groceries | ||
200 | │ │ | ||
201 | │ │ | ||
202 | WEEK 2 ------------- │ WEEK 2 ------------- │ WEEK 2 ------------- | ||
203 | │ │ | ||
204 | × latex setup │ - viral fever │ &gt; close sg-pr | ||
205 | × send invoice │ × forex │ × plan meet | ||
206 | × stack-graph pr │ × activate sim │ × sg storage | ||
207 | │ × bitlbee │</code></pre> | ||
208 | <h3 id="reducing-friction">Reducing friction</h3> | ||
209 | <p>Journaling already requires a solid amount of discipline and | ||
210 | consistency. The added friction of typing | ||
211 | <code>vim journal/$CURRENT_YEAR/$CURRENT_MONTH</code> each time is doing | ||
212 | no favors.</p> | ||
213 | <p>To open the current month based on system time:</p> | ||
214 | <div class="sourceCode" id="cb21"><pre | ||
215 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> vim <span class="va">$(</span><span class="fu">date</span> +<span class="st">&quot;%Y/%m&quot;</span><span class="va">)</span></span></code></pre></div> | ||
216 | <p>To open all the months within a 2 month window of today, is a little | ||
217 | trickier. The command we wish to generate is (if today is 2023/12):</p> | ||
218 | <div class="sourceCode" id="cb22"><pre | ||
219 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> vim <span class="at">-O</span> 2023/10 2023/11 2023/12 2024/01 2024/02</span></code></pre></div> | ||
220 | <p>And that is where <code>dateseq</code> from <a | ||
221 | href="http://www.fresse.org/dateutils">dateutils</a> comes in handy, for | ||
222 | example:</p> | ||
223 | <div class="sourceCode" id="cb23"><pre | ||
224 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> dateseq 2012-02-01 2012-03-01</span> | ||
225 | <span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a><span class="ex">2012-02-01</span></span> | ||
226 | <span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a><span class="ex">2012-02-02</span></span> | ||
227 | <span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a><span class="ex">2012-02-03</span></span> | ||
228 | <span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a><span class="ex">...</span></span> | ||
229 | <span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a><span class="ex">2012-02-28</span></span> | ||
230 | <span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a><span class="ex">2012-02-29</span></span> | ||
231 | <span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a><span class="ex">2012-03-01</span></span></code></pre></div> | ||
232 | <p>This script opens all months within a 2 month window of today:</p> | ||
233 | <div class="sourceCode" id="cb24"><pre | ||
234 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> vim <span class="at">-O</span> <span class="va">$(</span></span> | ||
235 | <span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a> <span class="ex">dateseq</span> <span class="dt">\</span></span> | ||
236 | <span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a> <span class="st">&quot;</span><span class="va">$(</span><span class="fu">date</span> <span class="at">--date</span> <span class="st">&quot;2 months ago&quot;</span> +%Y/%m<span class="va">)</span><span class="st">&quot;</span> <span class="dt">\</span></span> | ||
237 | <span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a> <span class="st">&quot;</span><span class="va">$(</span><span class="fu">date</span> <span class="at">--date</span> <span class="st">&quot;2 months&quot;</span> +%Y/%m<span class="va">)</span><span class="st">&quot;</span> <span class="dt">\</span></span> | ||
238 | <span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a> <span class="at">-i</span> %Y/%m <span class="dt">\</span></span> | ||
239 | <span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a> <span class="at">-f</span> %Y/%m</span> | ||
240 | <span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a><span class="va">)</span></span></code></pre></div> | ||
241 | <h3 id="fin">Fin</h3> | ||
242 | <p>You can find a sample vimrc file here: <a | ||
243 | href="https://git.peppe.rs/cli/journal/tree">cli/journal</a>, along with | ||
244 | a nix flake file to kick things off.</p> | ||
245 | <p>Plain text journaling can be just as much fun as a pen and paper. | ||
246 | Throw in some ASCII art for each month, use swankier signifiers, or | ||
247 | louder syntax highlighting. Don’t expect forgiveness from org-mode users | ||
248 | though.</p> | ||
249 | <p><a href="https://u.peppe.rs/ZCK.png"><img | ||
250 | src="https://u.peppe.rs/ZCK.png" /></a></p></description> | ||
251 | <link>https://peppe.rs/posts/plain_text_journaling/</link> | ||
252 | <pubDate>Sun, 18 Jun 2023 19:40:00 +0000</pubDate> | ||
253 | <guid>https://peppe.rs/posts/plain_text_journaling/</guid> | ||
254 | </item> | ||
255 | <item> | ||
15 | <title>Curing A Case Of Git-UX</title> | 256 | <title>Curing A Case Of Git-UX</title> |
16 | <description><p>Git worktrees are great, but they fall behind the venerable | 257 | <description><p>Git worktrees are great, but they fall behind the venerable |
17 | <code>git checkout</code> sometimes. I attempted to fix that with <a | 258 | <code>git checkout</code> sometimes. I attempted to fix that with <a |
diff --git a/docs/posts/index.html b/docs/posts/index.html index 4ed7f2d..9fcc773 100644 --- a/docs/posts/index.html +++ b/docs/posts/index.html | |||
@@ -27,6 +27,23 @@ | |||
27 | <tr> | 27 | <tr> |
28 | <td class=table-post> | 28 | <td class=table-post> |
29 | <div class="date"> | 29 | <div class="date"> |
30 | 19/06 — 2023 | ||
31 | </div> | ||
32 | <a href="/posts/plain_text_journaling" class="post-link"> | ||
33 | <span class="post-link">Plain Text Journaling</span> | ||
34 | </a> | ||
35 | </td> | ||
36 | <td class=table-stats> | ||
37 | <span class="stats-number"> | ||
38 | 8.9 | ||
39 | </span> | ||
40 | <span class=stats-unit>min</span> | ||
41 | </td> | ||
42 | </tr> | ||
43 | |||
44 | <tr> | ||
45 | <td class=table-post> | ||
46 | <div class="date"> | ||
30 | 03/09 — 2022 | 47 | 03/09 — 2022 |
31 | </div> | 48 | </div> |
32 | <a href="/posts/curing_a_case_of_git-UX" class="post-link"> | 49 | <a href="/posts/curing_a_case_of_git-UX" class="post-link"> |
diff --git a/docs/posts/plain_text_journaling/index.html b/docs/posts/plain_text_journaling/index.html new file mode 100644 index 0000000..1ef9011 --- /dev/null +++ b/docs/posts/plain_text_journaling/index.html | |||
@@ -0,0 +1,308 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html lang="en"> | ||
3 | <head> | ||
4 | <link rel="stylesheet" href="/style.css"> | ||
5 | <link rel="stylesheet" href="/syntax.css"> | ||
6 | <meta charset="UTF-8"> | ||
7 | <meta name="viewport" content="initial-scale=1"> | ||
8 | <meta content="#ffffff" name="theme-color"> | ||
9 | <meta name="HandheldFriendly" content="true"> | ||
10 | <meta property="og:title" content="Plain Text Journaling"> | ||
11 | <meta property="og:type" content="website"> | ||
12 | <meta property="og:description" content="a static site {for, by, about} me "> | ||
13 | <meta property="og:url" content="https://peppe.rs"> | ||
14 | <link rel="icon" type="image/x-icon" href="/favicon.png"> | ||
15 | <title>Plain Text Journaling · peppe.rs</title> | ||
16 | <body> | ||
17 | <div class="posts"> | ||
18 | <div class="post"> | ||
19 | <a href="/" class="post-end-link">Home</a> | ||
20 | <span>/</span> | ||
21 | <a href="/posts" class="post-end-link">Posts</a> | ||
22 | <span>/</span> | ||
23 | <a class="post-end-link">Plain Text Journaling</a> | ||
24 | <a class="stats post-end-link" href="https://git.peppe.rs/web/site/plain/posts/plain_text_journaling.md | ||
25 | ">View Raw</a> | ||
26 | <div class="separator"></div> | ||
27 | <div class="date"> | ||
28 | 19/06 — 2023 | ||
29 | <div class="stats"> | ||
30 | <span class="stats-number"> | ||
31 | 138.66 | ||
32 | </span> | ||
33 | <span class="stats-unit">cm</span> | ||
34 |   | ||
35 | <span class="stats-number"> | ||
36 | 8.9 | ||
37 | </span> | ||
38 | <span class="stats-unit">min</span> | ||
39 | </div> | ||
40 | </div> | ||
41 | <h1> | ||
42 | Plain Text Journaling | ||
43 | </h1> | ||
44 | <div class="post-text"> | ||
45 | <p>I cobbled together a journaling system with {neo,}vim, coreutils and | ||
46 | <a href="http://www.fresse.org/dateutils">dateutils</a>. This system is | ||
47 | loosely based on <a href="https://www.rydercarroll.com/">Ryder | ||
48 | Caroll’s</a> Bullet Journal method.</p> | ||
49 | <p><a href="https://u.peppe.rs/SpF.png"><img | ||
50 | src="https://u.peppe.rs/SpF.png" /></a></p> | ||
51 | <h3 id="the-format">The format</h3> | ||
52 | <p>The journal for a given year is a directory:</p> | ||
53 | <div class="sourceCode" id="cb1"><pre | ||
54 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> ls journal/</span> | ||
55 | <span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ex">2022/</span> 2023/</span></code></pre></div> | ||
56 | <p>In each directory are 12 files, one for each month of the year, | ||
57 | numbered like so:</p> | ||
58 | <div class="sourceCode" id="cb2"><pre | ||
59 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> ls journal/2023/</span> | ||
60 | <span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="ex">01</span> 02 03 04 05 06 07 08 09 10 11 12</span></code></pre></div> | ||
61 | <p>We can now begin writing stuff down:</p> | ||
62 | <div class="sourceCode" id="cb3"><pre | ||
63 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> vim journal/2023/1</span></code></pre></div> | ||
64 | <p>Every month must start with a calendar of course, fill that in | ||
65 | with:</p> | ||
66 | <pre class="vim"><code>:read !cal -m</code></pre> | ||
67 | <p>Your entry for January might look like this:</p> | ||
68 | <div class="sourceCode" id="cb5"><pre | ||
69 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> cat journal/2023/01</span> | ||
70 | <span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a> <span class="ex">January</span> 2023</span> | ||
71 | <span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="ex">Mo</span> Tu We Th Fr Sa Su</span> | ||
72 | <span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a> <span class="ex">1</span></span> | ||
73 | <span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a> <span class="ex">2</span> 3 4 5 6 7 8</span> | ||
74 | <span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a> <span class="ex">9</span> 10 11 12 13 14 15</span> | ||
75 | <span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="ex">16</span> 17 18 19 20 21 22</span> | ||
76 | <span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a><span class="ex">23</span> 24 25 26 27 28 29</span> | ||
77 | <span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="ex">30</span> 31</span></code></pre></div> | ||
78 | <p>I prefer planning week by week, as opposed to creating a task-list | ||
79 | every day, here’s what I have for the first couple of weeks:</p> | ||
80 | <pre><code> January 2023 | ||
81 | Mo Tu We Th Fr Sa Su | ||
82 | 1 | ||
83 | 2 3 4 5 6 7 8 | ||
84 | 9 10 11 12 13 14 15 | ||
85 | 16 17 18 19 20 21 22 | ||
86 | 23 24 25 26 27 28 29 | ||
87 | 30 31 | ||
88 | |||
89 | |||
90 | week 1 | ||
91 | |||
92 | done apply leaves | ||
93 | done dload boarding pass | ||
94 | moved reply to dan | ||
95 | |||
96 | |||
97 | week 2 | ||
98 | |||
99 | todo reply to dan | ||
100 | todo pack bags | ||
101 | done travel insurance | ||
102 | todo weigh luggage</code></pre> | ||
103 | <p>I start the week by writing a header and each item that week is | ||
104 | placed on its own line. The items are prefixed with a <code>todo</code> | ||
105 | or a <code>done</code> signifier.</p> | ||
106 | <h3 id="form-over-function">Form over function</h3> | ||
107 | <p>Right off the bat, the signifiers look very noisy, Even more so once | ||
108 | we start introducing variety (I use “event”, “note” and “moved”):</p> | ||
109 | <pre><code>week 1 | ||
110 | |||
111 | todo apply leaves | ||
112 | done dload boarding pass | ||
113 | todo reply to dan | ||
114 | event fr trip | ||
115 | note weight 68.6</code></pre> | ||
116 | <p>We can clean this up with “abbreviations” | ||
117 | (<code>:h abbreviations</code>):</p> | ||
118 | <pre class="vim"><code>:iabbrev todo · | ||
119 | :iabbrev done ×</code></pre> | ||
120 | <p>Now, typing this:</p> | ||
121 | <pre><code>todo apply leaves</code></pre> | ||
122 | <p>Automatically inserts:</p> | ||
123 | <pre><code>· apply leaves</code></pre> | ||
124 | <p>You can use <code>x</code> and <code>o</code> as well, but | ||
125 | <code>×</code> (U+00D7, MULTIPLICATION SIGN) and <code>·</code> (U+00B7, | ||
126 | MIDDLE DOT) are more … <em>gourmet</em>.</p> | ||
127 | <p>The other signifiers I use are:</p> | ||
128 | <ul> | ||
129 | <li><code>-</code> for note</li> | ||
130 | <li><code>o</code> for event</li> | ||
131 | <li><code>></code> for moved.</li> | ||
132 | </ul> | ||
133 | <p>Nit #2 is the lack of order. We can employ vim to introduce grouping | ||
134 | and sorting. Select the list of entries for this week:</p> | ||
135 | <pre class="vim"><code>vip " line-wise select inner paragraph | ||
136 | :'<,'>sort " the markers '< and '> are automatically inserted, | ||
137 | " they mark the start and end of the selection</code></pre> | ||
138 | <p>We end up with:</p> | ||
139 | <pre><code>week 1 | ||
140 | |||
141 | · apply leaves | ||
142 | · reply to dan | ||
143 | × dload boarding pass</code></pre> | ||
144 | <p>The lines are grouped by their signifiers, segregating todo items | ||
145 | from completed items. Luckily, MIDDLE DOT is lesser than MULTIPLICATION | ||
146 | SIGN, so todo items are placed at the top. The same goes for | ||
147 | <code>o</code> and <code>x</code> symbols, either set of signifiers will | ||
148 | result in the same sorting order.</p> | ||
149 | <p>We can shorten this select-paragraph-invoke-sort dance by setting the | ||
150 | <code>formatprg</code> variable:</p> | ||
151 | <pre class="vim"><code>:set formatprg=sort\ -V</code></pre> | ||
152 | <p>Now, hitting <code>gqip</code> should automatically group and sort | ||
153 | the items for the week under the cursor, moving todo items to the top. | ||
154 | Finding signifier glyphs that suit your sorting preference is a fun | ||
155 | exercise.</p> | ||
156 | <h3 id="syntax-highlighting">Syntax highlighting</h3> | ||
157 | <p>Adding color to items introduces another layer of visual distinction. | ||
158 | In truth, I like to deck it out just because.</p> | ||
159 | <p>First, create a few syntax groups:</p> | ||
160 | <pre class="vim"><code>:syntax match JournalAll /.*/ " captures the entire buffer | ||
161 | :syntax match JournalDone /^×.*/ " lines containing 'done' items: × | ||
162 | :syntax match JournalTodo /^·.*/ " lines containing 'todo' items: · | ||
163 | :syntax match JournalEvent /^o.*/ " lines containing 'event' items: o | ||
164 | :syntax match JournalNote /^- .*/ " lines containing 'note' items: - | ||
165 | :syntax match JournalMoved /^>.*/ " lines containing 'moved' items: ></code></pre> | ||
166 | <p>Add highlights to each group:</p> | ||
167 | <pre class="vim"><code>:highlight JournalAll ctermfg=12 " bright black | ||
168 | :highlight JournalDone ctermfg=12 " bright black | ||
169 | :highlight JournalEvent ctermfg=6 " cyan | ||
170 | :highlight JournalMoved ctermfg=5 " magenta | ||
171 | :highlight JournalNote ctermfg=3 " yellow</code></pre> | ||
172 | <p>In my terminal, this is rendered like so:</p> | ||
173 | <p><a href="https://u.peppe.rs/Du6.png"><img | ||
174 | src="https://u.peppe.rs/Du6.png" /></a></p> | ||
175 | <h3 id="habit-tracking">Habit tracking</h3> | ||
176 | <p>While this is not a part of my journaling system anymore, a few | ||
177 | headers and an awk script is all it takes to track habits. My weekly | ||
178 | entries would include a couple of habit headers like so:</p> | ||
179 | <pre><code>week 1 -------------- | ||
180 | |||
181 | × wake up on time | ||
182 | × water the plants | ||
183 | |||
184 | spend 7.5 7 10 | ||
185 | --------------------- | ||
186 | |||
187 | |||
188 | week 2 -------------- | ||
189 | |||
190 | · make the bed | ||
191 | · go to bed | ||
192 | |||
193 | spend 30 2.75 6 | ||
194 | ---------------------</code></pre> | ||
195 | <p>Here, under the <code>spend</code> header in week 1, are a list of | ||
196 | expenditures accumulated over the week. The monthly spend is calculated | ||
197 | with this awk script:</p> | ||
198 | <div class="sourceCode" id="cb17"><pre | ||
199 | class="sourceCode awk"><code class="sourceCode awk"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="cf">BEGIN</span> <span class="op">{</span>spend<span class="op">=</span><span class="dv">0</span><span class="op">;}</span></span> | ||
200 | <span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a><span class="ot">/</span><span class="ss">spend</span><span class="ot">/</span> <span class="op">{</span><span class="cf">for</span><span class="op">(</span>i<span class="op">=</span><span class="dv">1</span><span class="op">;</span>i<span class="op"><=</span><span class="dt">$NF</span><span class="op">;</span>i<span class="op">++)</span> spend<span class="op">+=</span><span class="dt">$i</span><span class="op">;}</span></span> | ||
201 | <span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a><span class="cf">END</span> <span class="op">{</span> <span class="kw">printf</span> spend <span class="st">"eur"</span><span class="op">}</span></span></code></pre></div> | ||
202 | <p>And invoked like so:</p> | ||
203 | <pre><code>λ awk -f spend.awk journal/2023/01 | ||
204 | 63.25eur</code></pre> | ||
205 | <h3 id="reflection">Reflection</h3> | ||
206 | <p>Journaling is not just about planning what is to come, but also | ||
207 | reflecting on what has passed. It would make sense to simultaneously | ||
208 | look at the past few weeks’ entries while making your current one. To | ||
209 | open multiple months of entries at the same time:</p> | ||
210 | <pre><code>λ vim -O journal/2023/0{1,2,3}</code></pre> | ||
211 | <p>Opens 3 months, side-by-side, in vertical splits:</p> | ||
212 | <pre><code>JANUARY ------------ │ FEBRUARY ----------- │ MARCH -------------- | ||
213 | │ │ | ||
214 | Mo Tu We Th Fr Sa Su │ Mo Tu We Th Fr Sa Su │ Mo Tu We Th Fr Sa Su | ||
215 | 1 │ 1 2 3 4 5 │ 1 2 3 4 5 | ||
216 | 2 3 4 5 6 7 8 │ 6 7 8 9 10 11 12 │ 6 7 8 9 10 11 12 | ||
217 | 9 10 11 12 13 14 15 │ 13 14 15 16 17 18 19 │ 13 14 15 16 17 18 19 | ||
218 | 16 17 18 19 20 21 22 │ 20 21 22 23 24 25 26 │ 20 21 22 23 24 25 26 | ||
219 | 23 24 25 26 27 28 29 │ 27 28 │ 27 28 29 30 31 | ||
220 | 30 31 │ │ | ||
221 | │ │ | ||
222 | │ │ | ||
223 | WEEK 1 ------------- │ WEEK 1 ------------- │ WEEK 1 ------------- | ||
224 | │ │ | ||
225 | > latex setup │ > forex │ - weight: 64 | ||
226 | × make the bed │ × clean shoes │ > close sg-pr | ||
227 | × 03: dentist │ × buy clothes │ × facewash | ||
228 | × integrate tsg │ × draw │ × groceries | ||
229 | │ │ | ||
230 | │ │ | ||
231 | WEEK 2 ------------- │ WEEK 2 ------------- │ WEEK 2 ------------- | ||
232 | │ │ | ||
233 | × latex setup │ - viral fever │ > close sg-pr | ||
234 | × send invoice │ × forex │ × plan meet | ||
235 | × stack-graph pr │ × activate sim │ × sg storage | ||
236 | │ × bitlbee │</code></pre> | ||
237 | <h3 id="reducing-friction">Reducing friction</h3> | ||
238 | <p>Journaling already requires a solid amount of discipline and | ||
239 | consistency. The added friction of typing | ||
240 | <code>vim journal/$CURRENT_YEAR/$CURRENT_MONTH</code> each time is doing | ||
241 | no favors.</p> | ||
242 | <p>To open the current month based on system time:</p> | ||
243 | <div class="sourceCode" id="cb21"><pre | ||
244 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> vim <span class="va">$(</span><span class="fu">date</span> +<span class="st">"%Y/%m"</span><span class="va">)</span></span></code></pre></div> | ||
245 | <p>To open all the months within a 2 month window of today, is a little | ||
246 | trickier. The command we wish to generate is (if today is 2023/12):</p> | ||
247 | <div class="sourceCode" id="cb22"><pre | ||
248 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> vim <span class="at">-O</span> 2023/10 2023/11 2023/12 2024/01 2024/02</span></code></pre></div> | ||
249 | <p>And that is where <code>dateseq</code> from <a | ||
250 | href="http://www.fresse.org/dateutils">dateutils</a> comes in handy, for | ||
251 | example:</p> | ||
252 | <div class="sourceCode" id="cb23"><pre | ||
253 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> dateseq 2012-02-01 2012-03-01</span> | ||
254 | <span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a><span class="ex">2012-02-01</span></span> | ||
255 | <span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a><span class="ex">2012-02-02</span></span> | ||
256 | <span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a><span class="ex">2012-02-03</span></span> | ||
257 | <span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a><span class="ex">...</span></span> | ||
258 | <span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a><span class="ex">2012-02-28</span></span> | ||
259 | <span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a><span class="ex">2012-02-29</span></span> | ||
260 | <span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a><span class="ex">2012-03-01</span></span></code></pre></div> | ||
261 | <p>This script opens all months within a 2 month window of today:</p> | ||
262 | <div class="sourceCode" id="cb24"><pre | ||
263 | class="sourceCode bash"><code class="sourceCode bash"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="ex">λ</span> vim <span class="at">-O</span> <span class="va">$(</span></span> | ||
264 | <span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a> <span class="ex">dateseq</span> <span class="dt">\</span></span> | ||
265 | <span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a> <span class="st">"</span><span class="va">$(</span><span class="fu">date</span> <span class="at">--date</span> <span class="st">"2 months ago"</span> +%Y/%m<span class="va">)</span><span class="st">"</span> <span class="dt">\</span></span> | ||
266 | <span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a> <span class="st">"</span><span class="va">$(</span><span class="fu">date</span> <span class="at">--date</span> <span class="st">"2 months"</span> +%Y/%m<span class="va">)</span><span class="st">"</span> <span class="dt">\</span></span> | ||
267 | <span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a> <span class="at">-i</span> %Y/%m <span class="dt">\</span></span> | ||
268 | <span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a> <span class="at">-f</span> %Y/%m</span> | ||
269 | <span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a><span class="va">)</span></span></code></pre></div> | ||
270 | <h3 id="fin">Fin</h3> | ||
271 | <p>You can find a sample vimrc file here: <a | ||
272 | href="https://git.peppe.rs/cli/journal/tree">cli/journal</a>, along with | ||
273 | a nix flake file to kick things off.</p> | ||
274 | <p>Plain text journaling can be just as much fun as a pen and paper. | ||
275 | Throw in some ASCII art for each month, use swankier signifiers, or | ||
276 | louder syntax highlighting. Don’t expect forgiveness from org-mode users | ||
277 | though.</p> | ||
278 | <p><a href="https://u.peppe.rs/ZCK.png"><img | ||
279 | src="https://u.peppe.rs/ZCK.png" /></a></p> | ||
280 | |||
281 | </div> | ||
282 | |||
283 | <div class="intro"> | ||
284 | Hi. | ||
285 | <div class="hot-links"> | ||
286 | <a href="https://peppe.rs/index.xml" class="feed-button">Subscribe</a> | ||
287 | </div> | ||
288 | <p>I'm Akshay, programmer and pixel-artist.</p> | ||
289 | <p> | ||
290 | I write <a href="https://git.peppe.rs">open-source stuff</a> to pass time. | ||
291 | I also design fonts: | ||
292 | <a href="https://git.peppe.rs/fonts/scientifica/about">scientifica</a>, | ||
293 | <a href="https://git.peppe.rs/fonts/curie/about">curie</a>. | ||
294 | </p> | ||
295 | <p>Send me a mail at [email protected] or a message at [email protected].</p> | ||
296 | </div> | ||
297 | |||
298 | <a href="/" class="post-end-link">Home</a> | ||
299 | <span>/</span> | ||
300 | <a href="/posts" class="post-end-link">Posts</a> | ||
301 | <span>/</span> | ||
302 | <a class="post-end-link">Plain Text Journaling</a> | ||
303 | <a class="stats post-end-link" href="https://git.peppe.rs/web/site/plain/posts/plain_text_journaling.md | ||
304 | ">View Raw</a> | ||
305 | </div> | ||
306 | </div> | ||
307 | </body> | ||
308 | </html> | ||
diff --git a/posts/plain_text_journaling.md b/posts/plain_text_journaling.md new file mode 100644 index 0000000..b1e2908 --- /dev/null +++ b/posts/plain_text_journaling.md | |||
@@ -0,0 +1,347 @@ | |||
1 | I cobbled together a journaling system with {neo,}vim, | ||
2 | coreutils and [dateutils](http://www.fresse.org/dateutils). | ||
3 | This system is loosely based on [Ryder | ||
4 | Caroll's](https://www.rydercarroll.com/) Bullet Journal | ||
5 | method. | ||
6 | |||
7 | [![](https://u.peppe.rs/SpF.png)](https://u.peppe.rs/SpF.png) | ||
8 | |||
9 | ### The format | ||
10 | |||
11 | The journal for a given year is a directory: | ||
12 | |||
13 | ```bash | ||
14 | λ ls journal/ | ||
15 | 2022/ 2023/ | ||
16 | ``` | ||
17 | |||
18 | In each directory are 12 files, one for each month of the | ||
19 | year, numbered like so: | ||
20 | |||
21 | ```bash | ||
22 | λ ls journal/2023/ | ||
23 | 01 02 03 04 05 06 07 08 09 10 11 12 | ||
24 | ``` | ||
25 | |||
26 | We can now begin writing stuff down: | ||
27 | |||
28 | ```bash | ||
29 | λ vim journal/2023/1 | ||
30 | ``` | ||
31 | |||
32 | Every month must start with a calendar of course, fill that | ||
33 | in with: | ||
34 | |||
35 | ```vim | ||
36 | :read !cal -m | ||
37 | ``` | ||
38 | |||
39 | Your entry for January might look like this: | ||
40 | |||
41 | ```bash | ||
42 | λ cat journal/2023/01 | ||
43 | January 2023 | ||
44 | Mo Tu We Th Fr Sa Su | ||
45 | 1 | ||
46 | 2 3 4 5 6 7 8 | ||
47 | 9 10 11 12 13 14 15 | ||
48 | 16 17 18 19 20 21 22 | ||
49 | 23 24 25 26 27 28 29 | ||
50 | 30 31 | ||
51 | ``` | ||
52 | |||
53 | I prefer planning week by week, as opposed to creating a | ||
54 | task-list every day, here's what I have for the first couple | ||
55 | of weeks: | ||
56 | |||
57 | ``` | ||
58 | January 2023 | ||
59 | Mo Tu We Th Fr Sa Su | ||
60 | 1 | ||
61 | 2 3 4 5 6 7 8 | ||
62 | 9 10 11 12 13 14 15 | ||
63 | 16 17 18 19 20 21 22 | ||
64 | 23 24 25 26 27 28 29 | ||
65 | 30 31 | ||
66 | |||
67 | |||
68 | week 1 | ||
69 | |||
70 | done apply leaves | ||
71 | done dload boarding pass | ||
72 | moved reply to dan | ||
73 | |||
74 | |||
75 | week 2 | ||
76 | |||
77 | todo reply to dan | ||
78 | todo pack bags | ||
79 | done travel insurance | ||
80 | todo weigh luggage | ||
81 | ``` | ||
82 | |||
83 | I start the week by writing a header and each item that week | ||
84 | is placed on its own line. The items are prefixed with a | ||
85 | `todo` or a `done` signifier. | ||
86 | |||
87 | |||
88 | ### Form over function | ||
89 | |||
90 | Right off the bat, the signifiers look very noisy, Even more | ||
91 | so once we start introducing variety (I use "event", "note" | ||
92 | and "moved"): | ||
93 | |||
94 | ``` | ||
95 | week 1 | ||
96 | |||
97 | todo apply leaves | ||
98 | done dload boarding pass | ||
99 | todo reply to dan | ||
100 | event fr trip | ||
101 | note weight 68.6 | ||
102 | ``` | ||
103 | |||
104 | We can clean this up with "abbreviations" (`:h abbreviations`): | ||
105 | |||
106 | ```vim | ||
107 | :iabbrev todo · | ||
108 | :iabbrev done × | ||
109 | ``` | ||
110 | |||
111 | Now, typing this: | ||
112 | |||
113 | ``` | ||
114 | todo apply leaves | ||
115 | ``` | ||
116 | |||
117 | Automatically inserts: | ||
118 | |||
119 | ``` | ||
120 | · apply leaves | ||
121 | ``` | ||
122 | |||
123 | You can use `x` and `o` as well, but `×` (U+00D7, | ||
124 | MULTIPLICATION SIGN) and `·` (U+00B7, MIDDLE DOT) are more | ||
125 | ... *gourmet*. | ||
126 | |||
127 | The other signifiers I use are: | ||
128 | |||
129 | - `-` for note | ||
130 | - `o` for event | ||
131 | - `>` for moved. | ||
132 | |||
133 | Nit #2 is the lack of order. We can employ vim to introduce | ||
134 | grouping and sorting. Select the list of entries for this | ||
135 | week: | ||
136 | |||
137 | ```vim | ||
138 | vip " line-wise select inner paragraph | ||
139 | :'<,'>sort " the markers '< and '> are automatically inserted, | ||
140 | " they mark the start and end of the selection | ||
141 | ``` | ||
142 | |||
143 | We end up with: | ||
144 | |||
145 | ``` | ||
146 | week 1 | ||
147 | |||
148 | · apply leaves | ||
149 | · reply to dan | ||
150 | × dload boarding pass | ||
151 | ``` | ||
152 | |||
153 | The lines are grouped by their signifiers, segregating todo | ||
154 | items from completed items. Luckily, MIDDLE DOT is lesser | ||
155 | than MULTIPLICATION SIGN, so todo items are placed at the | ||
156 | top. The same goes for `o` and `x` symbols, either set of | ||
157 | signifiers will result in the same sorting order. | ||
158 | |||
159 | We can shorten this select-paragraph-invoke-sort dance by | ||
160 | setting the `formatprg` variable: | ||
161 | |||
162 | ```vim | ||
163 | :set formatprg=sort\ -V | ||
164 | ``` | ||
165 | |||
166 | Now, hitting `gqip` should automatically group and sort the | ||
167 | items for the week under the cursor, moving todo items to | ||
168 | the top. Finding signifier glyphs that suit your sorting | ||
169 | preference is a fun exercise. | ||
170 | |||
171 | ### Syntax highlighting | ||
172 | |||
173 | Adding color to items introduces another layer of visual | ||
174 | distinction. In truth, I like to deck it out just because. | ||
175 | |||
176 | First, create a few syntax groups: | ||
177 | |||
178 | ```vim | ||
179 | :syntax match JournalAll /.*/ " captures the entire buffer | ||
180 | :syntax match JournalDone /^×.*/ " lines containing 'done' items: × | ||
181 | :syntax match JournalTodo /^·.*/ " lines containing 'todo' items: · | ||
182 | :syntax match JournalEvent /^o.*/ " lines containing 'event' items: o | ||
183 | :syntax match JournalNote /^- .*/ " lines containing 'note' items: - | ||
184 | :syntax match JournalMoved /^>.*/ " lines containing 'moved' items: > | ||
185 | ``` | ||
186 | |||
187 | Add highlights to each group: | ||
188 | |||
189 | ```vim | ||
190 | :highlight JournalAll ctermfg=12 " bright black | ||
191 | :highlight JournalDone ctermfg=12 " bright black | ||
192 | :highlight JournalEvent ctermfg=6 " cyan | ||
193 | :highlight JournalMoved ctermfg=5 " magenta | ||
194 | :highlight JournalNote ctermfg=3 " yellow | ||
195 | ``` | ||
196 | |||
197 | In my terminal, this is rendered like so: | ||
198 | |||
199 | [![](https://u.peppe.rs/Du6.png)](https://u.peppe.rs/Du6.png) | ||
200 | |||
201 | ### Habit tracking | ||
202 | |||
203 | While this is not a part of my journaling system anymore, a | ||
204 | few headers and an awk script is all it takes to track | ||
205 | habits. My weekly entries would include a couple of habit | ||
206 | headers like so: | ||
207 | |||
208 | ``` | ||
209 | week 1 -------------- | ||
210 | |||
211 | × wake up on time | ||
212 | × water the plants | ||
213 | |||
214 | spend 7.5 7 10 | ||
215 | --------------------- | ||
216 | |||
217 | |||
218 | week 2 -------------- | ||
219 | |||
220 | · make the bed | ||
221 | · go to bed | ||
222 | |||
223 | spend 30 2.75 6 | ||
224 | --------------------- | ||
225 | ``` | ||
226 | |||
227 | Here, under the `spend` header in week 1, are a list of | ||
228 | expenditures accumulated over the week. The monthly spend is | ||
229 | calculated with this awk script: | ||
230 | |||
231 | ```awk | ||
232 | BEGIN {spend=0;} | ||
233 | /spend/ {for(i=1;i<=$NF;i++) spend+=$i;} | ||
234 | END { printf spend "eur"} | ||
235 | ``` | ||
236 | |||
237 | And invoked like so: | ||
238 | |||
239 | ``` | ||
240 | λ awk -f spend.awk journal/2023/01 | ||
241 | 63.25eur | ||
242 | ``` | ||
243 | |||
244 | ### Reflection | ||
245 | |||
246 | Journaling is not just about planning what is to come, but | ||
247 | also reflecting on what has passed. It would make sense to | ||
248 | simultaneously look at the past few weeks' entries while | ||
249 | making your current one. To open multiple months of entries | ||
250 | at the same time: | ||
251 | |||
252 | ``` | ||
253 | λ vim -O journal/2023/0{1,2,3} | ||
254 | ``` | ||
255 | |||
256 | Opens 3 months, side-by-side, in vertical splits: | ||
257 | |||
258 | ``` | ||
259 | JANUARY ------------ │ FEBRUARY ----------- │ MARCH -------------- | ||
260 | │ │ | ||
261 | Mo Tu We Th Fr Sa Su │ Mo Tu We Th Fr Sa Su │ Mo Tu We Th Fr Sa Su | ||
262 | 1 │ 1 2 3 4 5 │ 1 2 3 4 5 | ||
263 | 2 3 4 5 6 7 8 │ 6 7 8 9 10 11 12 │ 6 7 8 9 10 11 12 | ||
264 | 9 10 11 12 13 14 15 │ 13 14 15 16 17 18 19 │ 13 14 15 16 17 18 19 | ||
265 | 16 17 18 19 20 21 22 │ 20 21 22 23 24 25 26 │ 20 21 22 23 24 25 26 | ||
266 | 23 24 25 26 27 28 29 │ 27 28 │ 27 28 29 30 31 | ||
267 | 30 31 │ │ | ||
268 | │ │ | ||
269 | │ │ | ||
270 | WEEK 1 ------------- │ WEEK 1 ------------- │ WEEK 1 ------------- | ||
271 | │ │ | ||
272 | > latex setup │ > forex │ - weight: 64 | ||
273 | × make the bed │ × clean shoes │ > close sg-pr | ||
274 | × 03: dentist │ × buy clothes │ × facewash | ||
275 | × integrate tsg │ × draw │ × groceries | ||
276 | │ │ | ||
277 | │ │ | ||
278 | WEEK 2 ------------- │ WEEK 2 ------------- │ WEEK 2 ------------- | ||
279 | │ │ | ||
280 | × latex setup │ - viral fever │ > close sg-pr | ||
281 | × send invoice │ × forex │ × plan meet | ||
282 | × stack-graph pr │ × activate sim │ × sg storage | ||
283 | │ × bitlbee │ | ||
284 | ``` | ||
285 | |||
286 | ### Reducing friction | ||
287 | |||
288 | Journaling already requires a solid amount of discipline and | ||
289 | consistency. The added friction of typing `vim | ||
290 | journal/$CURRENT_YEAR/$CURRENT_MONTH` each time is doing no | ||
291 | favors. | ||
292 | |||
293 | To open the current month based on system time: | ||
294 | |||
295 | ```bash | ||
296 | λ vim $(date +"%Y/%m") | ||
297 | ``` | ||
298 | |||
299 | To open all the months within a 2 month window of today, is | ||
300 | a little trickier. The command we wish to generate is (if | ||
301 | today is 2023/12): | ||
302 | |||
303 | ```bash | ||
304 | λ vim -O 2023/10 2023/11 2023/12 2024/01 2024/02 | ||
305 | ``` | ||
306 | |||
307 | And that is where `dateseq` from | ||
308 | [dateutils](http://www.fresse.org/dateutils) comes in handy, | ||
309 | for example: | ||
310 | |||
311 | ```bash | ||
312 | λ dateseq 2012-02-01 2012-03-01 | ||
313 | 2012-02-01 | ||
314 | 2012-02-02 | ||
315 | 2012-02-03 | ||
316 | ... | ||
317 | 2012-02-28 | ||
318 | 2012-02-29 | ||
319 | 2012-03-01 | ||
320 | ``` | ||
321 | |||
322 | This script opens all months within a 2 month window of | ||
323 | today: | ||
324 | |||
325 | ```bash | ||
326 | λ vim -O $( | ||
327 | dateseq \ | ||
328 | "$(date --date "2 months ago" +%Y/%m)" \ | ||
329 | "$(date --date "2 months" +%Y/%m)" \ | ||
330 | -i %Y/%m \ | ||
331 | -f %Y/%m | ||
332 | ) | ||
333 | ``` | ||
334 | |||
335 | |||
336 | ### Fin | ||
337 | |||
338 | You can find a sample vimrc file here: | ||
339 | [cli/journal](https://git.peppe.rs/cli/journal/tree), along | ||
340 | with a nix flake file to kick things off. | ||
341 | |||
342 | Plain text journaling can be just as much fun as a pen and | ||
343 | paper. Throw in some ASCII art for each month, use swankier | ||
344 | signifiers, or louder syntax highlighting. Don't expect | ||
345 | forgiveness from org-mode users though. | ||
346 | |||
347 | [![](https://u.peppe.rs/ZCK.png)](https://u.peppe.rs/ZCK.png) | ||