EXTRACTING 'TODO'S FROM A LOG

Hello gophers!

In  one  of  my earliest rambling phlog posts, I mentioned that I
keep a personal "log", which is my version of a journal or diary.
[1]

In short, here's how the system works:

1.  I  always  have  a small notebook and mechanical pencil on my
person in which I record the happenings of the day, ideas, things
I've learned and...TODOs!

2.  The  next  day,  I transcribe the previous day's entry into a
text file named with the day's date (example: "2019-05-17-Fri").



What works well
=================================================================

For the most part, this has worked really well for years because:

* Paper notebook and mechanical pencil are (nearly) bomb-proof

*  As long as I remember to jot things into the notebook, I never
lose information or ideas

* The transcription process means I never  forget  about  a  TODO
note because I'm guaranteed to see the note again

This  last  point is especially important because _knowing you'll
see the note again_ develops trust in the  system.   Trust  means
that I'm not tempted to put important things somewhere else "just
in case" and have the whole thing fall apart  into  a  series  of
post-its,  emails  to  myself, etc. like I used to do before this
system.

The other awesome super-power of this system (over  just  writing
in a paper journal) is that text files are searchable!



The problem
=================================================================

Transcribing is a bit of a chore, but it only takes a little over
five minutes for me to type up the _average_ day's log.

The problem is the TODO entries.

In  the best case scenario, I can accomplish the TODO immediately
- often just a matter of filing away a note in another text  file
(or VimWiki, which I use for most of my general notes).

But some things would be more involved - even taking me away from
the keyboard entirely.

If a TODO was big enough that I couldn't just  stop  and  get  it
done right away, I would need to make sure I didn't forget it. So
I would then have to stop transcribing anyway,  flip  forward  to
the  current day in my paper notebook and *re-write* the entry as
a safe-guard.

Sometimes I ended up re-writing the same TODO over and over for a
week before it got done.

I don't enjoy hand writing things.

So  this was truly a painful burden (bordering on punishment), so
I usually tried to complete the TODO as soon as I could.

Well, I was finding that the so-called task of  "transcribing  my
log"  could  easily  take over an hour for a single day's entries
because it actually encompassed a half dozen other tasks.

You can imagine how this problem could snowball  out  of  control
when I got a little behind in my transcription!

(And  let's  not  even speak of being behind on the raw _written_
entries other than to say I am human and it has happened.)



The solution
=================================================================

I  love it when a solution is technological.  But I'm shy of sys-
tems which are: complicated, fragile, or proprietary.

So how could I:

1. Transcribe a day's entry as fast as I could type the words  on
the page

2. Trust the system to capture TODOs

3. Be reminded of any outstanding TODOs until they are done

4. Make it easy to track the completion of TODOs

Whatever  it was would also have to be simple, free, and entirely
under my control.

The solution to the first three items is an amazingly simple Perl
script called "extract-todos":

 #!/usr/bin/perl

 # CPAN package:
 use Mail::Sendmail;

 my $todos = `ag '^todo:' /home/ratfactor/log/`;
 my $count = $todos =~ tr/\n//;

 my %mail = (
         To      => '[email protected]',
         From    => '[email protected]',
         Subject => "$count TODOs",
         Message => $todos,
 );
 sendmail(%mail) or die "Could not send mail.";

It  matches any line which starts with "todo:" (case insensitive,
so "TODO:" works too) and sends the results in  the  body  of  an
email.

     Side-notes:

     I  use  "ag" - The Silver Searcher, but grep would be
     almost a drop-in replacement - just a couple  command
     line changes.

     The CPAN Sendmail module is completely self-contained
     and requires  no  additional  configuration  to  send
     email.

     As  I  expected, I also needed to whitelist the email
     from my todo script with my email provider  based  on
     the  "From"  address  to keep it from being marked as
     Spam.

This script runs every night at 02:00.  Here's the cron entry:

 0 2 * * * /home/ratfactor/bin/extract-todos

Every morning, there's an email in my inbox with a  subject  like
"3 TODOs".  Open it up and there they are!

I love my little email report.



Additional Vim Sugar
=================================================================

So you might be wondering how  I  complete  a  TODO  item  so  it
doesn't keep getting emailed to me over and over.

What  I've decided to do is complete an entry by changing "todo:"
into "done <date>:" so that an entry like

 todo: Buy some milk

becomes

 done 2019-05-19: Buy some milk

There are lots of possible future applications for having a  date
of an item being complete.

     It has also occurred to me that there are neat things
     I could do with the TODOs themselves, such as append-
     ing  a  future "due" date.  But with added complexity
     comes a reduction in trust in my system.

     For now, if I need to schedule something for the  fu-
     ture, I'll use a proper calendar.

     What  I  *can* do in my log system, though, is make a
     TODO entry to *remind me to make* the calendar  entry
     for a specific future date.

But  wouldn't be a total pain to have to open up each file with a
TODO entry, find the entry, and update the text?

Yes it would be horrible.

I didn't do even a single entry manually.

Instead, I've got this incredibly cool Vim "one-liner" in a shell
script called "todos":

 #!/bin/bash

 vim -c "cd /home/ratfactor/log/" \
         -c "vimgrep /^todo:/ *" \
         -c "copen"

Each "-c" option runs a command in Vim (as if you'd typed ":" and
then the ex command yourself).

What this does is open Vim, change to my log directory,  use  the
vimgrep  command to search for TODOs and then open up the "quick-
fix" window in a split window with all of the results.

Neat!  But to make it even better, I've got these keyboard short-
cuts in my .vimrc:

 nnoremap <C-up> :cp<CR>
 nnoremap <C-down> :cn<CR>
 nnoremap <F6> :s/^todo:/done <C-r>=strftime("%F")<CR>:/i<CR>

If  you've  not dealt with a lot of Vimscript, this may appear to
be sheer nonsense, but here's what each keyboard shortcut does:

     Ctrl+Up      Go to previous TODO entry
     Ctrl+Down    Go to next TODO entry
     F6           Mark and datestamp a TODO as done

The previous/next shortcuts work no matter if the entries are  in
the same day's file or if they span multiple months of files.

I  used  this  new  setup yesterday afternoon and this morning to
blast through a backlog of 32 TODOs in record time.

It's not merely less typing, it's less *thinking*.



Conclusion
=================================================================

I'm really happy with this setup.

This  system  means I can concentrate on the task at hand without
the constant annoying and inefficient context-switching  required
by my old method.

If I'm transcribing an entry, that's all I'm doing: typing.

If  I'm clearing TODO's, all I have to worry about is either com-
pleting the TODO or skipping it and going on  to  the  next  one.
After  just  a  handful of entries, the keyboard shortcuts become
completely automatic.

I don't lay awake at night wondering  if  I'm  forgetting  to  do
something because I know there's going to be an email waiting for
me in my inbox in the morning.  I doubt I'll even be reading  the
email  the  vast majority of the time.  It's more like a piece of
string tied to my finger: just seeing it there is enough of a re-
minder.

This entire system is so minimalistic that I could easily re-cre-
ate it if I had to.

--

Isn't it amazing how you can ponder  something  for  *years*  and
when  you  finally come up with a solution, it can turn out to be
so astonishingly *quick and easy* to implement?

Of course, it's only because of the years of pondering  that  the
simple solution becomes "obvious". :-)

[1]  gopher://sdf.org/0/users/ratfactor/phlog/2018-08-10-The-Log-
ging-Habit