/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:57:56 UTC
  • Revision ID: tim@ed.am-20120801195756-qaxahzf9sikcbv6e
removed --list option because it was confusing and unnecessary

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