/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: 2012-03-12 14:07:28 UTC
  • Revision ID: tim@ed.am-20120312140728-nv11dg8zapxs9gtj
added --list

Show diffs side-by-side

added added

removed removed

1
1
#!/usr/bin/perl
2
2
 
 
3
use feature "state";
 
4
 
3
5
use strict;
4
6
use warnings;
5
7
use Getopt::Long;
14
16
my $display_section = "TODO";
15
17
my $display_headers = 0;
16
18
my $mode_edit = 0;
 
19
my $mode_less = 0;
17
20
my $mode_help = 0;
18
21
my $mode_version = 0;
19
22
 
23
26
    'a|all' => \$display_all,
24
27
    'e|edit' => \$mode_edit,
25
28
    'h|headers' => \$display_headers,
26
 
    'section=s' => \$display_section,
 
29
        'l|list' => \$mode_less,
 
30
    's|section=s' => \$display_section,
27
31
    'help' => \$mode_help,
28
32
    'version' => \$mode_version,
29
33
) ) {
34
38
# help mode
35
39
if( $mode_help ) {
36
40
    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";
 
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";
45
58
    exit( 0 );
46
59
}
47
60
 
48
61
# version mode
49
62
if( $mode_version ) {
50
63
    print "todo 1.0\n".
51
 
                "Copyright (C) 2011 Tim Marston.\n".
52
 
                "http://ed.am/software/todo\n";
 
64
        "Copyright (C) 2011, 2012 Tim Marston.\n".
 
65
        "http://ed.am/software/todo\n";
53
66
    exit( 0 );
54
67
}
55
68
 
65
78
$todo_dir = glob( $todo_dir );
66
79
( -f $todo_dir ) and die "$todo_dir exists and is a file";
67
80
 
 
81
# less mode
 
82
if( $mode_less )
 
83
{
 
84
    ( ! -f "$todo_dir/todo" ) && die "no todo file";
 
85
        $mode_edit = 1;
 
86
}
 
87
 
68
88
# edit mode
69
89
if( $mode_edit )
70
90
{
71
91
    # 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";
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";
 
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";
82
102
<!-- This file uses Markdown syntax. For more info about Markdown
83
103
     syntax, see http://daringfireball.net/projects/markdown/syntax.
84
104
 
94
114
 
95
115
EOT
96
116
        print FILE $content or die "couldn't write default todo file";
97
 
                close FILE;
98
 
                `bzr add --no-aliases -q "$todo_dir/todo"`;
99
 
                $? == 0 or die "couldn't add todo file to bzr repo";
100
 
        }
 
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
    }
101
121
 
102
122
    # determine editor from environment, default to "emacs -nw"
103
 
    my $editor = $ENV{ 'EDITOR' };
104
 
    defined $editor or $editor = '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
        }
105
132
    my @exec_array = split( / +/, $editor );
106
133
    push( @exec_array, "$todo_dir/todo" );
107
134
 
108
 
        # detect emacs and try to use markdown-mode
109
 
        $exec_array[ 0 ] eq "emacs" and
110
 
                push( @exec_array, '--funcall=markdown-mode' );
 
135
    # detect emacs and try to use markdown-mode
 
136
    $exec_array[ 0 ] eq "emacs" and
 
137
        push( @exec_array, '--funcall=markdown-mode' );
111
138
 
112
139
    # edit todo file
113
140
    system( @exec_array );
114
 
        $? == 0 or
115
 
                die "can't start editor, check EDITOR envionment variable";
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";
 
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
                }
124
172
        }
125
173
 
126
 
        # after editing, exit
127
 
        exit
 
174
        # replace tabs with 4 spaces
 
175
        $line =~ s/\t/    /g;
 
176
        
 
177
        # display the line
 
178
        print $line;
128
179
}
129
180
 
 
181
 
130
182
# scan through file
131
 
my $next_section = '';
 
183
my $candidate_section = '';
132
184
my $section = '';
133
 
my $old_section = '';
 
185
my $last_line = '';
134
186
open FILE, "<$todo_dir/todo" or die "can't open todo file";
135
 
while( <FILE> ) {
136
 
    my $display = 0;
137
 
 
 
187
while( <FILE> )
 
188
{
138
189
    # detect the line after section headings, and thus sections
139
 
    if( /^[-=]{2,}/ && $next_section ne '' ) {
140
 
                $section = $next_section;
141
 
                $next_section = '';
 
190
    if( /^[-=]{2,}/ && $candidate_section ne '' ) {
 
191
        $section = $candidate_section;
 
192
        $candidate_section = '';
 
193
                $last_line = '';
 
194
                next;
142
195
    }
 
196
 
143
197
    # 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
 
198
    if( /^[-_\.A-Za-z0-9 ]+$/ ) {
 
199
        $candidate_section = $_;
 
200
                chomp $candidate_section;
 
201
        }
149
202
    else {
150
 
                $next_section = '';
151
 
 
152
 
                # display line
153
 
                if( ( $section eq $display_section ) ||
154
 
                        ( $section && $display_all ) )
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
 
                                {
164
 
                                        print "$section\n".
165
 
                                                ( "=" x length( $section ) )."\n";
166
 
                                }
167
 
                        }
168
 
 
169
 
                        # replace tabs with 4 spaces
170
 
                        s/\t/    /g;
171
 
 
172
 
                        # display the line
173
 
                        print;
174
 
                }
 
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 = $_;
175
214
    }
 
215
        else {
 
216
                $last_line = '';
 
217
        }
176
218
}
 
219
display_line( $last_line, $section ) if( $last_line ne '' );