/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
 
my $mode_less = 0;
20
17
my $mode_help = 0;
21
18
my $mode_version = 0;
22
19
 
26
23
    'a|all' => \$display_all,
27
24
    'e|edit' => \$mode_edit,
28
25
    'h|headers' => \$display_headers,
29
 
        'l|list' => \$mode_less,
30
 
    's|section=s' => \$display_section,
 
26
    'section=s' => \$display_section,
31
27
    'help' => \$mode_help,
32
28
    'version' => \$mode_version,
33
29
) ) {
38
34
# help mode
39
35
if( $mode_help ) {
40
36
    print "todo - display your todo file\n\n".
41
 
    "Usage: $app_name [OPTIONS]\n\n".
42
 
    "Options:\n".
43
 
    "  -a, --all              display all sections\n".
44
 
    "  -e, --edit             edit your todo file\n".
45
 
    "  -h, --headers          show setion headers\n".
46
 
        "  -l, --list             show the list in your pager (see notes)\n".
47
 
    "  -s, --section=SECTION  display this named section\n".
48
 
    "      --help     display this help and exit\n".
49
 
    "      --version  output version information and exit\n".
50
 
        "\n".
51
 
        "The advantage of using '--list' is that the pager is run as if the\n".
52
 
        "todo list were being edited. This means that if you decide to spawn an\n".
53
 
        "editor from you pager and edit the list, these changes get noticed.\n".
54
 
        "\n".
55
 
        "The environment variables EDITOR and PAGER are used.\n".
56
 
        "\n".
57
 
        "Please report bugs to Tim Marston <tim\@ed.am>.\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";
58
45
    exit( 0 );
59
46
}
60
47
 
61
48
# version mode
62
49
if( $mode_version ) {
63
 
    print "todo 1.0\n".
64
 
        "Copyright (C) 2011, 2012 Tim Marston.\n".
65
 
        "http://ed.am/software/todo\n";
 
50
    print "todo 1.0\n" .
 
51
        "Copyright (C) 2011 Tim Marston.\n";
66
52
    exit( 0 );
67
53
}
68
54
 
78
64
$todo_dir = glob( $todo_dir );
79
65
( -f $todo_dir ) and die "$todo_dir exists and is a file";
80
66
 
81
 
# less mode
82
 
if( $mode_less )
83
 
{
84
 
    ( ! -f "$todo_dir/todo" ) && die "no todo file";
85
 
        $mode_edit = 1;
86
 
}
87
 
 
88
67
# edit mode
89
68
if( $mode_edit )
90
69
{
91
70
    # create the todo directory, as necessary
92
 
    if( ! -d $todo_dir ) {
93
 
        mkdir $todo_dir or die "couldn't create todo directory";
94
 
        `bzr init --no-aliases -q "$todo_dir"`;
95
 
        $? == 0 or die "couldn't init bzr repo";
96
 
    }
97
 
    
98
 
    # create a default todo file, as necessary
99
 
    if( ! -f "$todo_dir/todo" ) {
100
 
        open FILE, ">$todo_dir/todo" or die "couldn't create default todo file";
101
 
        my $content = <<"EOT";
102
 
<!-- This file uses Markdown syntax. For more info about Markdown
103
 
     syntax, see http://daringfireball.net/projects/markdown/syntax.
104
 
 
105
 
     There should be a main H1 header called "TODO" for the main todo
106
 
     list section (one has been added for you below). You can also add
107
 
     as many more sections as you like for other lists. And feel free
108
 
     to delete this comment! -->
109
 
 
110
 
TODO
111
 
====
112
 
 
113
 
* make a list of things to do
114
 
 
115
 
EOT
116
 
        print FILE $content or die "couldn't write default todo file";
117
 
        close FILE;
118
 
        `bzr add --no-aliases -q "$todo_dir/todo"`;
119
 
        $? == 0 or die "couldn't add todo file to bzr repo";
120
 
    }
 
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
        }
121
80
 
122
81
    # determine editor from environment, default to "emacs -nw"
123
 
        my $editor;
124
 
        if( $mode_less ) {
125
 
                $editor = $ENV{ 'PAGER' };
126
 
                defined $editor or $editor = 'less';
127
 
        }
128
 
        else {
129
 
                $editor = $ENV{ 'EDITOR' };
130
 
                defined $editor or $editor = 'emacs -nw';
131
 
        }
 
82
    my $editor = $ENV{ 'EDITOR' };
 
83
    defined $editor or $editor = 'emacs -nw';
132
84
    my @exec_array = split( / +/, $editor );
133
85
    push( @exec_array, "$todo_dir/todo" );
134
86
 
135
 
    # detect emacs and try to use markdown-mode
136
 
    $exec_array[ 0 ] eq "emacs" and
137
 
        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' );
138
89
 
139
90
    # edit todo file
140
91
    system( @exec_array );
141
 
    $? == 0 or
142
 
        die "can't start editor, check EDITOR envionment variable";
143
 
 
144
 
    # check for changes and commit it
145
 
    $output = `bzr status --no-aliases "$todo_dir/todo"`;
146
 
    $? == 0 or die "couldn't check bzr rerpo status";
147
 
    chomp $output;
148
 
    if( $output ne "" ) {
149
 
        `bzr commit --no-aliases -q -m - "$todo_dir/todo"`;
150
 
        $? == 0 or die "couldn't commit to bzr repo";
151
 
    }
152
 
 
153
 
    # after editing, exit
154
 
    exit
155
 
}
156
 
 
157
 
