Showing ToDo’s with Conky by Context (HOWTO)

In my ongoing series of "Gosh, I love tweaking my desktop", I’ve come across a solution to my todo.txt problem.

I love the todo.txt script originally created by Gina Trapani. Keeping my todo list in a flat text file lets me keep it portable. It also makes it easy for conky (or if I was still using Windows, Samurize or Rainmeter) to display my todos on my desktop. While this HOWTO is written with conky in mind, if you can run a bash script on your system you can probably modify this to your purposes.

The problem I faced was that my todo list – even when sliced down by context or project – got to be too large for my desktop. Either the font was too small, or items were not displayed, or I was simply overwhelmed by the sheer amount of stuff to get done.

I had four requirements in order to solve my problem:

  • Be able to show any combination of categories
  • Be able to dynamically choose which categories to show
  • Have the items update
  • Low system resource usage

This is what I came up with, using a combination of grep, cat, conky, and zenity. You may not have heard of zenity before; it allows you to have an extremely customizable GUI option selector.

I did a standard install of the todo.txt, and created two files. Both reside in ~/scripts; there’s

todorc_base.txt

and

show_todo.sh

. I’ll comment the bits of code, then give you the full script here in a second.

cat /home/USER/scripts/todorc_base.txt > /home/USER/.todoconky

First, we copy the base of our configuration over to the home directory, overwriting any that might already be there.

Then this bit:

ans=$(zenity –list –text "What categories shall we show?" –checklist –column "Pick" –column "options" TRUE @pc TRUE @web FALSE @data FALSE @fiction FALSE –separator=" -e "); cat -b /home/USER/Documents/todo/todo.txt | grep -e $ans > /home/USER/scripts/sortedtodo.txt; echo ‘grep -e ‘$ans > /home/USER/scripts/categories.txt; echo ‘${execi 30 cat -b /home/USER/Documents/todo/todo.txt | grep -e ‘$ans’ > /home/USER/scripts/sortedtodo.txt}’ | cat – >> /home/USER/.todoconky ; echo ‘${color White}${execi 30 cat /home/USER/scripts/sortedtodo.txt | grep -e’ $ans’}’| cat – >> /home/USER/.todoconky

Yes, that’s all one line.

ans=$(zenity  --list  --text "What categories shall we show?" --checklist  --column "Pick" --column "options" TRUE @pc TRUE @web FALSE @data FALSE @fiction FALSE --separator=" -e ") 

This uses zenity to present us with a messagebox with checkboxes for each option. It’s actually simpler if you know you’ll only show one category at a time; that example’s in the code. My categories (or contexts) that I’m searching for are @pc, @web, @data, @fiction. I actually have more, but this gets the point across. It returns $ans with my responses.

cat -b /home/USER/Documents/todo/todo.txt | grep -e $ans > /home/USER/scripts/sortedtodo.txt 

This takes my todo.txt and parses it into a new text file that conky will actually read. Let’s say I chose @pc and @web. The actual command passed to grep will be

grep -e @pc -e @web

, because the separator is -e. Sweet, huh? So only items that have @pc or @web in them will be in this text file.

echo '${execi 30 cat -b /home/USER/Documents/todo/todo.txt | grep -e '$ans' > /home/USER/scripts/sortedtodo.txt}' | cat - >> /home/USER/.todoconky 

This adds a line to my conky config file so that it will recreate this same sorted text file every thirty seconds. That way, when I use the todo script to mark something as done, it’s automagically reflected in my conky display.

echo '${color White}${execi 30 cat /home/USER/scripts/sortedtodo.txt}' | cat - >> /home/USER/.todoconky 

This adds a line to my conky config file so that it displays the right text. I could have put it in my base copied file, but this makes more procedural sense to me. Same with this line:

echo '${color DarkSlateGray}${hr 2}' | cat - >> /home/USER/.todoconky

.

And then the script kills all conky instances and restarts the appropriate ones.

There’s two things I’d love to be able to do – have the contexts highlighted in conky’s display (the same way you would if you had –color=always with grep, and a way to only restart the particular conky instance in question. If you know how, please let me know in the comments!

Anyway, here’s the script and config!

show_todo.sh

!/bin/bash

Magic that makes it happen:

One category:

ans=$(zenity –height 300 –list –text "Which context would you like?" –radiolist –column "Pick" –column "Context" TRUE data FALSE pc FALSE web FALSE fiction FALSE nonfiction FALSE secondlife FALSE writing FALSE email FALSE phone); cat -b /home/USER/Documents/todo/todo.txt | grep –color=always @$ans > /home/USER/scripts/sortedtodo.txt

Move base there, overwrite old.

cat /home/USER/scripts/todorc_base.txt > /home/USER/.todoconky

use zenity to choose categories. use text files to hold categories

ans=$(zenity –list –text "What categories shall we show?" –checklist –column "Pick" –column "options" TRUE @pc TRUE @web FALSE @email FALSE @phone –separator=" -e "); cat -b /home/USER/Documents/todo/todo.txt | grep -e $ans > /home/USER/scripts/sortedtodo.txt; echo ‘${execi 30 cat -b /home/USER/Documents/todo/todo.txt | grep -e ‘$ans’ > /home/USER/scripts/sortedtodo.txt}’ | cat – >> /home/USER/.todoconky ; echo ‘${color White}${execi 30 cat /home/USER/scripts/sortedtodo.txt}’ | cat – >> /home/USER/.todoconky
echo ‘${color DarkSlateGray}${hr 2}’ | cat – >> /home/USER/.todoconky
killall conky

restart my top-of-screen bar

conky -c /home/USER/.conkybar &

start or restart my todo list

conky -c /home/USER/.todoconky &

todorc_base.txt

Text alignment, other possible values are commented

alignment top_left

alignment top_right

alignment bottom_left

alignment bottom_right

Gap between borders of screen and text

same thing as passing -x at command line

gap_x 970

gap_y 40

maximum_width 300

use_xft yes
xftfont verdana:size=9
xftalpha 0.8
own_window yes
own_window_type override
own_window_transparent yes
own_window_colour 262626
own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager
double_buffer yes
draw_shades no
draw_outline yes
draw_borders no
stippled_borders 10
border_width 1
default_shade_color grey
default_outline_color black
default_color BADCDD
use_spacer none
no_buffers yes
text_buffer_size 2048
uppercase no
color1 F8DF58
update_interval 5
update_interval_on_battery 10

TEXT
${color DarkSlateGray}${hr 2}