/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-12-10 20:46:56 UTC
  • Revision ID: edam@waxworlds.org-20111210204656-ivc37tya904ogje5
fixed version info and error about failing to start the editor

Show diffs side-by-side

added added

removed removed

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;
16
14
my $display_section = "TODO";
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
50
    print "todo 1.0\n".
64
 
        "Copyright (C) 2011, 2012 Tim Marston.\n".
65
 
        "http://ed.am/software/todo\n";
 
51
                "Copyright (C) 2011 Tim Marston.\n".
 
52
                "http://ed.am/software/todo\n";
66
53
    exit( 0 );
67
54
}
68
55
 
78
65
$todo_dir = glob( $todo_dir );
79
66
( -f $todo_dir ) and die "$todo_dir exists and is a file";
80
67
 
81
 
# less mode
82
 
if( $mode_less )
83
 
{
84
 
    ( ! -f "$todo_dir/todo" ) && die "no todo file";
85
 
        $mode_edit = 1;
86
 
}
87
 
 
88
68
# edit mode
89
69
if( $mode_edit )
90
70
{
91
71
    # 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";
 
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";
102
82
<!-- This file uses Markdown syntax. For more info about Markdown
103
83
     syntax, see http://daringfireball.net/projects/markdown/syntax.
104
84
 
114
94
 
115
95
EOT
116
96
        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
 
    }
 
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
        }
121
101
 
122
102
    # 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
 
        }
 
103
    my $editor = $ENV{ 'EDITOR' };
 
104
    defined $editor or $editor = 'emacs -nw';
132
105
    my @exec_array = split( / +/, $editor );
133
106
    push( @exec_array, "$todo_dir/todo" );
134
107
 
135
 
    # detect emacs and try to use markdown-mode
136
 
    $exec_array[ 0 ] eq "emacs" and
137
 
        push( @exec_array, '--funcall=markdown-mode' );
 
108
        # detect emacs and try to use markdown-mode
 
109
        $exec_array[ 0 ] eq "emacs" and
 
110
                push( @exec_array, '--funcall=markdown-mode' );
138
111
 
139
112
    # edit todo file
140
113
    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
 
                }
 
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";
172
124
        }
173
125
 
174
 
        # replace tabs with 4 spaces
175
 
        $line =~ s/\t/    /g;
176
 
        
177
 
        # display the line
178
 
        print $line;
 
126
        # after editing, exit
 
127
        exit
179
128
}
180
129
 
181
 
 
182
130
# scan through file
183
 
my $candidate_section = '';
 
131
my $next_section = '';
184
132
my $section = '';
185
 
my $last_line = '';
 
133
my $old_section = '';
186
134
open FILE, "<$todo_dir/todo" or die "can't open todo file";
187
 
while( <FILE> )
188
 
{
 
135
while( <FILE> ) {
 
136
    my $display = 0;
 
137
 
189
138
    # 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;
 
139
    if( /^[-=]{2,}/ && $next_section ne '' ) {
 
140
                $section = $next_section;
 
141
                $next_section = '';
195
142
    }
196
 
 
197
143
    # detect section headings
198
 
    if( /^[-_\.A-Za-z0-9 ]+$/ ) {
199
 
        $candidate_section = $_;
200
 
                chomp $candidate_section;
201
 
        }
 
144
    elsif( /^[A-Z]+$/ ) {
 
145
                $next_section = $_;
 
146
                chomp( $next_section );
 
147
    }
 
148
    # we have neither a section heading nor the line after
202
149
    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 = $_;
 
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
                }
214
175
    }
215
 
        else {
216
 
                $last_line = '';
217
 
        }
218
176
}
219
 
display_line( $last_line, $section ) if( $last_line ne '' );