For reasons that are not really relevant to this post, I am in search of a good solution for a personal log or journal type thing. Essentially, my goal is to be able to keep a record of certain events occurring, with a timestamp and brief explanation. Things like tags would be great, or fields for additional circumstances. Ideally, it’ll be portable and easily synced between several machines. Setting up an SQLite database would be a great solution, except that merge/sync issue sounds like a bit of a nightmare. jrnl looks really neat, but I haven’t been able to try it yet due to a borked homebrew on my home Mac1 and a lack of pip on my main Win machine. While syncing this could also be a chore, and there would be no mobile version, the interface itself is so straightforward that writing an entry could be done in any text editor, and then fed line-by-line into the command.
But I haven’t settled on anything yet, so I was just kind of maintaining a few separate text files using vim (Buffer Editor on iOS), and figuring I’d
cat them together at some point. But I got to thinking about ways I can make my life easier (not having to manually insert entries at the right spot chronologically, etc.), and came to a few conclusions about ways to maintain a quick and dirty manual log file.
First thing was to standardize and always use a full date/timestamp. Originally I was doing something like:
2018-01-29: 8.05a, sat on a chair. 10.30p, ate a banana. 2018-01-30: [...]
…which is very hard to sort. So I decided to simply preface every single entry with an ISO-formatted stamp down to the minute, and then delimit the entry with a tab (
2018-01-29T22.30 ate a banana.). As a matter of principal, I don’t like customizing my environment too much, or in ways that will lead to my forgetting how to do things without customization. I don’t, therefore, have many custom mappings in vim, but why not simplify adding the current date and/or time:
"insert time and date in insert mode imap <Leader>d <C-R>=strftime('%F')<CR> imap <Leader>t <C-R>=strftime('%R')<CR> imap <Leader>dt <C-R>=strftime('%FT%R')<CR>
Leaderd for ISO-formatted date, Leadert for ISO-formatted time (down to minutes), Leaderdt for both, separated by a ’T’. If everything is formatted the same, with lines beginning in ISO time formats, then every entry can readily be sorted. Sorting is simple in vim,
:sort or, to strip unique lines,
:sort u. I think that it’s more likely that the merge operation would happen outside of vim, in which case we’d use the
sort command in the same way:
cat log1.tsv log2.tsv >> log.tsv && sort -u -o log.tsv log.tsv.
sorting in place like this was a new discovery for me; I had always used temporary files before, but apparently if the output file to
sort (specified by
-o) is the same as the input file, it handles all the temporary file stuff on its own.
I think it’d be neat to establish a file format for this in vim. Sort upon opening (with optional uniqueness filtering). Automatically timestamp each newline. Perhaps have some settings to visually reformat the timestamp to something friendlier while retaining ISO in the background (using conceal?). The whole thing is admittedly very simple and straightforward, but it’s a process that seems worthwhile to think about and optimize. While most journaling solutions are much more complicated, I think there is a lot of value in a simple timestamped list of events for tracking certain behaviors, etc. I’m a bit surprised there isn’t more out there for it.
- The joys of a package manager written in a scripting language. ↩︎