todorb 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +5 -0
- data/Makefile +3 -2
- data/Rakefile +12 -2
- data/VERSION +1 -1
- data/lib/common/cmdapp.rb +41 -8
- data/lib/common/sed.rb +9 -6
- data/lib/todorb.rb +309 -144
- data/tests/data.1 +14 -0
- data/tests/data.2 +7 -0
- data/tests/rtest2.sh +11 -6
- data/tests/t0001-help.sh +97 -0
- data/tests/t0002-subc_help.sh +41 -0
- data/tests/t0003-add.sh +19 -0
- data/tests/{t0002-listing.sh → t0004-list.sh} +6 -5
- data/tests/t0005-pri.sh +43 -0
- data/tests/t0006-pri_sort.sh +55 -0
- data/tests/t0007-status.sh +78 -0
- data/tests/t0008-addsub.sh +78 -0
- data/tests/t0009-del.sh +43 -0
- data/tests/test-lib.sh +13 -9
- data/todorb.gemspec +18 -6
- metadata +29 -9
- data/tests/t0001-add.sh +0 -22
data/lib/todorb.rb
CHANGED
@@ -4,7 +4,8 @@
|
|
4
4
|
* Description: a command line todo list manager
|
5
5
|
* Author: rkumar
|
6
6
|
* Date: 2010-06-10 20:10
|
7
|
-
* License:
|
7
|
+
* License: Ruby License
|
8
|
+
* Now requires subcommand gem as of 2010-06-22 16:16
|
8
9
|
|
9
10
|
=end
|
10
11
|
require 'rubygems'
|
@@ -12,15 +13,17 @@ require 'rubygems'
|
|
12
13
|
require 'common/colorconstants'
|
13
14
|
require 'common/sed'
|
14
15
|
require 'common/cmdapp'
|
16
|
+
require 'subcommand'
|
15
17
|
include ColorConstants
|
16
18
|
include Sed
|
17
19
|
include Cmdapp
|
20
|
+
include Subcommands
|
18
21
|
|
19
22
|
PRI_A = YELLOW + BOLD
|
20
23
|
PRI_B = WHITE + BOLD
|
21
24
|
PRI_C = GREEN + BOLD
|
22
25
|
PRI_D = CYAN + BOLD
|
23
|
-
VERSION = "
|
26
|
+
VERSION = "1.0.0"
|
24
27
|
DATE = "2010-06-10"
|
25
28
|
APPNAME = File.basename($0)
|
26
29
|
AUTHOR = "rkumar"
|
@@ -59,7 +62,6 @@ class Todo
|
|
59
62
|
def initialize options, argv
|
60
63
|
|
61
64
|
@options = options
|
62
|
-
@aliases = {}
|
63
65
|
@argv = argv
|
64
66
|
@file = options[:file]
|
65
67
|
## data is a 2 dim array: rows and fields. It contains each row of the file
|
@@ -86,29 +88,28 @@ class Todo
|
|
86
88
|
$valid_array = false
|
87
89
|
# menu MENU
|
88
90
|
#@actions = %w[ list add pri priority depri tag del delete status redo note archive help]
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
91
|
+
#@actions = {}
|
92
|
+
#@actions["list"] = "List all tasks.\n\t --hide-numbering --renumber"
|
93
|
+
#@actions["listsub"] = "List all tasks.\n\t --hide-numbering --renumber"
|
94
|
+
#@actions["add"] = "Add a task. \n\t #{$APPNAME} add <TEXT>\n\t --component C --project P --priority X add <TEXT>"
|
95
|
+
#@actions["pri"] = "Add priority to task. \n\t #{$APPNAME} pri <TASK> [A-Z]"
|
96
|
+
#@actions["priority"] = "Same as pri"
|
97
|
+
#@actions["depri"] = "Remove priority of task. \n\t #{$APPNAME} depri <TASK>"
|
98
|
+
#@actions["delete"] = "Delete a task. \n\t #{$APPNAME} delete <TASK>"
|
99
|
+
#@actions["del"] = "Same as delete"
|
100
|
+
#@actions["status"] = "Change the status of a task. \n\t #{$APPNAME} status <STAT> <TASK>\n\t<STAT> are open closed started pending hold next"
|
101
|
+
#@actions["redo"] = "Renumbers the todo file starting 1"
|
102
|
+
#@actions["note"] = "Add a note to an item. \n\t #{$APPNAME} note <TASK> <TEXT>"
|
103
|
+
#@actions["tag"] = "Add a tag to an item/s. \n\t #{$APPNAME} tag <TASK> <TEXT>"
|
104
|
+
#@actions["archive"] = "archive closed tasks to archive.txt"
|
105
|
+
#@actions["copyunder"] = "Move first item under second (as a subtask). aka cu"
|
106
|
+
#
|
107
|
+
#@actions["help"] = "Display help"
|
108
|
+
#@actions["addsub"] = "Add a task under another . \n\t #{$APPNAME} add <TEXT>\n\t --component C --project P --priority X add <TEXT>"
|
107
109
|
|
108
110
|
# adding some sort of aliases so shortcuts can be defined
|
109
|
-
|
110
|
-
|
111
|
-
@aliases["cu"] = ["copyunder"]
|
111
|
+
#@aliases["open"] = ["status","open"]
|
112
|
+
#@aliases["close"] = ["status","closed"]
|
112
113
|
|
113
114
|
@copying = false # used by copyunder when it calls addsub
|
114
115
|
# TODO: config
|
@@ -147,8 +148,9 @@ class Todo
|
|
147
148
|
##
|
148
149
|
# add a subtask
|
149
150
|
# @param [Array] 1. item under which to place, 2. text
|
150
|
-
# @return
|
151
|
-
#
|
151
|
+
# @return [0,1] success or fail
|
152
|
+
#
|
153
|
+
# @example
|
152
154
|
# addsub 1 "A task"
|
153
155
|
# => will get added as 1.1 or 1.2 etc
|
154
156
|
# addsub 1.3 "a task"
|
@@ -232,16 +234,20 @@ class Todo
|
|
232
234
|
@ctr = 0
|
233
235
|
@total = 0
|
234
236
|
#CSV.foreach(@file,:col_sep => "\t") do |row| # 1.9 2009-10-05 11:12
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
@
|
241
|
-
|
242
|
-
unless row[1] =~ /^\[x\]/
|
237
|
+
filelist = [@file]
|
238
|
+
filelist << @archive_path if @options[:show_arch]
|
239
|
+
filelist.each do |file|
|
240
|
+
File.open(file).each do |line|
|
241
|
+
row = line.chomp.split "\t"
|
242
|
+
@total += 1
|
243
|
+
if @options[:show_all]
|
243
244
|
@data << row
|
244
245
|
@ctr += 1
|
246
|
+
else
|
247
|
+
unless row[1] =~ /^\[x\]/
|
248
|
+
@data << row
|
249
|
+
@ctr += 1
|
250
|
+
end
|
245
251
|
end
|
246
252
|
end
|
247
253
|
end
|
@@ -325,7 +331,8 @@ class Todo
|
|
325
331
|
#string = "#{BLUE}#{string}#{CLEAR}"
|
326
332
|
end
|
327
333
|
else
|
328
|
-
string = "#{NORMAL}#{string}#{CLEAR}"
|
334
|
+
#string = "#{NORMAL}#{string}#{CLEAR}"
|
335
|
+
# no need to put clear, let it be au natural
|
329
336
|
end
|
330
337
|
end # colorme
|
331
338
|
## since we've added notes, we convert C-a to newline with spaces
|
@@ -335,8 +342,15 @@ class Todo
|
|
335
342
|
puts string
|
336
343
|
end
|
337
344
|
end
|
345
|
+
# internal method for sorting on reverse of line (status, priority)
|
338
346
|
def sort
|
339
|
-
|
347
|
+
fold_subtasks
|
348
|
+
if @options[:reverse]
|
349
|
+
@data.sort! { |a,b| a[1] <=> b[1] }
|
350
|
+
else
|
351
|
+
@data.sort! { |a,b| b[1] <=> a[1] }
|
352
|
+
end
|
353
|
+
unfold_subtasks
|
340
354
|
end
|
341
355
|
def grep
|
342
356
|
r = Regexp.new @options[:grep]
|
@@ -347,8 +361,8 @@ class Todo
|
|
347
361
|
# Adds or changes priority for a task
|
348
362
|
#
|
349
363
|
# @param [Array] priority, single char A-Z, item or items
|
350
|
-
# @return
|
351
|
-
# @example
|
364
|
+
# @return [0,1] success or fail
|
365
|
+
# @example
|
352
366
|
# pri A 5 6 7
|
353
367
|
# pri 5 6 7 A
|
354
368
|
# -- NO LONGER this complicated system pri A 5 6 7 B 1 2 3
|
@@ -400,7 +414,7 @@ class Todo
|
|
400
414
|
# Remove the priority of a task
|
401
415
|
#
|
402
416
|
# @param [Array] items to deprioritize
|
403
|
-
# @return
|
417
|
+
# @return [0,1] success or fail
|
404
418
|
def depri(args)
|
405
419
|
change_items args, /\([A-Z]\) /,""
|
406
420
|
end
|
@@ -409,7 +423,7 @@ class Todo
|
|
409
423
|
# FIXME: check with subtasks
|
410
424
|
#
|
411
425
|
# @param [Array] items and tag, or tag and items
|
412
|
-
# @return
|
426
|
+
# @return [0,1] success or fail
|
413
427
|
def tag(args)
|
414
428
|
tag, items = _separate args
|
415
429
|
#change_items items do |item, row|
|
@@ -422,8 +436,7 @@ class Todo
|
|
422
436
|
# deletes one or more items
|
423
437
|
#
|
424
438
|
# @param [Array, #include?] items to delete
|
425
|
-
# @return
|
426
|
-
# FIXME: if invalid item passed I have no way of giving error
|
439
|
+
# @return [0,1] success or fail
|
427
440
|
public
|
428
441
|
def delete(args)
|
429
442
|
ctr = errors = 0
|
@@ -454,10 +467,24 @@ class Todo
|
|
454
467
|
end
|
455
468
|
end
|
456
469
|
totalitems.each { |item|
|
470
|
+
# FIXME: TODO: if --force used then don'y prompt
|
457
471
|
puts "#{item[0]} #{item[1]}"
|
458
|
-
|
459
|
-
|
460
|
-
|
472
|
+
ans = nil
|
473
|
+
if @options[:force]
|
474
|
+
ans = "Y"
|
475
|
+
else
|
476
|
+
$stderr.print "Do you wish to delete (Y/N/A/q): "
|
477
|
+
STDOUT.flush
|
478
|
+
ans = STDIN.gets.chomp
|
479
|
+
# A means user specified ALL, don't keep asking
|
480
|
+
if ans =~ /[Aa]/
|
481
|
+
ans = "Y"
|
482
|
+
@options[:force] = true
|
483
|
+
elsif ans =~ /[qQ]/
|
484
|
+
$stderr.puts "Operation canceled. No tasks deleted."
|
485
|
+
exit 1
|
486
|
+
end
|
487
|
+
end
|
461
488
|
if ans =~ /[Yy]/
|
462
489
|
@data.delete item
|
463
490
|
# put deleted row into deleted file, so one can undo
|
@@ -479,7 +506,7 @@ class Todo
|
|
479
506
|
# Change status of given items
|
480
507
|
#
|
481
508
|
# @param [Array, #include?] items to change status of
|
482
|
-
# @return [
|
509
|
+
# @return [0,1] success or fail
|
483
510
|
public
|
484
511
|
def status(args)
|
485
512
|
stat, items = _separate args #, /^[a-zA-Z]/
|
@@ -530,7 +557,7 @@ class Todo
|
|
530
557
|
end
|
531
558
|
##
|
532
559
|
# Renumber while displaying
|
533
|
-
# @return [
|
560
|
+
# @return [0,1] success or fail
|
534
561
|
private
|
535
562
|
def renumber
|
536
563
|
## this did not account for subtasks
|
@@ -556,7 +583,7 @@ class Todo
|
|
556
583
|
# For given items, add a note
|
557
584
|
#
|
558
585
|
# @param [Array, #include?] items to add note to, note
|
559
|
-
# @return [
|
586
|
+
# @return [0, 1] success or fail
|
560
587
|
public
|
561
588
|
def note(args)
|
562
589
|
_backup
|
@@ -567,12 +594,13 @@ class Todo
|
|
567
594
|
ret = row[1].sub!(/ (\([0-9]{4})/," #{indent}* #{text} "+'\1')
|
568
595
|
ret
|
569
596
|
end
|
597
|
+
0
|
570
598
|
end
|
571
599
|
##
|
572
|
-
# Archive all items
|
600
|
+
# Archive all closed items
|
573
601
|
#
|
574
602
|
# @param none (ignored)
|
575
|
-
# @return [
|
603
|
+
# @return [0, 1] success or fail
|
576
604
|
public
|
577
605
|
def archive(args=nil)
|
578
606
|
filename = @archive_path
|
@@ -588,11 +616,12 @@ class Todo
|
|
588
616
|
end
|
589
617
|
file.close
|
590
618
|
puts "Archived #{ctr} tasks."
|
619
|
+
0
|
591
620
|
end
|
592
621
|
# Copy given item under second item
|
593
622
|
#
|
594
623
|
# @param [Array] 2 items, move first under second
|
595
|
-
# @return [
|
624
|
+
# @return [0,1] success or fail
|
596
625
|
public
|
597
626
|
def copyunder(args)
|
598
627
|
if args.nil? or args.count != 2
|
@@ -616,8 +645,8 @@ class Todo
|
|
616
645
|
# remove item number and status ?
|
617
646
|
# give to addsub to add.
|
618
647
|
# delete from
|
619
|
-
|
620
|
-
|
648
|
+
# The earlier todoapp.sh was not deleting, so we don't. We just copy
|
649
|
+
delete_item(from) if @options[:delete_old]
|
621
650
|
end
|
622
651
|
##
|
623
652
|
# Get row for given item or nil.
|
@@ -740,7 +769,7 @@ class Todo
|
|
740
769
|
def regexp_item item
|
741
770
|
Regexp.new("^ +#{item}#{@todo_delim}")
|
742
771
|
end
|
743
|
-
#
|
772
|
+
# unused - wrote so i could use it refactoring - i should be using this TODO:
|
744
773
|
def extract_item line
|
745
774
|
item = line.match(/^ *([0-9\.]+)/)
|
746
775
|
return nil if item.nil?
|
@@ -749,6 +778,7 @@ class Todo
|
|
749
778
|
##
|
750
779
|
# Redoes the numbering in the file.
|
751
780
|
# Useful if the numbers have gone high and you want to start over.
|
781
|
+
# @return [0,1] success or fail
|
752
782
|
def redo args
|
753
783
|
#require 'fileutils'
|
754
784
|
#FileUtils.cp @app_file_path, "#{@app_file_path}.org"
|
@@ -771,8 +801,9 @@ class Todo
|
|
771
801
|
line.sub!(/[0-9]+\./, "#{ctr}.")
|
772
802
|
end
|
773
803
|
end
|
774
|
-
_set_serial_number ctr
|
804
|
+
_set_serial_number ctr+1
|
775
805
|
puts "Redone numbering"
|
806
|
+
0
|
776
807
|
end
|
777
808
|
##
|
778
809
|
private
|
@@ -818,6 +849,46 @@ class Todo
|
|
818
849
|
end
|
819
850
|
## [1, 2, 3, 3.1, 3.1.1, 3.2, 3.3 ... ], " 3.1.1\t[ ] some task"
|
820
851
|
|
852
|
+
def fold_subtasks
|
853
|
+
#load_array
|
854
|
+
prev = ""
|
855
|
+
newarray = []
|
856
|
+
# get the main item, avoid subitem
|
857
|
+
#item = line.match(/^ *([0-9\.]+)/)
|
858
|
+
rx = Regexp.new "^ *([0-9]+)"
|
859
|
+
@data.each { |row|
|
860
|
+
it = row[0].match(rx)
|
861
|
+
item = it[1]
|
862
|
+
if item == prev # append to prev line
|
863
|
+
#puts "item matches prev #{item} #{prev} "
|
864
|
+
x=newarray.last
|
865
|
+
x[1] << "#{row[0]}\t#{row[1]}"
|
866
|
+
else
|
867
|
+
#puts "no match item matches prev #{row[0]}: #{prev} "
|
868
|
+
newarray << row
|
869
|
+
end
|
870
|
+
prev = item
|
871
|
+
}
|
872
|
+
#newarray.each { |row| puts "#{row[0]} #{row[1]}" }
|
873
|
+
@data = newarray
|
874
|
+
end
|
875
|
+
def unfold_subtasks
|
876
|
+
newarray = []
|
877
|
+
# get the main item, avoid subitem
|
878
|
+
#item = line.match(/^ *([0-9\.]+)/)
|
879
|
+
@data.each { |row|
|
880
|
+
if row[1] =~ //
|
881
|
+
#puts "row #{row[0]} contains ^B"
|
882
|
+
line = row.join "\t"
|
883
|
+
lines = line.split //
|
884
|
+
#puts " #{lines.count} lines "
|
885
|
+
lines.each { |e| newarray << e.split("\t") }
|
886
|
+
else
|
887
|
+
newarray << row
|
888
|
+
end
|
889
|
+
}
|
890
|
+
@data = newarray
|
891
|
+
end
|
821
892
|
def self.main args
|
822
893
|
ret = nil
|
823
894
|
begin
|
@@ -836,103 +907,197 @@ class Todo
|
|
836
907
|
options[:colorize] = (plain == "0") ? false:true
|
837
908
|
end
|
838
909
|
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
opts.separator "List options:"
|
867
|
-
|
868
|
-
opts.on("--[no-]color", "--[no-]colors", "colorize listing") do |v|
|
869
|
-
options[:colorize] = v
|
870
|
-
options[:color_scheme] = 1
|
871
|
-
end
|
872
|
-
opts.on("-s", "--sort", "sort list on priority") do |v|
|
873
|
-
options[:sort] = v
|
874
|
-
end
|
875
|
-
opts.on("-g", "--grep REGEXP", "filter list on pattern") do |v|
|
876
|
-
options[:grep] = v
|
877
|
-
end
|
878
|
-
opts.on("--renumber", "renumber while listing") do |v|
|
879
|
-
options[:renumber] = v
|
880
|
-
end
|
881
|
-
opts.on("--hide-numbering", "hide-numbering while listing ") do |v|
|
882
|
-
options[:hide_numbering] = v
|
883
|
-
end
|
884
|
-
opts.on("--[no-]show-all", "show all tasks (incl closed)") do |v|
|
885
|
-
options[:show_all] = v
|
886
|
-
end
|
887
|
-
|
888
|
-
opts.separator ""
|
889
|
-
opts.separator "Common options:"
|
890
|
-
|
891
|
-
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
892
|
-
options[:verbose] = v
|
893
|
-
end
|
894
|
-
opts.on("-f", "--file FILENAME", "CSV filename") do |v|
|
895
|
-
options[:file] = v
|
896
|
-
end
|
897
|
-
opts.on("-d DIR", "--dir DIR", "Use TODO file in this directory") do |v|
|
898
|
-
require 'FileUtils'
|
899
|
-
dir = File.expand_path v
|
900
|
-
if File.directory? dir
|
901
|
-
options[:dir] = dir
|
902
|
-
# changing dir is important so that serial_number file is the current one.
|
903
|
-
FileUtils.cd dir
|
904
|
-
else
|
905
|
-
die "#{RED}#{v}: no such directory #{CLEAR}"
|
906
|
-
end
|
907
|
-
end
|
908
|
-
# No argument, shows at tail. This will print an options summary.
|
909
|
-
# Try it and see!
|
910
|
-
opts.on("-h", "--help", "Show this message") do
|
911
|
-
puts opts
|
912
|
-
exit 0
|
913
|
-
end
|
914
|
-
|
915
|
-
opts.on("--show-actions", "show actions ") do |v|
|
916
|
-
todo = Todo.new(options, ARGV)
|
917
|
-
todo.help nil
|
918
|
-
exit 0
|
919
|
-
end
|
910
|
+
Subcommands::global_options do |opts|
|
911
|
+
opts.banner = "Usage: #{$APPNAME} [options] [subcommand [options]]"
|
912
|
+
opts.description = "Todo list manager"
|
913
|
+
#opts.separator ""
|
914
|
+
#opts.separator "Global options are:"
|
915
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
916
|
+
options[:verbose] = v
|
917
|
+
end
|
918
|
+
opts.on("-f", "--file FILENAME", "CSV filename") do |v|
|
919
|
+
options[:file] = v
|
920
|
+
end
|
921
|
+
opts.on("-d DIR", "--dir DIR", "Use TODO file in this directory") do |v|
|
922
|
+
require 'FileUtils'
|
923
|
+
dir = File.expand_path v
|
924
|
+
if File.directory? dir
|
925
|
+
options[:dir] = dir
|
926
|
+
# changing dir is important so that serial_number file is the current one.
|
927
|
+
FileUtils.cd dir
|
928
|
+
else
|
929
|
+
die "#{RED}#{v}: no such directory #{CLEAR}"
|
930
|
+
end
|
931
|
+
end
|
932
|
+
opts.on("--show-actions", "show actions ") do |v|
|
933
|
+
todo = Todo.new(options, ARGV)
|
934
|
+
todo.help nil
|
935
|
+
exit 0
|
936
|
+
end
|
920
937
|
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
938
|
+
opts.on("--version", "Show version") do
|
939
|
+
version = Cmdapp::version_info || VERSION
|
940
|
+
puts "#{APPNAME} version #{version}, #{DATE}"
|
941
|
+
puts "by #{AUTHOR}. This software is under the GPL License."
|
942
|
+
exit 0
|
943
|
+
end
|
944
|
+
# No argument, shows at tail. This will print an options summary.
|
945
|
+
# Try it and see!
|
946
|
+
opts.on("-h", "--help", "Show this message") do
|
947
|
+
puts opts
|
948
|
+
exit 0
|
949
|
+
end
|
926
950
|
opts.separator ""
|
927
951
|
opts.separator "Common Usage:"
|
928
952
|
opts.separator <<TEXT
|
953
|
+
#{APPNAME} add "Text ...."
|
929
954
|
#{APPNAME} list
|
930
|
-
#{APPNAME} add "TEXT ...."
|
931
955
|
#{APPNAME} pri 1 A
|
932
956
|
#{APPNAME} close 1
|
933
957
|
TEXT
|
934
|
-
|
935
|
-
|
958
|
+
end
|
959
|
+
|
960
|
+
Subcommands::command :list do |opts|
|
961
|
+
opts.banner = "Usage: list [options]"
|
962
|
+
opts.description = "List tasks.\t --show-all and others"
|
963
|
+
opts.on("-P", "--project PROJECTNAME", "name of project for add or list") { |v|
|
964
|
+
options[:project] = v
|
965
|
+
options[:filter] = true
|
966
|
+
}
|
967
|
+
opts.on("-p", "--priority A-Z", "priority code for add or list") { |v|
|
968
|
+
options[:priority] = v
|
969
|
+
options[:filter] = true
|
970
|
+
}
|
971
|
+
opts.on("-C", "--component COMPONENT", "component name for add or list") { |v|
|
972
|
+
options[:component] = v
|
973
|
+
options[:filter] = true
|
974
|
+
}
|
975
|
+
opts.on("--[no-]color", "--[no-]colors", "colorize listing") do |v|
|
976
|
+
options[:colorize] = v
|
977
|
+
options[:color_scheme] = 1
|
978
|
+
end
|
979
|
+
opts.on("-s", "--sort", "sort list on status,priority") do |v|
|
980
|
+
options[:sort] = v
|
981
|
+
end
|
982
|
+
opts.on("--reverse", "sort list on status,priority reversed") do |v|
|
983
|
+
options[:reverse] = v
|
984
|
+
end
|
985
|
+
opts.on("-g", "--grep REGEXP", "filter list on pattern") do |v|
|
986
|
+
options[:grep] = v
|
987
|
+
end
|
988
|
+
opts.on("--renumber", "renumber while listing") do |v|
|
989
|
+
options[:renumber] = v
|
990
|
+
end
|
991
|
+
opts.on("--hide-numbering", "hide-numbering while listing ") do |v|
|
992
|
+
options[:hide_numbering] = v
|
993
|
+
end
|
994
|
+
opts.on("--[no-]show-all", "show all tasks (incl closed)") do |v|
|
995
|
+
options[:show_all] = v
|
996
|
+
end
|
997
|
+
opts.on("--show-arch", "show all tasks adding archived ones too") do |v|
|
998
|
+
options[:show_arch] = v
|
999
|
+
options[:show_all] = v # when adding archived, we set show-all so closed are visible
|
1000
|
+
end
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
Subcommands::command :add, :a do |opts|
|
1004
|
+
opts.banner = "Usage: add [options] TEXT"
|
1005
|
+
opts.description = "Add a task."
|
1006
|
+
opts.on("-f", "--[no-]force", "force verbosely") do |v|
|
1007
|
+
options[:force] = v
|
1008
|
+
end
|
1009
|
+
opts.on("-P", "--project PROJECTNAME", "name of project for add or list") { |v|
|
1010
|
+
options[:project] = v
|
1011
|
+
options[:filter] = true
|
1012
|
+
}
|
1013
|
+
opts.on("-p", "--priority A-Z", "priority code for add or list") { |v|
|
1014
|
+
options[:priority] = v
|
1015
|
+
options[:filter] = true
|
1016
|
+
}
|
1017
|
+
opts.on("-C", "--component COMPONENT", "component name for add or list") { |v|
|
1018
|
+
options[:component] = v
|
1019
|
+
options[:filter] = true
|
1020
|
+
}
|
1021
|
+
end
|
1022
|
+
# XXX order of these 2 matters !! reverse and see what happens
|
1023
|
+
Subcommands::command :pri, :p do |opts|
|
1024
|
+
opts.banner = "Usage: pri [options] [A-Z] <TASK/s>"
|
1025
|
+
opts.description = "Add priority to task. "
|
1026
|
+
opts.on("-f", "--[no-]force", "force verbosely") do |v|
|
1027
|
+
options[:force] = v
|
1028
|
+
end
|
1029
|
+
end
|
1030
|
+
Subcommands::command :depri do |opts|
|
1031
|
+
opts.banner = "Usage: depri [options] <TASK/s>"
|
1032
|
+
opts.description = "Remove priority of task. \n\t todorb depri <TASK>"
|
1033
|
+
opts.on("-f", "--[no-]force", "force verbosely") do |v|
|
1034
|
+
options[:force] = v
|
1035
|
+
end
|
1036
|
+
end
|
1037
|
+
Subcommands::command :delete, :del do |opts|
|
1038
|
+
opts.banner = "Usage: delete [options] <TASK/s>"
|
1039
|
+
opts.description = "Delete a task. \n\t todorb delete <TASK>"
|
1040
|
+
opts.on("-f", "--[no-]force", "force - don't prompt") do |v|
|
1041
|
+
options[:force] = v
|
1042
|
+
end
|
1043
|
+
opts.on("--recursive", "operate on subtasks also") { |v|
|
1044
|
+
options[:recursive] = v
|
1045
|
+
}
|
1046
|
+
end
|
1047
|
+
Subcommands::command :status do |opts|
|
1048
|
+
opts.banner = "Usage: status [options] <STATUS> <TASKS>"
|
1049
|
+
opts.description = "Change the status of a task. \t<STATUS> are open closed started pending hold next"
|
1050
|
+
opts.on("--recursive", "operate on subtasks also") { |v|
|
1051
|
+
options[:recursive] = v
|
1052
|
+
}
|
1053
|
+
end
|
1054
|
+
Subcommands::command :redo do |opts|
|
1055
|
+
opts.banner = "Usage: redo"
|
1056
|
+
opts.description = "Renumbers the todo file starting 1"
|
1057
|
+
end
|
1058
|
+
Subcommands::command :note do |opts|
|
1059
|
+
opts.banner = "Usage: note <TASK> <TEXT>"
|
1060
|
+
opts.description = "Add a note to a task."
|
1061
|
+
end
|
1062
|
+
Subcommands::command :tag do |opts|
|
1063
|
+
opts.banner = "Usage: tag <TAG> <TASKS>"
|
1064
|
+
opts.description = "Add a tag to an item/s. "
|
1065
|
+
end
|
1066
|
+
Subcommands::command :archive do |opts|
|
1067
|
+
opts.banner = "Usage: archive"
|
1068
|
+
opts.description = "archive closed tasks to archive.txt"
|
1069
|
+
end
|
1070
|
+
Subcommands::command :copyunder, :cu do |opts|
|
1071
|
+
opts.banner = "Usage: copyunder"
|
1072
|
+
opts.description = "Move first task under second (as a subtask). aka cu"
|
1073
|
+
opts.on("-d", "--delete", "Delete old after copying") do |v|
|
1074
|
+
options[:delete_old] = v
|
1075
|
+
end
|
1076
|
+
end
|
1077
|
+
Subcommands::command :addsub do |opts|
|
1078
|
+
opts.banner = "Usage: addsub [options]"
|
1079
|
+
opts.description = "Add a task under another."
|
1080
|
+
opts.on("-P", "--project PROJECTNAME", "name of project for add or list") { |v|
|
1081
|
+
options[:project] = v
|
1082
|
+
#options[:filter] = true
|
1083
|
+
}
|
1084
|
+
opts.on("-p", "--priority A-Z", "priority code for add or list") { |v|
|
1085
|
+
options[:priority] = v
|
1086
|
+
#options[:filter] = true
|
1087
|
+
}
|
1088
|
+
opts.on("-C", "--component COMPONENT", "component name for add or list") { |v|
|
1089
|
+
options[:component] = v
|
1090
|
+
#options[:filter] = true
|
1091
|
+
}
|
1092
|
+
end
|
1093
|
+
#Subcommands::command :testy do |opts|
|
1094
|
+
#opts.banner = "Usage: test"
|
1095
|
+
#opts.description = "test out some functionality"
|
1096
|
+
#end
|
1097
|
+
Subcommands::alias_command :open , "status","open"
|
1098
|
+
Subcommands::alias_command :close , "status","closed"
|
1099
|
+
cmd = Subcommands::opt_parse()
|
1100
|
+
args.unshift cmd if cmd
|
936
1101
|
|
937
1102
|
options[:file] ||= "TODO2.txt"
|
938
1103
|
if options[:verbose]
|
data/tests/data.1
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
1 [x] if no TODO file give proper message to add task (2010-06-14)
|
2
|
+
2 [x] what if no serial_number file? (2010-06-14)
|
3
|
+
3 [x] Add a close for status close (2010-06-14)
|
4
|
+
3.1 [ ] hello there new a u 3 (2010-06-15)
|
5
|
+
3.1.1 [ ] hello there new a u 3 (2010-06-15)
|
6
|
+
3.1.2 [ ] hello there new a u 3 (2010-06-15)
|
7
|
+
3.1.3 [ ] hello there new a u 3 (2010-06-15)
|
8
|
+
3.2 [ ] hello there new a u 3.2 (2010-06-15)
|
9
|
+
3.2.1 [ ] hello there new a u 3.2.1 (2010-06-15)
|
10
|
+
3.2.1.1 [ ] hello there new a u 3.2.1.1 (2010-06-15)
|
11
|
+
4 [ ] start rubyforge project for todorb (2010-06-14)
|
12
|
+
5 [ ] list: if dir given then show full path of TODO2.txt at end (2010-06-14)
|
13
|
+
6 [ ] allow for ENV VARS such as verbose, plain, force (2010-06-15)
|
14
|
+
7 [ ] list: search terms with - + and = (2010-06-15)
|
data/tests/data.2
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
1 [ ] if no TODO file give proper message to add task (2010-06-14)
|
2
|
+
2 [ ] what if no serial_number file? (2010-06-14)
|
3
|
+
3 [ ] Add a close for status close (2010-06-14)
|
4
|
+
4 [ ] start rubyforge project for todorb (2010-06-14)
|
5
|
+
5 [ ] list: if dir given then show full path of TODO2.txt at end (2010-06-14)
|
6
|
+
6 [ ] allow for ENV VARS such as verbose, plain, force (2010-06-15)
|
7
|
+
7 [ ] list: search terms with - + and = (2010-06-15)
|