doing 1.0.6pre → 1.0.7pre

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 31cbf5627a0818d3252c9f75265372652b7b22df
4
- data.tar.gz: 3c70bc7a7b81dd3ce0db6d0e291dd4d4cf45d29f
3
+ metadata.gz: 416eb3b0c0b4892d106c8e6431a5925b393e587c
4
+ data.tar.gz: 47b5a29f17ce836404630379612a0c82e0811a97
5
5
  SHA512:
6
- metadata.gz: 68287fcedc4d02dc46fa61e6587f4c3d7cf33f6727a9a03a9c155b9ecce63244deca08451be86be9d0c0260221d75b3478224c2c52edf538fc161a4bde191662
7
- data.tar.gz: a20c0b2ff59f6125e7d5f0046034a3bc1825546d3f8c01b0b72600285325a0ef719e97f4ead9beafb9954ec82e465263636caf152b08c9f93d6f22bd885fa588
6
+ metadata.gz: 4fb329e66f43e85a03a2c256d1ef0b68db8b8c917c974de5d39c5de805c71b9c2b7a0e4a5357cc4e5fe854ffdf2bfcb266ec60b1537e8426736023179b5dd541
7
+ data.tar.gz: a1057480b5758c883d6602a6e50b328b68972b9566888516a84a0b5d57a76c25e56031e725f6036bab35581a4bb9c37ead73b4a54cf0d7b59a800dd473587610
data/README.md CHANGED
@@ -127,6 +127,7 @@ The config also contains templates for various command outputs. Include placehol
127
127
  - `%[color]`: color can be black, red, green, blue, yellow, magenta, cyan or white
128
128
  - you can prefix "bg" to affect background colors (%bgyellow)
129
129
  - prefix "bold" and "boldbg" for strong colors (%boldgreen, %boldbgblue)
130
+ - there are some random special combo colors. Use `doing colors` to see the list
130
131
  - `%interval`: when used with the `-t` switch on the `show` command, it will display the time between a timestamp or `@start(date)` tag and the `@done(date)` tag, if it exists. Otherwise, it will remain empty.
131
132
 