# function to display a line
158
 
sub display_line
159
 
{
160
 
        my ( $line, $section ) = @_;
161
 
        state $old_section = '';
162
 
 
163
 
        # detect section change
164
 
        if( $section ne $old_section ) {
165
 
                $old_section = $section;
166
 
                
167
 
                # display section heading
168
 
                if( $display_headers || $display_all ) {
169
 
                        print "$section\n".
170
 
                                ( "=" x length( $section ) )."\n";
171
 
                }
 
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";
172
101
        }
173
 
 
174
 
        # replace tabs with 4 spaces
175
 
        $line =~ s/\t/    /g;
176
102
        
177
 
        # display the line
178
 
        print $line;
 
103
        # exit
 
104
        exit
179
105
}
180
106
 
181
 
 
182
107
# scan through file
183
 
my $candidate_section = '';
 
108
my $next_section = '';
184
109
my $section = '';
185
 
my $last_line = '';
 
110
my $old_section = '';
186
111
open FILE, "<$todo_dir/todo" or die "can't open todo file";
187
 
while( <FILE> )
188
 
{
 
112
while( <FILE> ) {
 
113
    my $display = 0;
 
114
 
189
115
    # detect the line after section headings, and thus sections
190
 
    if( /^[-=]{2,}/ && $candidate_section ne '' ) {
191
 
        $section = $candidate_section;
192
 
        $candidate_section = '';
193
 
                $last_line = '';
194
 
                next;
 
116
    if( /^[-=]{2,}/ && $next_section ne '' ) {
 
117
                $section = $next_section;
 
118
                $next_section = '';
195
119
    }
196
 
 
197
120
    # detect section headings
198
 
    if( /^[-_\.A-Za-z0-9 ]+$/ ) {
199
 
        $candidate_section = $_;
200
 
                chomp $candidate_section;
201
 
        }
 
121
    elsif( /^[A-Z]+$/ ) {
 
122
                $next_section = $_;
 
123
                chomp( $next_section );
 
124
    }
 
125
    # we have neither a section heading nor the line after
202
126
    else {
203
 
        $candidate_section = '';
204
 
        }
205
 
 
206
 
        # display last line
207
 
        display_line( $last_line, $section ) if( $last_line ne '' );
208
 
 
209
 
    # display line
210
 
        if( ( lc( $section ) eq lc( $display_section ) ) ||
211
 
                ( $section && $display_all ) )
212
 
        {
213
 
                $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
                }
214
154
    }
215
 
        else {
216
 
                $last_line = '';
217
 
        }
218
155
}
219
 
display_line( $last_line, $section ) if( $last_line ne '' );