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