/todo

To get this branch, use:
bzr branch http://bzr.ed.am/todo

« back to all changes in this revision

Viewing changes to todo

  • Committer: edam
  • Date: 2011-09-30 10:20:26 UTC
  • Revision ID: edam@waxworlds.org-20110930102026-8kbh15ufm67eit0k
init

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!/usr/bin/perl
2
2
 
3
 
use feature "state";
4
 
 
5
3
use strict;
6
4
use warnings;
7
5
use Getopt::Long;
13
11
# option defaults
14
12
my $todo_dir = "~/.todo";
15
13
my $display_all = 0;
16
 
my $display_section = "TODO";
 
14
my $display_section = "IMMEDIATE";
17
15
my $display_headers = 0;
18
16
my $mode_edit = 0;
19
17
my $mode_help = 0;
25
23
    'a|all' => \$display_all,
26
24
    'e|edit' => \$mode_edit,
27
25
    'h|headers' => \$display_headers,
28
 
    's|section=s' => \$display_section,
 
26
    'section=s' => \$display_section,
29
27
    'help' => \$mode_help,
30
28
    'version' => \$mode_version,
31
29
) ) {
36
34
# help mode
37
35
if( $mode_help ) {
38
36
    print "todo - display your todo file\n\n".
39
 
    "Usage: $app_name [OPTIONS]\n\n".
40
 
    "Options:\n".
41
 
    "  -a, --all              display all sections\n".
42
 
    "  -e, --edit             edit your todo file\n".
43
 
    "  -h, --headers          show setion headers\n".
44
 
    "  -s, --section=SECTION  display this named section\n".
45
 
    "      --help     display this help and exit\n".
46
 
    "      --version  output version information and exit\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";
47
45
    exit( 0 );
48
46
}
49
47
 
50
48
# version mode
51
49
if( $mode_version ) {
52
 
    print "todo 1.0\n".
53
 
        "Copyright (C) 2011 Tim Marston.\n".
54
 
        "http://ed.am/software/todo\n";
 
50
    print "todo 1.0\n" .
 
51
        "Copyright (C) 2011 Tim Marston.\n";
55
52
    exit( 0 );
56
53
}
57
54
 
71
68
if( $mode_edit )
72
69
{
73
70
    # create the todo directory, as necessary
74
 
    if( ! -d $todo_dir ) {
75
 
        mkdir $todo_dir or die "couldn't create todo directory";
76
 
        `bzr init --no-aliases -q "$todo_dir"`;
77
 
        $? == 0 or die "couldn't init bzr repo";
78
 
    }
79
 
    
80
 
    # create a default todo file, as necessary
81
 
    if( ! -f "$todo_dir/todo" ) {
82
 
        open FILE, ">$todo_dir/todo" or die "couldn't create default todo file";
83
 
        my $content = <<"EOT";
84
 
<!-- This file uses Markdown syntax. For more info about Markdown
85
 
     syntax, see http://daringfireball.net/projects/markdown/syntax.
86
 
 
87
 
     There should be a main H1 header called "TODO" for the main todo
88
 
     list section (one has been added for you below). You can also add
89
 
     as many more sections as you like for other lists. And feel free
90
 
     to delete this comment! -->
91
 
 
92
 
TODO
93
 
====
94
 
 
95
 
* make a list of things to do
96
 
 
97
 
EOT
98
 
        print FILE $content or die "couldn't write default todo file";
99
 
        close FILE;
100
 
        `bzr add --no-aliases -q "$todo_dir/todo"`;
101
 
        $? == 0 or die "couldn't add todo file to bzr repo";
102
 
    }
 
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
        }
103
80
 
104
81
    # determine editor from environment, default to "emacs -nw"
105
82
    my $editor = $ENV{ 'EDITOR' };
107
84
    my @exec_array = split( / +/, $editor );
108
85
    push( @exec_array, "$todo_dir/todo" );
109
86
 
110
 
    # detect emacs and try to use markdown-mode
111
 
    $exec_array[ 0 ] eq "emacs" and
112
 
        push( @exec_array, '--funcall=markdown-mode' );
 
87
        # detect emacs and try to use markdown-mode
 
88
        $exec_array[ 0 ] eq "emacs" and push( @exec_array, '--funcall=markdown-mode' );
113
89
 
114
90
    # edit todo file
115
91
    system( @exec_array );
116
 
    $? == 0 or
117
 
        die "can't start editor, check EDITOR envionment variable";
118
 
 
119
 
    # check for changes and commit it
120
 
    $output = `bzr status --no-aliases "$todo_dir/todo"`;
121
 
    $? == 0 or die "couldn't check bzr rerpo status";
122
 
    chomp $output;
123
 
    if( $output ne "" ) {
124
 
        `bzr commit --no-aliases -q -m - "$todo_dir/todo"`;
125
 
        $? == 0 or die "couldn't commit to bzr repo";
126
 
    }
127
 
 
128
 
    # after editing, exit
129
 
    exit
130
 
}
131
 
 
132
 
# function to display a line
133
 
sub display_line
134
 
{
135
 
        my ( $line, $section ) = @_;
136
 
        state $old_section = '';
137
 
 
138
 
        # detect section change
139
 
        if( $section ne $old_section ) {
140
 
                $old_section = $section;
141
 
                
142
 
                # display section heading
143
 
                if( $display_headers || $display_all ) {
144
 
                        print "$section\n".
145
 
                                ( "=" x length( $section ) )."\n";
146
 
                }
 
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";
147
101
        }
148
 
 
149
 
        # replace tabs with 4 spaces
150
 
        $line =~ s/\t/    /g;
151
102
        
152
 
        # display the line
153
 
        print $line;
 
103
        # exit
 
104
        exit
154
105
}
155
106
 
156
 
 
157
107
# scan through file
158
 
my $candidate_section = '';
 
108
my $next_section = '';
159
109
my $section = '';
160
 
my $last_line = '';
 
110
my $old_section = '';
161
111
open FILE, "<$todo_dir/todo" or die "can't open todo file";
162
 
while( <FILE> )
163
 
{
 
112
while( <FILE> ) {
 
113
    my $display = 0;
 
114
 
164
115
    # detect the line after section headings, and thus sections
165
 
    if( /^[-=]{2,}/ && $candidate_section ne '' ) {
166
 
        $section = $candidate_section;
167
 
        $candidate_section = '';
168
 
                $last_line = '';
169
 
                next;
 
116
    if( /^[-=]{2,}/ && $next_section ne '' ) {
 
117
                $section = $next_section;
 
118
                $next_section = '';
170
119
    }
171
 
 
172
120
    # detect section headings
173
 
    if( /^[-_\.A-Za-z0-9 ]+$/ ) {
174
 
        $candidate_section = $_;
175
 
                chomp $candidate_section;
176
 
        }
 
121
    elsif( /^[A-Z]+$/ ) {
 
122
                $next_section = $_;
 
123
                chomp( $next_section );
 
124
    }
 
125
    # we have neither a section heading nor the line after
177
126
    else {
178
 
        $candidate_section = '';
179
 
        }
180
 
 
181
 
        # display last line
182
 
        display_line( $last_line, $section ) if( $last_line ne '' );
183
 
 
184
 
    # display line
185
 
        if( ( lc( $section ) eq lc( $display_section ) ) ||
186
 
                ( $section && $display_all ) )
187
 
        {
188
 
                $last_line = $_;
 
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
                }
189
154
    }
190
 
        else {
191
 
                $last_line = '';
192
 
        }
193
155
}
194
 
display_line( $last_line, $section ) if( $last_line ne '' );