From af9a5edd1fd65b504cad8eee4c2097b8db7de1e0 Mon Sep 17 00:00:00 2001 From: Akshay Date: Mon, 19 Jun 2023 01:24:08 +0530 Subject: new post: plain text journaling --- posts/plain_text_journaling.md | 347 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 347 insertions(+) create mode 100644 posts/plain_text_journaling.md (limited to 'posts') 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 @@ +I cobbled together a journaling system with {neo,}vim, +coreutils and [dateutils](http://www.fresse.org/dateutils). +This system is loosely based on [Ryder +Caroll's](https://www.rydercarroll.com/) Bullet Journal +method. + +[![](https://u.peppe.rs/SpF.png)](https://u.peppe.rs/SpF.png) + +### The format + +The journal for a given year is a directory: + +```bash +λ ls journal/ +2022/ 2023/ +``` + +In each directory are 12 files, one for each month of the +year, numbered like so: + +```bash +λ ls journal/2023/ +01 02 03 04 05 06 07 08 09 10 11 12 +``` + +We can now begin writing stuff down: + +```bash +λ vim journal/2023/1 +``` + +Every month must start with a calendar of course, fill that +in with: + +```vim +:read !cal -m +``` + +Your entry for January might look like this: + +```bash +λ cat journal/2023/01 + January 2023 +Mo Tu We Th Fr Sa Su + 1 + 2 3 4 5 6 7 8 + 9 10 11 12 13 14 15 +16 17 18 19 20 21 22 +23 24 25 26 27 28 29 +30 31 +``` + +I prefer planning week by week, as opposed to creating a +task-list every day, here's what I have for the first couple +of weeks: + +``` + January 2023 +Mo Tu We Th Fr Sa Su + 1 + 2 3 4 5 6 7 8 + 9 10 11 12 13 14 15 +16 17 18 19 20 21 22 +23 24 25 26 27 28 29 +30 31 + + +week 1 + +done apply leaves +done dload boarding pass +moved reply to dan + + +week 2 + +todo reply to dan +todo pack bags +done travel insurance +todo weigh luggage +``` + +I start the week by writing a header and each item that week +is placed on its own line. The items are prefixed with a +`todo` or a `done` signifier. + + +### Form over function + +Right off the bat, the signifiers look very noisy, Even more +so once we start introducing variety (I use "event", "note" +and "moved"): + +``` +week 1 + +todo apply leaves +done dload boarding pass +todo reply to dan +event fr trip +note weight 68.6 +``` + +We can clean this up with "abbreviations" (`:h abbreviations`): + +```vim +:iabbrev todo · +:iabbrev done × +``` + +Now, typing this: + +``` +todo apply leaves +``` + +Automatically inserts: + +``` +· apply leaves +``` + +You can use `x` and `o` as well, but `×` (U+00D7, +MULTIPLICATION SIGN) and `·` (U+00B7, MIDDLE DOT) are more +... *gourmet*. + +The other signifiers I use are: + +- `-` for note +- `o` for event +- `>` for moved. + +Nit #2 is the lack of order. We can employ vim to introduce +grouping and sorting. Select the list of entries for this +week: + +```vim +vip " line-wise select inner paragraph +:'<,'>sort " the markers '< and '> are automatically inserted, + " they mark the start and end of the selection +``` + +We end up with: + +``` +week 1 + +· apply leaves +· reply to dan +× dload boarding pass +``` + +The lines are grouped by their signifiers, segregating todo +items from completed items. Luckily, MIDDLE DOT is lesser +than MULTIPLICATION SIGN, so todo items are placed at the +top. The same goes for `o` and `x` symbols, either set of +signifiers will result in the same sorting order. + +We can shorten this select-paragraph-invoke-sort dance by +setting the `formatprg` variable: + +```vim +:set formatprg=sort\ -V +``` + +Now, hitting `gqip` should automatically group and sort the +items for the week under the cursor, moving todo items to +the top. Finding signifier glyphs that suit your sorting +preference is a fun exercise. + +### Syntax highlighting + +Adding color to items introduces another layer of visual +distinction. In truth, I like to deck it out just because. + +First, create a few syntax groups: + +```vim +:syntax match JournalAll /.*/ " captures the entire buffer +:syntax match JournalDone /^×.*/ " lines containing 'done' items: × +:syntax match JournalTodo /^·.*/ " lines containing 'todo' items: · +:syntax match JournalEvent /^o.*/ " lines containing 'event' items: o +:syntax match JournalNote /^- .*/ " lines containing 'note' items: - +:syntax match JournalMoved /^>.*/ " lines containing 'moved' items: > +``` + +Add highlights to each group: + +```vim +:highlight JournalAll ctermfg=12 " bright black +:highlight JournalDone ctermfg=12 " bright black +:highlight JournalEvent ctermfg=6 " cyan +:highlight JournalMoved ctermfg=5 " magenta +:highlight JournalNote ctermfg=3 " yellow +``` + +In my terminal, this is rendered like so: + +[![](https://u.peppe.rs/Du6.png)](https://u.peppe.rs/Du6.png) + +### Habit tracking + +While this is not a part of my journaling system anymore, a +few headers and an awk script is all it takes to track +habits. My weekly entries would include a couple of habit +headers like so: + +``` +week 1 -------------- + +× wake up on time +× water the plants + +spend 7.5 7 10 +--------------------- + + +week 2 -------------- + +· make the bed +· go to bed + +spend 30 2.75 6 +--------------------- +``` + +Here, under the `spend` header in week 1, are a list of +expenditures accumulated over the week. The monthly spend is +calculated with this awk script: + +```awk +BEGIN {spend=0;} +/spend/ {for(i=1;i<=$NF;i++) spend+=$i;} +END { printf spend "eur"} +``` + +And invoked like so: + +``` +λ awk -f spend.awk journal/2023/01 +63.25eur +``` + +### Reflection + +Journaling is not just about planning what is to come, but +also reflecting on what has passed. It would make sense to +simultaneously look at the past few weeks' entries while +making your current one. To open multiple months of entries +at the same time: + +``` +λ vim -O journal/2023/0{1,2,3} +``` + +Opens 3 months, side-by-side, in vertical splits: + +``` +JANUARY ------------ │ FEBRUARY ----------- │ MARCH -------------- + │ │ +Mo Tu We Th Fr Sa Su │ Mo Tu We Th Fr Sa Su │ Mo Tu We Th Fr Sa Su + 1 │ 1 2 3 4 5 │ 1 2 3 4 5 + 2 3 4 5 6 7 8 │ 6 7 8 9 10 11 12 │ 6 7 8 9 10 11 12 + 9 10 11 12 13 14 15 │ 13 14 15 16 17 18 19 │ 13 14 15 16 17 18 19 +16 17 18 19 20 21 22 │ 20 21 22 23 24 25 26 │ 20 21 22 23 24 25 26 +23 24 25 26 27 28 29 │ 27 28 │ 27 28 29 30 31 +30 31 │ │ + │ │ + │ │ +WEEK 1 ------------- │ WEEK 1 ------------- │ WEEK 1 ------------- + │ │ +> latex setup │ > forex │ - weight: 64 +× make the bed │ × clean shoes │ > close sg-pr +× 03: dentist │ × buy clothes │ × facewash +× integrate tsg │ × draw │ × groceries + │ │ + │ │ +WEEK 2 ------------- │ WEEK 2 ------------- │ WEEK 2 ------------- + │ │ +× latex setup │ - viral fever │ > close sg-pr +× send invoice │ × forex │ × plan meet +× stack-graph pr │ × activate sim │ × sg storage + │ × bitlbee │ +``` + +### Reducing friction + +Journaling already requires a solid amount of discipline and +consistency. The added friction of typing `vim +journal/$CURRENT_YEAR/$CURRENT_MONTH` each time is doing no +favors. + +To open the current month based on system time: + +```bash +λ vim $(date +"%Y/%m") +``` + +To open all the months within a 2 month window of today, is +a little trickier. The command we wish to generate is (if +today is 2023/12): + +```bash +λ vim -O 2023/10 2023/11 2023/12 2024/01 2024/02 +``` + +And that is where `dateseq` from +[dateutils](http://www.fresse.org/dateutils) comes in handy, +for example: + +```bash +λ dateseq 2012-02-01 2012-03-01 +2012-02-01 +2012-02-02 +2012-02-03 +... +2012-02-28 +2012-02-29 +2012-03-01 +``` + +This script opens all months within a 2 month window of +today: + +```bash +λ vim -O $( + dateseq \ + "$(date --date "2 months ago" +%Y/%m)" \ + "$(date --date "2 months" +%Y/%m)" \ + -i %Y/%m \ + -f %Y/%m +) +``` + + +### Fin + +You can find a sample vimrc file here: +[cli/journal](https://git.peppe.rs/cli/journal/tree), along +with a nix flake file to kick things off. + +Plain text journaling can be just as much fun as a pen and +paper. Throw in some ASCII art for each month, use swankier +signifiers, or louder syntax highlighting. Don't expect +forgiveness from org-mode users though. + +[![](https://u.peppe.rs/ZCK.png)](https://u.peppe.rs/ZCK.png) -- cgit v1.2.3