132
133
  Date formats are based on Ruby [strftime](http://www.ruby-doc.org/stdlib-2.1.1/libdoc/date/rdoc/Date.html#method-i-strftime) formatting.
@@ -309,9 +310,9 @@ As mentioned above, `finish` also accepts `--back "2 hours"` (sets the finish da
309
310
 
310
311
  ... will mark the last three entries as "@client @cancelled." Add `-r` as a switch to remove the listed tags instead.
311
312
 
312
- `note` lets you enter a note on the last entry. You can specify a section with `-s section_name`. `-e` will open your $EDITOR for typing the note, but you can just include it on the command line after any arguments. You can also pipe a note in on STDIN (`echo "fun stuff"|doing note`). The `-r` switch will remove/replace a note; if there's new note text passed when using the `-r` switch, it will replace any existing note. If the `-r` switch is used alone, any existing note will be removed.
313
+ `note` lets you append a note to the last entry. You can specify a section to grab the last entry from with `-s section_name`. `-e` will open your $EDITOR for typing the note, but you can also just include it on the command line after any flags. You can also pipe a note in on STDIN (`echo "fun stuff"|doing note`). If you don't use the `-r` switch, new notes will be appended to the existing notes, and using the `-e` switch will let you edit and add to an existing note. The `-r` switch will remove/replace a note; if there's new note text passed when using the `-r` switch, it will replace any existing note. If the `-r` switch is used alone, any existing note will be removed.
313
314
 
314
- You can also add notes at the time of entry by using the `-n` or `--note` flag with `doing now`, `doing later`, or `doing done`. If you pass in text to any of the creation commands that has multiple lines, everything after the first line break will become the note.
315
+ You can also add notes at the time of entry by using the `-n` or `--note` flag with `doing now`, `doing later`, or `doing done`. If you pass text to any of the creation commands which has multiple lines, everything after the first line break will become the note.
315
316
 
316
317
  #### Displaying entries:
317
318
 
@@ -451,10 +452,36 @@ I'll try to document some of the code structure as I flesh it out. I'm currently
451
452
 
452
453
  ### Changelog
453
454
 
455
+
456
+ #### 1.0.7 / 2014-09-23
457
+
458
+ * fix for -v option
459
+ * Slightly fuzzier searching in the grep command
460
+ * cleaner exits, only_timed key for view configs
461
+ * making the note command append new notes better, and load existing notes in the editor if -e is called
462
+ * handle multiple tag input in 'show' tag filter
463
+ * Global tag operations, better reporting
464
+
454
465
  #### 1.0.4pre
455
466
 
456
467
  * Improved HTML output
457
468
  * --only_timed option for view/show commands that only outputs items with elapsed timers (interval between start and done dates)
469
+ * add seconds for timed items in CSV output, run --only_timed before chopping off --count #
470
+ * fix for 1.8.7 Dir.home issue
471
+ * version bump
472
+ * don't show tag totals with zero times
473
+ * zsh completion for doing
474
+ * HTML styling
475
+ * --only_timed option
476
+ * added zsh completion file to README.md
477
+ * add zsh completion file
478
+
479
+ #### 1.0.3pre
480
+
481
+ * done command: making --took modify start time if --back isn't specified
482
+ * Cleaned up time totals, improved HTML output
483
+ * fixes for --back and --took parsing
484
+ * Adding more complete terminal reporting to archive command
458
485
 
459
486
  #### 1.0.0pre
460
487
 
data/bin/doing CHANGED
@@ -117,15 +117,22 @@ command :note do |c|
117
117
 
118
118
  if options[:e] || (args.length == 0 && STDIN.stat.size == 0 && !options[:r])
119
119
  raise "No EDITOR variable defined in environment" if ENV['EDITOR'].nil?
120
- input = ""
121
- input += args.join(" ") if args.length > 0
120
+
121
+ input = args.length > 0 ? args.join(" ") : ""
122
+
123
+ prev_input = wwid.last_note(section)
124
+ if prev_input.class == Array
125
+ prev_input = prev_input.join("\n")
126
+ end
127
+ input = prev_input + input
128
+
122
129
  input = wwid.fork_editor(input)
123
130
  if input
124
131
  title, note = wwid.format_input(input)
125
132
  note.insert(0, title)
126
- wwid.note_last(section, note, options[:r])
133
+ wwid.note_last(section, note, true)
127
134
  else
128
- raise "No content"
135
+ raise "No content, cancelled"
129
136
  end
130
137
  else
131
138
  if args.length > 0
@@ -423,7 +430,7 @@ command :tag do |c|
423
430
  c.default_value wwid.current_section
424
431
  c.flag [:s,:section], :default_value => wwid.current_section
425
432
 
426
- c.desc 'How many recent entries to tag'
433
+ c.desc 'How many recent entries to tag (0 for all)'
427
434
  c.default_value 1
428
435
  c.flag [:c,:count], :default_value => 1
429
436
 
@@ -442,7 +449,6 @@ command :tag do |c|
442
449
 
443
450
  section = wwid.guess_section(options[:s]) || options[:s].cap_first
444
451
 
445
- count = options[:c].to_i
446
452
  if args.join("") =~ /,/
447
453
  tags = args.join("").split(/,/)
448
454
  else
@@ -451,6 +457,22 @@ command :tag do |c|
451
457
 
452
458
  tags.map!{|tag| tag.sub(/^@/,'').strip }
453
459
 
460
+ count = options[:c].to_i
461
+
462
+ if count == 0
463
+ if options[:r]
464
+ print "Are you sure you want to remove #{tags.join(" and ")} from all records? (y/N) "
465
+ else
466
+ print "Are you sure you want to add #{tags.join(" and ")} to all records? (y/N) "
467
+ end
468
+
469
+ res = STDIN.gets
470
+
471
+ unless res.strip =~ /^y(es)?$/i
472
+ raise "Cancelled"
473
+ end
474
+ end
475
+
454
476
  wwid.tag_last({:tags => tags, :count => count, :section => section, :date => options[:d], :remove => options[:r]})
455
477
  end
456
478
  end
@@ -476,6 +498,7 @@ end
476
498
 
477
499
 
478
500
  desc 'List all entries'
501
+ long_desc 'The argument can be a section name, tag(s) or both. "pick" or "choose" as an argument will offer a section menu.'
479
502
  arg_name 'section [tags]'
480
503
  command :show do |c|
481
504
  c.desc 'Tag boolean (AND,OR,NONE)'
@@ -515,15 +538,27 @@ command :show do |c|
515
538
  if args.length > 0
516
539
  if args[0] =~ /^all$/i
517
540
  section = "All"
541
+ args.shift
542
+ elsif args[0] =~ /^(choose|pick)$/i
543
+ section = wwid.choose_section
544
+ args.shift
518
545
  elsif args[0] =~ /^@/
519
546
  section = "All"
520
- tags.push(args[0].sub(/^@/,''))
521
547
  else
522
548
  section = wwid.guess_section(args[0])
523
549
  raise "No such section: #{args[0]}" unless section
550
+ args.shift
524
551
  end
525
- if args.length > 1
526
- tags += args[1..-1].map{|tag| tag.sub(/^@/,'').strip}
552
+ if args.length > 0
553
+ args.each {|arg|
554
+ if arg =~ /,/
555
+ arg_tags = arg.split(/,/).each {|tag|
556
+ tags.push(tag.strip.sub(/^@/,''))
557
+ }
558
+ else
559
+ tags.push(arg.strip.sub(/^@/,''))
560
+ end
561
+ }
527
562
  end
528
563
  else
529
564
  section = wwid.current_section
@@ -572,7 +607,7 @@ command :grep do |c|
572
607
 
573
608
  options[:t] = true if options[:totals]
574
609
 
575
- puts wwid.list_section({:search => args.join, :section => section, :output => options[:output], :times => options[:t], :highlight => true, :totals => options[:totals], :only_timed => options[:only_timed]})
610
+ puts wwid.list_section({:search => args.join(' '), :section => section, :output => options[:output], :times => options[:t], :highlight => true, :totals => options[:totals], :only_timed => options[:only_timed]})
576
611
 
577
612
  end
578
613
  end
@@ -690,6 +725,24 @@ command :add_section do |c|
690
725
  end
691
726
  end
692
727
 
728
+ desc 'List available color variables for configuration templates and views'
729
+ command :colors do |c|
730
+ c.action do |global_options,options,args|
731
+ clrs = wwid.colors
732
+ bgs = []
733
+ fgs = []
734
+ clrs.each {|k,v|
735
+ if k =~ /bg/
736
+ bgs.push("#{v} #{clrs['default']} <-- #{k}")
737
+ else
738
+ fgs.push("#{v}XXXX#{clrs['default']} <-- #{k}")
739
+ end
740
+ }
741
+ puts fgs.join("\n")
742
+ puts bgs.join("\n")
743
+ end
744
+ end
745
+
693
746
  desc 'Display a user-created view'
694
747
  arg_name 'view_name'
695
748
  command :view do |c|
@@ -712,7 +765,7 @@ command :view do |c|
712
765
 
713
766
  c.desc 'Only show items with recorded time intervals'
714
767
  c.default_value false
715
- c.switch [:only_timed], :default_value => false, :negatable => false
768
+ c.switch [:only_timed], :default_value => false, :negatable => true
716
769
 
717
770
  c.action do |global_options,options,args|
718
771
  if args.empty?
@@ -727,6 +780,12 @@ command :view do |c|
727
780
 
728
781
  view = wwid.get_view(title)
729
782
  if view
783
+ if (view.has_key?('only_timed') && view['only_timed']) || options[:only_timed]
784
+ only_timed = true
785
+ else
786
+ only_timed = false
787
+ end
788
+
730
789
  template = view.has_key?('template') ? view['template'] : nil
731
790
  format = view.has_key?('date_format') ? view['date_format'] : nil
732
791
  tags_color = view.has_key?('tags_color') ? view['tags_color'] : nil
@@ -747,7 +806,7 @@ command :view do |c|
747
806
  order = view.has_key?('order') ? view['order'] : "asc"
748
807
  options[:t] = true if options[:totals]
749
808
  options[:output].downcase! if options[:output]
750
- puts wwid.list_section({:section => section, :count => count, :template => template, :format => format, :order => order, :tag_filter => tag_filter, :output => options[:output], :tags_color => tags_color, :times => options[:t], :highlight => true, :totals => options[:totals], :only_timed => options[:only_timed] })
809
+ puts wwid.list_section({:section => section, :count => count, :template => template, :format => format, :order => order, :tag_filter => tag_filter, :output => options[:output], :tags_color => tags_color, :times => options[:t], :highlight => true, :totals => options[:totals], :only_timed => only_timed })
751
810
  else
752
811
  raise "View #{title} not found in config"
753
812
  end
@@ -900,7 +959,7 @@ pre do |global,command,options,args|
900
959
  end
901
960
  wwid.config[:include_notes] = false unless global[:notes]
902
961
  if global[:version]
903
- puts "doing v" + Doing::VERSION
962
+ $stdout.puts "doing v" + Doing::VERSION
904
963
  end
905
964
 
906
965
  # Return true to proceed; false to abort and not call the
@@ -917,8 +976,7 @@ post do |global,command,options,args|
917
976
  end
918
977
 
919
978
  on_error do |exception|
920
- # Error logic here
921
- # return false to skip default error handling
979
+ # puts exception.message
922
980
  true
923
981
  end
924
982
 
data/lib/doing/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Doing
2
- VERSION = '1.0.6pre'
2
+ VERSION = '1.0.7pre'
3
3
  end
data/lib/doing/wwid.rb CHANGED
@@ -363,6 +363,17 @@ class WWID
363
363
  @results.push(%Q{Added "#{entry['title']}" to #{section}})
364
364
  end
365
365
 
366
+ def last_note(section=@current_section)
367
+ section = guess_section(section)
368
+ if @content.has_key?(section)
369
+ last_item = @content[section]['items'].dup.sort_by{|item| item['date'] }.reverse[0]
370
+ p last_item
371
+ return last_item['note']
372
+ else
373
+ raise "Section #{section} not found"
374
+ end
375
+ end
376
+
366
377
  def tag_last(opt={})
367
378
  opt[:section] ||= @current_section
368
379
  opt[:count] ||= 1
@@ -374,68 +385,85 @@ class WWID
374
385
  opt[:back] ||= Time.now
375
386
 
376
387
 
388
+ sec_arr = []
377
389
 
378
- opt[:section] = guess_section(opt[:section])
379
-
380
- if @content.has_key?(opt[:section])
381
- # sort_section(opt[:section])
382
- items = @content[opt[:section]]['items'].dup.sort_by{|item| item['date'] }.reverse
383
-
384
- index = 0
385
- done_date = Time.now
386
- next_start = Time.now
387
- items.map! {|item|
388
- break if index == opt[:count]
389
- if opt[:sequential]
390
- done_date = next_start - 1
391
- next_start = item['date']
392
- elsif opt[:back].instance_of? Fixnum
393
- done_date = item['date'] + opt[:back]
394
- else
395
- done_date = opt[:back]
396
- end
390
+ if opt[:section].nil?
391
+ sec_arr = [@current_section]
392
+ elsif opt[:section].class == String
393
+ if opt[:section] =~ /^all$/i
394
+ sec_arr = sections
395
+ else
396
+ sec_arr = [guess_section(opt[:section])]
397
+ end
398
+ end
397
399
 
398
- title = item['title']
399
- opt[:tags].each {|tag|
400
- if opt[:remove]
401
- title.gsub!(/(^| )@#{tag.strip}(\([^\)]*\))?/,'')
402
- @results.push("Updated: #{title}")
400
+ sec_arr.each {|section|
401
+ if @content.has_key?(section)
402
+
403
+ items = @content[section]['items'].dup.sort_by{|item| item['date'] }.reverse
404
+
405
+ index = 0
406
+ done_date = Time.now
407
+ next_start = Time.now
408
+ count = opt[:count] == 0 ? items.length : opt[:count]
409
+ items.map! {|item|
410
+ break if index == count
411
+ if opt[:sequential]
412
+ done_date = next_start - 1
413
+ next_start = item['date']
414
+ elsif opt[:back].instance_of? Fixnum
415
+ done_date = item['date'] + opt[:back]
403
416
  else
404
- unless title =~ /@#{tag}/
405
- title.chomp!
406
- if opt[:date]
407
- title += " @#{tag}(#{done_date.strftime('%F %R')})"
408
- else
409
- title += " @#{tag}"
417
+ done_date = opt[:back]
418
+ end
419
+
420
+ title = item['title']
421
+ opt[:tags].each {|tag|
422
+ tag.strip!
423
+ if opt[:remove]
424
+ if title =~ /@#{tag}/
425
+ title.gsub!(/(^| )@#{tag}(\([^\)]*\))?/,'')
426
+ @results.push("Removed @#{tag}: #{title}")
427
+ end
428
+ else
429
+ unless title =~ /@#{tag}/
430
+ title.chomp!
431
+ if opt[:date]
432
+ title += " @#{tag}(#{done_date.strftime('%F %R')})"
433
+ else
434
+ title += " @#{tag}"
435
+ end
436
+ @results.push("Added @#{tag}: #{title}")
410
437
  end
411
- @results.push("Updated: #{title}")
412
438
  end
413
- end
414
- }
439
+ }
415
440
 
416
- item['title'] = title
417
- index += 1
418
- item
419
- }
441
+ item['title'] = title
442
+ index += 1
443
+ item
444
+ }
420
445
 
421
- @content[opt[:section]]['items'] = items
422
-
423
- if opt[:archive] && opt[:section] != "Archive"
424
- # concat [count] items from [section] and archive section
425
- archived = @content[opt[:section]]['items'][0..opt[:count]-1].concat(@content['Archive']['items'])
426
- # chop [count] items off of [section] items
427
- @content[opt[:section]]['items'] = @content[opt[:section]]['items'][opt[:count]..-1]
428
- # overwrite archive section with concatenated array
429
- @content['Archive']['items'] = archived
430
- # log it
431
- result = opt[:count] == 1 ? "1 entry" : "#{opt[:count]} entries"
432
- @results.push("Archived #{result}")
446
+ @content[section]['items'] = items
447
+
448
+ if opt[:archive] && section != "Archive" && opt[:count] > 0
449
+ # concat [count] items from [section] and archive section
450
+ archived = @content[section]['items'][0..opt[:count]-1].concat(@content['Archive']['items'])
451
+ # chop [count] items off of [section] items
452
+ @content[opt[:section]]['items'] = @content[opt[:section]]['items'][opt[:count]..-1]
453
+ # overwrite archive section with concatenated array
454
+ @content['Archive']['items'] = archived
455
+ # log it
456
+ result = opt[:count] == 1 ? "1 entry" : "#{opt[:count]} entries"
457
+ @results.push("Archived #{result}")
458
+ elsif opt[:archive] && opt[:count] == 0
459
+ @results.push("Archiving is skipped when operating on all entries") if opt[:count] == 0
460
+ end
461
+ else
462
+ raise "Section not found: #{section}"
433
463
  end
464
+ }
434
465
 
435
- write(@doing_file)
436
- else
437
- raise "Section not found"
438
- end
466
+ write(@doing_file)
439
467
  end
440
468
 
441
469
  def note_last(section, note, replace=false)
@@ -488,12 +516,15 @@ class WWID
488
516
 
489
517
  tag.sub!(/^@/,'')
490
518
 
519
+ found_items = 0
520
+
491
521
  @content[opt[:section]]['items'].each_with_index {|item, i|
492
522
  if item['title'] =~ /@#{tag}/
493
523
  title = item['title'].gsub(/(^| )@(#{tag}|done)(\([^\)]*\))?/,'')
494
524
  title += " @done(#{opt[:back].strftime('%F %R')})"
495
525
 
496
526
  @content[opt[:section]]['items'][i]['title'] = title
527
+ found_items += 1
497
528
 
498
529
  if opt[:archive] && opt[:section] != "Archive"
499
530
  @results.push(%Q{Completed and archived "#{@content[opt[:section]]['items'][i]['title']}"})
@@ -505,6 +536,8 @@ class WWID
505
536
  end
506
537
  }
507
538
 
539
+ @results.push("No active @#{tag} tasks found.") if found_items == 0
540
+
508
541
  if opt[:new_item]
509
542
  title, note = format_input(opt[:new_item])
510
543
  note.push(opt[:note]) if opt[:note]
@@ -530,7 +563,9 @@ class WWID
530
563
  $stdout.puts output
531
564
  else
532
565
  if File.exists?(File.expand_path(file))
566
+ # Create a backup copy for the undo command
533
567
  FileUtils.cp(file,file+"~")
568
+
534
569
  File.open(File.expand_path(file),'w+') do |f|
535
570
  f.puts output
536
571
  end
@@ -647,13 +682,14 @@ class WWID
647
682
  if opt[:search]
648
683
  items.keep_if {|item|
649
684
  text = item['note'] ? item['title'] + item['note'].join(" ") : item['title']
650
- text =~ /#{opt[:search]}/i
685
+ pattern = opt[:search].split('').join('.{0,3}')
686
+ text =~ /#{pattern}/i
651
687
  }
652
688
  end
653
689
 
654
690
  if opt[:only_timed]
655
691
  items.delete_if {|item|
656
- get_interval(item) == "00:00:00"
692
+ get_interval(item) == false
657
693
  }
658
694
  end
659
695
 
@@ -963,6 +999,12 @@ EOT
963
999
  color['boldbgmagenta'] = "\033[1;45m"
964
1000
  color['boldbgcyan'] = "\033[1;46m"
965
1001
  color['boldbgwhite'] = "\033[1;47m"
1002
+ color['softpurple'] = "\033[0;35;40m"
1003
+ color['hotpants'] = "\033[7;34;40m"
1004
+ color['knightrider'] = "\033[7;30;40m"
1005
+ color['flamingo'] = "\033[7;31;47m"
1006
+ color['yeller'] = "\033[1;37;43m"
1007
+ color['whiteboard'] = "\033[1;30;47m"
966
1008
  color['default']="\033[0;39m"
967
1009
  color
968
1010
  end
@@ -1090,7 +1132,7 @@ EOS
1090
1132
 
1091
1133
  return seconds unless formatted
1092
1134
 
1093
- "%02d:%02d:%02d" % fmt_time(seconds)
1135
+ seconds > 0 ? "%02d:%02d:%02d" % fmt_time(seconds) : false
1094
1136
  end
1095
1137
 
1096
1138
  def fmt_time(seconds)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doing
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6pre
4
+ version: 1.0.7pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-23 00:00:00.000000000 Z
11
+ date: 2014-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake