todorb 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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)
|