did.txt - Making Simple Things More Complicated

I started using the 'did.txt' idea and I liked it, but wanted some more functionality.

TL;DR:

I started using the ‘did.txt’ idea from https://theptrk.com/2018/07/11/did-txt-file/ (found via HN), and I liked it a lot, but wanted some more and different functionality. You can skip to “The full scripts” section to see the scripts I have now.

The original

The original version of did.txt aliases a did command to start vim with the current timestamp automatically inserted at the end of the file ~/did.txt:

.bashrc
...
alias did=”vim +'normal Go' +'r!date' ~/did.txt”
...

So running did results in editing the file in vim like so:

original version

I implemented that version, and liked it, but there were a few things I wanted to add and change to make this a little more suited to my own preferences and laziness:

  1. Add the newest entries at the top
  2. Sync the log file between my computers
  3. Easily show what I did yesterday
  4. Add single entries from the command line

Add the newest entries at the top

This was the first thing I changed, because I like seeing the most recent entries at the top. And I saved myself a few keystrokes by automatically inserting the - characters for the entry, and starting in insert mode.

vim +'r!date' +'normal o' +'normal ggo-  ' +startinsert ~/did.txt

Now after running did I can start typing the entry at the top of the file without any extra keystrokes.

edit entry at top

Sync the log file between computers

I use a couple different machines most days, one at work and a different one at home. So I want to sync this log between those to have a single log of what I did. This was simple - I just put the log file in my Dropbox folder, so it gets automatically synced.

(At this point, as things were starting to get more complicated, I switched from an alias to a script.)

did
#!/usr/bin/env bash
did_file="$HOME/Dropbox/doc/did.txt"
vim +'r!date' +'normal o' +'normal ggo-  ' +startinsert "$did_file"

Easily show what I did yesterday

This is nice to have for standups (what did I do yesterday?), as well as general review.

Problem is, for the original version, it uses the plain date command to log the current date.

$ date
Wed Dec 26 14:44:18 PST 2018

That format puts the time in the middle of the date info, which adds some difficulty when trying to search the entries by date. So I changed the date format to make this easy.

$ date +"%Y-%m-%d %H:%M:%S %A"
2018-12-26 14:47:00 Wednesday

When using this format with vim, the backslashes have to be escaped because % in vim means the current file name.

vim +'r!date +"\%Y-\%m-\%d \%H:\%M:\%S \%A"' +'normal o' +'normal ggo-  ' +startinsert "$did_file"

Now it uses that format for the date, which is much easier to search for.

new date format

Then I created a new script yesterday to find the entries for the day before.

yesterday
#!/usr/bin/env bash
yesterday_date="$(gdate -d '1 day ago' +"%Y-%m-%d")"
echo "Items from yesterday, $yesterday_date:"

did_file="$HOME/Dropbox/doc/did.txt"

# print all the entries matching yesterday's date
# (from http://www.grymoire.com/Unix/Sed.html#toc-uh-58)
sed -n '
  # if an empty line, check the paragraph
  /^$/ b para
  # else add it to the hold buffer
  H
  # at end of file, check paragraph
  $ b para
  # now branch to end of script
  b
  # this is where a paragraph is checked for the pattern
  :para
  # return the entire paragraph into the pattern space
  x
  # look for the pattern, if there - print
  /'$yesterday_date'/ p
' "$did_file"

The main sed command is adapted from http://www.grymoire.com/Unix/Sed.html#toc-uh-58 (that page is a great tutorial on sed). It collects the lines of each paragraph together, and prints out the paragraphs that contain yesterday’s date.

Also of note is that this script uses gdate, which is the GNU version of date that has more features than the date command that ships with OSX. You can install that with brew install coreutils (which installs a bunch of other GNU stuff, more info here).

$ yesterday
Items from yesterday, 2018-12-21:

2018-12-21 17:07:23 Friday
- fix ssh-config for the new home network

2018-12-21 15:51:48 Friday
- fix rate-limiting of notion installer
...

Add single entries from the command line

Most of the time I’m only adding one line, and there’s really no need for me to go into vim. So I should just be able to add the entry on the command line. That’s easy enough to do in the script.

timestamp="$(date +"%Y-%m-%d %H:%M:%S %A")"
message="$1"
echo -e "$timestamp\n- $message\n\n$(cat $did_file)" > "$did_file"

Now I can type this in on the command line.

$ did "adding a single entry to the did file"

Which is nice, but I would like a little feedback about what was just added. So I added a sed command to print out everything up to the first blank line.

sed -n -e '/^$/ q' -e 'p' "$did_file"

That suppresses printing the lines automatically, and quits once it hits the first blank line (without printing it out). Otherwise it prints every non-blank line up to then.

$ did "adding entries on the command line"

2018-12-26 15:28:17 Wednesday
- adding entries on the command line

Much better.

The full scripts

Instead of a simple alias I now have two more complicated scripts.

Log what I did today:

did
#!/usr/bin/env bash
did_file="$HOME/Dropbox/doc/did.txt"
timestamp="$(date +"%Y-%m-%d %H:%M:%S %A")"

if [ -n "$1" ]
then
  # log the entry from the command line
  message="$1"
  echo -e "$timestamp\n- $message\n\n$(cat $did_file)" > "$did_file"
else
  # no entry input, do this in vim
  vim +"normal O$timestamp" +'normal o' +'normal ggo-  ' +startinsert "$did_file"
fi

# then show what I just added to that file - print everything up to the first blank line in the file
echo ""
# don't print automatically
# once it hits a blank line quit (without printing the blank line)
# otherwise print the non-blank line
sed -n -e '/^$/ q' -e 'p' "$did_file"

Show what I did yesterday:

yesterday
#!/usr/bin/env bash

yesterday_date="$(gdate -d '1 day ago' +"%Y-%m-%d")"
echo "Items from yesterday, $yesterday_date:"

did_file="$HOME/Dropbox/doc/did.txt"

# print all the entries matching yesterday's date
# (from http://www.grymoire.com/Unix/Sed.html#toc-uh-58)
sed -n '
  # if an empty line, check the paragraph
  /^$/ b para
  # else add it to the hold buffer
  H
  # at end of file, check paragraph
  $ b para
  # now branch to end of script
  b
  # this is where a paragraph is checked for the pattern
  :para
  # return the entire paragraph
  # into the pattern space
  x
  # look for the pattern, if there - print
  /'$yesterday_date'/ p
' "$did_file"

It’s a little more code, but it makes things a little easier, so I’m ok with that.