/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;
2 by edam
added default todo file content and changed main todo section name to "TODO"
14
my $display_section = "TODO";
1 by edam
init
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";
2 by edam
added default todo file content and changed main todo section name to "TODO"
75
	}
76
	
77
	# create a default todo file, as necessary
78
	if( ! -f "$todo_dir/todo" ) {
79
		open FILE, ">$todo_dir/todo" or die "couldn't create default todo file";
80
		my $content = <<"EOT";
81
<!-- This file uses Markdown syntax. For more info about Markdown
82
     syntax, see http://daringfireball.net/projects/markdown/syntax.
83
84
     There should be a main H1 header called "TODO" for the main todo
85
     list section (one has been added for you below). You can also add
86
     as many more sections as you like for other lists. And feel free
87
     to delete this comment! -->
88
89
TODO
90
====
91
92
* make a list of things to do
93
94
EOT
95
        print FILE $content or die "couldn't write default todo file";
96
		close FILE;
1 by edam
init
97
		`bzr add --no-aliases -q "$todo_dir/todo"`;
98
		$? == 0 or die "couldn't add todo file to bzr repo";
99
	}
100
101
    # determine editor from environment, default to "emacs -nw"
102
    my $editor = $ENV{ 'EDITOR' };
103
    defined $editor or $editor = 'emacs -nw';
104
    my @exec_array = split( / +/, $editor );
105
    push( @exec_array, "$todo_dir/todo" );
106
107
	# detect emacs and try to use markdown-mode
2 by edam
added default todo file content and changed main todo section name to "TODO"
108
	$exec_array[ 0 ] eq "emacs" and
109
		push( @exec_array, '--funcall=markdown-mode' );
1 by edam
init
110
111
    # edit todo file
112
    system( @exec_array );
113
	$? == 0 or die "unable to exec editor";
114
115
	# check for changes and commit it
116
	$output = `bzr status --no-aliases "$todo_dir/todo"`;
117
	$? == 0 or die "couldn't check bzr rerpo status";
118
	chomp $output;
119
	if( $output ne "" ) {
120
		`bzr commit --no-aliases -q -m - "$todo_dir/todo"`;
121
		$? == 0 or die "couldn't commit to bzr repo";
122
	}
2 by edam
added default todo file content and changed main todo section name to "TODO"
123
124
	# after editing, exit
1 by edam
init
125
	exit
126
}
127
128
# scan through file
129
my $next_section = '';
130
my $section = '';
131
my $old_section = '';
132
open FILE, "<$todo_dir/todo" or die "can't open todo file";
133
while( <FILE> ) {
134
    my $display = 0;
135
136
    # detect the line after section headings, and thus sections
137
    if( /^[-=]{2,}/ && $next_section ne '' ) {
138
		$section = $next_section;
139
		$next_section = '';
140
    }
141
    # detect section headings
142
    elsif( /^[A-Z]+$/ ) {
143
		$next_section = $_;
144
		chomp( $next_section );
145
    }
146
    # we have neither a section heading nor the line after
147
    else {
148
		$next_section = '';
149
150
		# display line
2 by edam
added default todo file content and changed main todo section name to "TODO"
151
		if( ( $section eq $display_section ) ||
152
			( $section && $display_all ) )
1 by edam
init
153
		{
154
			# detect section change
155
			if( $section ne $old_section ) {
156
				$old_section = $section;
157
				
158
				# display section heading
159
				if( $display_headers ||
160
					$display_all )
161
				{
2 by edam
added default todo file content and changed main todo section name to "TODO"
162
					print "$section\n".
163
						( "=" x length( $section ) )."\n";
1 by edam
init
164
				}
165
			}
166
167
			# replace tabs with 4 spaces
168
			s/\t/    /g;
169
170
			# display the line
171
			print;
172
		}
173
    }
174
}