/todo

To get this branch, use:
bzr branch http://bzr.ed.am/todo
1 by edam
init
1
#!/usr/bin/perl
2
3
use strict;
4
use warnings;
5
use Getopt::Long;
6
use File::Basename;
7
8
# get app name
9
my $app_name = basename( $0 );
10
11
# option defaults
12
my $todo_dir = "~/.todo";
13
my $display_all = 0;
14
my $display_section = "IMMEDIATE";
15
my $display_headers = 0;
16
my $mode_edit = 0;
17
my $mode_help = 0;
18
my $mode_version = 0;
19
20
# parse command line opts
21
Getopt::Long::Configure( 'gnu_getopt' );
22
if( !GetOptions(
23
    'a|all' => \$display_all,
24
    'e|edit' => \$mode_edit,
25
    'h|headers' => \$display_headers,
26
    'section=s' => \$display_section,
27
    'help' => \$mode_help,
28
    'version' => \$mode_version,
29
) ) {
30
    print "Try `$app_name --help' for more information.\n";
31
    exit( 1 );
32
}
33
34
# help mode
35
if( $mode_help ) {
36
    print "todo - display your todo file\n\n".
37
	"Usage: $app_name [OPTIONS]\n\n".
38
	"Options:\n".
39
	"  -a, --all              display all sections\n".
40
	"  -e, --edit             edit your todo file\n".
41
	"  -h, --headers          show setion headers\n".
42
	"  -s, --section=SECTION  display this named section\n".
43
	"      --help     display this help and exit\n".
44
	"      --version  output version information and exit\n";
45
    exit( 0 );
46
}
47
48
# version mode
49
if( $mode_version ) {
50
    print "todo 1.0\n" .
51
	"Copyright (C) 2011 Tim Marston.\n";
52
    exit( 0 );
53
}
54
55
#_______________________________________________________________________________
56
57
58
# check we have bazaar installed
59
my $output = `which bzr`;
60
chomp $output;
61
$output eq "" and die "Bazaar is not installed";
62
63
# glob todo directory
64
$todo_dir = glob( $todo_dir );
65
( -f $todo_dir ) and die "$todo_dir exists and is a file";
66
67
# edit mode
68
if( $mode_edit )
69
{
70
    # create the todo directory, as necessary
71
	if( ! -d $todo_dir ) {
72
		mkdir $todo_dir or die "couldn't create todo directory";
73
		`bzr init --no-aliases -q "$todo_dir"`;
74
		$? == 0 or die "couldn't init bzr repo";
75
		`> "$todo_dir/todo"`;
76
		$? == 0 or die "couldn't create initial todo file";
77
		`bzr add --no-aliases -q "$todo_dir/todo"`;
78
		$? == 0 or die "couldn't add todo file to bzr repo";
79
	}
80
81
    # determine editor from environment, default to "emacs -nw"
82
    my $editor = $ENV{ 'EDITOR' };
83
    defined $editor or $editor = 'emacs -nw';
84
    my @exec_array = split( / +/, $editor );
85
    push( @exec_array, "$todo_dir/todo" );
86
87
	# detect emacs and try to use markdown-mode
88
	$exec_array[ 0 ] eq "emacs" and push( @exec_array, '--funcall=markdown-mode' );
89
90
    # edit todo file
91
    system( @exec_array );
92
	$? == 0 or die "unable to exec editor";
93
94
	# check for changes and commit it
95
	$output = `bzr status --no-aliases "$todo_dir/todo"`;
96
	$? == 0 or die "couldn't check bzr rerpo status";
97
	chomp $output;
98
	if( $output ne "" ) {
99
		`bzr commit --no-aliases -q -m - "$todo_dir/todo"`;
100
		$? == 0 or die "couldn't commit to bzr repo";
101
	}
102
	
103
	# exit
104
	exit
105
}
106
107
# scan through file
108
my $next_section = '';
109
my $section = '';
110
my $old_section = '';
111
open FILE, "<$todo_dir/todo" or die "can't open todo file";
112
while( <FILE> ) {
113
    my $display = 0;
114
115
    # detect the line after section headings, and thus sections
116
    if( /^[-=]{2,}/ && $next_section ne '' ) {
117
		$section = $next_section;
118
		$next_section = '';
119
    }
120
    # detect section headings
121
    elsif( /^[A-Z]+$/ ) {
122
		$next_section = $_;
123
		chomp( $next_section );
124
    }
125
    # we have neither a section heading nor the line after
126
    else {
127
		$next_section = '';
128
129
		# display line
130
		if( $section eq $display_section ||
131
			$display_all )
132
		{
133
			# detect section change
134
			if( $section ne $old_section ) {
135
				$old_section = $section;
136
				
137
				# display section heading
138
				if( $display_headers ||
139
					$display_all )
140
				{
141
					my $heading = 'TODO';
142
					$heading .= ' ('.lc( $section ).')' if $section ne "IMMEDIATE";
143
					print "$heading\n".
144
						( "=" x length( $heading ) )."\n";
145
				}
146
			}
147
148
			# replace tabs with 4 spaces
149
			s/\t/    /g;
150
151
			# display the line
152
			print;
153
		}
154
    }
155
}