[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 "cat" 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} = "emacs"; # editor to use
$G{todo_file} = "/home/chad/TODO"; # TODO file
$G{usage_only} = 0; # display usage message
$G{list_only} = 0; # dump file contents
$G{list_pager} = "less"; # output pager program
# -- 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 requests 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 "cat"
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() { print PAGER; }
close PAGER;
# else there is no pager program so just print the file contents
} else {
while() { print; }
}
# close the input file
close FH;
}
Not quite the same thing, but you might find Andy's App::HWD of interest.
< open FH , "<" , $fname or die("Unable to open file '$fname'. $!\n");
> open FH , "<$fname" or die("Unable to open file '$fname'. $!\n");
102c101
< open PAGER , "|-" , $G{list_pager}
> open PAGER , "| $G{list_pager}"
A couple minor points.
$G{editor} = "emacs"; # editor to use
$G{list_pager} = "less"; # output pager program
Both of these have existing unixy conventions. I would suggest a minor change:
$G{editor} = $ENV{EDITOR} || "vi"; # editor to use
$G{list_pager} = $ENV{PAGER} || "more"; # output pager program
These follow unixy convention. That is, if EDITOR is not set, vi is supposed to be the fallback default for editor, while if PAGER is not set, more is supposed to be the fallback default for the pager. Since you probably should have these variables set to emacs and less, respectively, in your own environment for use with other programs anyway, this shouldn't actually affect your program's operation on your machine.
Further, you can completely get rid of the commandline options using a little shell trick:
$ PAGER="mail -S \"TODO reminders\" me@domain.com" t -lor
$ EDITOR= t -eto use vi. This trick just sets an environment variable (that is exported) but resets it back to what it was, after the command is finished, leaving it unchanged in the parent process.
With these minor changes, your program feels more part of the unix world, making it operate just like everything else. For example, if you have sudo set up, try "sudo -e /etc/inittab" - it will use your current EDITOR environment variable to launch an editor to modify the inittab. Or "crontab -e" - launches the same editor to modify your crontab entries. So why not "t -e"? :-)
To be honest, when I saw the CUFP on the [Newest Nodes] page, I thought there would be a "-a" (add) option and a "-r" option which would allow easy/fast ability to modify standard TODO files (such as one might find in module distributions). That would be really handy ;-)
perlmonks.org content © perlmonks.org and adrianh, idle, superfrink, Tanktalus
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03