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}