A while back I created a TODO file to keep track of things I wanted to get done. This way I would not have to think about everything I wanted to do because it was noted somewhere. I had a cron job mail the file to me every morning at 7:00.

I thought about writing a tool to allow me to add and remove items. I realized that it would be easy to setup a shell alias to edit a file. I made it so I just had to type "todo" instead of "emacs ~/TODO". Eventually I shortened it to the single letter command "t".

After a while I noticed I wanted to be able to list the items without opening and exiting an editor. It would be reasonable to want to run "t -l" to list the file. That lead to the following script.

Update: Changed default editor and pager lines as Tanktalus suggested. "vi" and "more" are safer defaults. It is better to use well known environment variables than hard coded constants.

Update: Applied patch from idle to make the script run under Perl 5.005.

The usage message looks like:
[frink@truth:~]$ t -h usage: /home/frink/code/scripts/todo.pl [options] where [options] are: -e , --editor specify an alternate editor like "vi" -h , --help this usage message -l , --list list the file contents instead of editing -p , --pager specify an alternate pager program like "more" or "c +at" examples: todo.pl todo.pl -l todo.pl -e vi todo.pl -l -p head todo.pl -l -p cat todo.pl -l -p more todo.pl -l -p "mail -S \"TODO reminders\" me@domain.com"
#!/usr/bin/perl -w # # file: /home/frink/code/scripts/todo.pl # purpose: manage my TODO file. # # chad c d clark < email: frink-todo.pl *at* superfrink *dot* com > # created: 2005-03-26 # updated: 2006-01-24 added -e , -h , -l , -p # $Id$ use strict; use Getopt::Long; sub list_file($); sub usage_mesage(); # -- set the global settings -- my %G; $G{editor} = $ENV{EDITOR} || "vi"; # editor to use $G{list_only} = 0; # dump file contents $G{list_pager} = $ENV{PAGER} || "more"; # output pager program $G{todo_file} = "/home/chad/TODO"; # TODO file $G{usage_only} = 0; # display usage message # -- get the command line args -- GetOptions ("e|editor=s" => \$G{editor}, "h|help" => \$G{usage_only}, "l|list" => \$G{list_only}, "p|pager=s" => \$G{list_pager}) or die("Problem with command line options. $!\n"); # -- now take the requested action -- # if a usage message was requested print one and exit if($G{usage_only}) { usage_mesage(); exit(0); } # if a contents list was requested then list the file and exit if($G{list_only}) { list_file($G{todo_file}); exit(0); } # -- if we get here we need to open the file for editing -- # make sure the file exists. unless(-e $G{todo_file}) { `touch $G{todo_file}`; } # open the file for editing. my $cmd = "$G{editor} $G{todo_file}"; print $cmd, "\n"; exec $cmd; # -- we should never get here -- die("$0 : exec($cmd) failed. $!\n"); # -- subroutines ---------------------------------------------------- sub usage_mesage() { # try to get a shorter version of the current program name. # (some people might not have File::Basename.) my $me = $0; if ($0 =~ m/^(.*\/)(.*)$/) { $me = $2; } print qq{ usage: $0 [options] where [options] are: -e , --editor specify an alternate editor like "vi" -h , --help this usage message -l , --list list the file contents instead of editing -p , --pager specify an alternate pager program like "more" or "c +at" examples: $me $me -l $me -e vi $me -l -p head $me -l -p cat $me -l -p more $me -l -p "mail -S \\\"TODO reminders\\\" me\@domain.com" }; } sub list_file($) { # purpose: dump the file using an optional pager program # globals used: # $G{list_pager} - pager program, eg "less" or "cat" my $fname = shift; unless ($fname) { die ("No file specified.\n"); } unless (-e $fname) { die ("File does not exist '$fname'.\n"); } unless (-r $fname) { die ("File is not readable '$fname'.\n"); } # open the input file open FH , "<$fname" or die("Unable to open file '$fname'. $!\n"); # if there is a pager program then use it if($G{list_pager}) { open PAGER , "| $G{list_pager}" or die("Unable to open file '$G{list_pager}'. $!\n"); while(<FH>) { print PAGER; } close PAGER; # else there is no pager program so just print the file contents } else { while(<FH>) { print; } } # close the input file close FH; }

In reply to Tool for editing / viewing a TODO file. by superfrink

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.