/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-08-01 19:54:49 UTC
  • Revision ID: tim@ed.am-20120801195449-fcyrejq9aazxa5l5
detect extra arguments and extend --help message

Show diffs side-by-side

added added

removed removed

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