doing 1.0.83 → 1.0.84

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb85f27f305f246d4ab182268c9e5188da67f22fde46d3ee4ae716996c78b2c3
4
- data.tar.gz: 7b302748d9837511adc77679fd619c6daf85b2f7e15f541d530c8cc211e0aac3
3
+ metadata.gz: c11e6c75768b8dc2db3a36c5cdd572ad03eb884e118848ebbe413df2988a53df
4
+ data.tar.gz: a3f45b396e4c6b06bab65d24007f0437e72687c6811f559ece8f6c5ca2e7bbba
5
5
  SHA512:
6
- metadata.gz: dbf5e04626a97e5287c2417cf5afffd6516860a1fa5f3ed64e93fe15bdc62b85f045d0a54adc08c774b4d711add29f02799cf3d4a2c22853e1273a691d0a9f00
7
- data.tar.gz: 87bf6eac2e770b161c8ae4fd2fee4adea5ed261b828f2142997858393a627e0d36788981fe52a4c66486f442da2de349ce1ac157732d824b0ef633e4dcbdc703
6
+ metadata.gz: 7be6844f9f6caa072014afeded310cbaddf2a15380fde5498aea0f980dd5e8448ca44f5c5d9692a2075818f632bbbd19cce93e0db338c621a487abed8259f555
7
+ data.tar.gz: d0af857fee4113e2055af031059901b56e2ff94e849f9d3a0d167d8edde0519e4d6a6ebdeef55050ee313ed628ba6fa2fbd17e73cfc66143e57e7a2c42f93c8f
data/README.md CHANGED
@@ -27,7 +27,7 @@ If there's something I want to look at later but doesn't need to be added to a t
27
27
 
28
28
  ## Installation
29
29
 
30
- The current version of `doing` is <!--VER-->1.0.82<!--END VER-->.
30
+ The current version of `doing` is <!--VER-->1.0.83<!--END VER-->.
31
31
 
32
32
  $ [sudo] gem install doing
33
33
 
data/bin/doing CHANGED
@@ -55,7 +55,7 @@ arg_name 'ENTRY'
55
55
  command %i[now next] do |c|
56
56
  c.desc 'Section'
57
57
  c.arg_name 'NAME'
58
- c.flag %i[s section], default_value: wwid.current_section
58
+ c.flag %i[s section]
59
59
 
60
60
  c.desc "Edit entry with #{ENV['EDITOR']}"
61
61
  c.switch %i[e editor], negatable: false, default_value: false
@@ -84,7 +84,11 @@ command %i[now next] do |c|
84
84
  date = Time.now
85
85
  end
86
86
 
87
- section = wwid.guess_section(options[:s]) || options[:s].cap_first
87
+ if options[:section]
88
+ section = wwid.guess_section(options[:section]) || options[:section].cap_first
89
+ else
90
+ options[:section] = wwid.config['current_section']
91
+ end
88
92
 
89
93
  if options[:e] || (args.empty? && $stdin.stat.size.zero?)
90
94
  exit_now! 'No EDITOR variable defined in environment' if ENV['EDITOR'].nil?
@@ -135,7 +139,9 @@ command :note do |c|
135
139
  c.switch %i[r remove], negatable: false, default_value: false
136
140
 
137
141
  c.action do |_global_options, options, args|
138
- section = wwid.guess_section(options[:s]) || options[:s].cap_first
142
+ if options[:section]
143
+ section = wwid.guess_section(options[:section]) || options[:section].cap_first
144
+ end
139
145
 
140
146
  if options[:e] || (args.empty? && $stdin.stat.size.zero? && !options[:r])
141
147
  exit_now! 'No EDITOR variable defined in environment' if ENV['EDITOR'].nil?
@@ -176,7 +182,7 @@ arg_name 'ENTRY'
176
182
  command :meanwhile do |c|
177
183
  c.desc 'Section'
178
184
  c.arg_name 'NAME'
179
- c.flag %i[s section], default_value: wwid.current_section
185
+ c.flag %i[s section]
180
186
 
181
187
  c.desc "Edit entry with #{ENV['EDITOR']}"
182
188
  c.switch %i[e editor], negatable: false, default_value: false
@@ -201,7 +207,11 @@ command :meanwhile do |c|
201
207
  date = Time.now
202
208
  end
203
209
 
204
- section = wwid.guess_section(options[:s]) || options[:s].cap_first
210
+ if options[:section]
211
+ section = wwid.guess_section(options[:section]) || options[:section].cap_first
212
+ else
213
+ section = wwid.config['current_section']
214
+ end
205
215
  input = ''
206
216
 
207
217
  if options[:e]
@@ -308,7 +318,7 @@ command :select do |c|
308
318
  c.arg_name 'FILE'
309
319
  c.flag %i[save_to]
310
320
 
311
- c.desc 'Output format for export (doing|taskpaper|csv|html|json|template|timeline)'
321
+ c.desc 'Output entries to format (doing|taskpaper|csv|html|json|template|timeline)'
312
322
  c.arg_name 'FORMAT'
313
323
  c.flag %i[o output], must_match: /^(?:doing|taskpaper|html|csv|json|template|timeline)$/i
314
324
 
@@ -399,7 +409,7 @@ command %i[done did] do |c|
399
409
 
400
410
  c.desc 'Section'
401
411
  c.arg_name 'NAME'
402
- c.flag %i[s section], default_value: wwid.current_section
412
+ c.flag %i[s section]
403
413
 
404
414
  c.desc "Edit entry with #{ENV['EDITOR']}"
405
415
  c.switch %i[e editor], negatable: false, default_value: false
@@ -440,7 +450,11 @@ command %i[done did] do |c|
440
450
  donedate = options[:date] ? "(#{finish_date.strftime('%F %R')})" : ''
441
451
  end
442
452
 
443
- section = wwid.guess_section(options[:s]) || options[:s].cap_first
453
+ if options[:section]
454
+ section = wwid.guess_section(options[:section]) || options[:section].cap_first
455
+ else
456
+ section = wwid.config['current_section']
457
+ end
444
458
 
445
459
  if options[:e]
446
460
  exit_now! 'No EDITOR variable defined in environment' if ENV['EDITOR'].nil?
@@ -497,7 +511,7 @@ command :cancel do |c|
497
511
 
498
512
  c.desc 'Section'
499
513
  c.arg_name 'NAME'
500
- c.flag %i[s section], default_value: wwid.current_section
514
+ c.flag %i[s section]
501
515
 
502
516
  c.desc 'Cancel the last X entries containing TAG. Separate multiple tags with comma (--tag=tag1,tag2)'
503
517
  c.arg_name 'TAG'
@@ -511,7 +525,11 @@ command :cancel do |c|
511
525
  c.switch %i[u unfinished], negatable: false, default_value: false
512
526
 
513
527
  c.action do |_global_options, options, args|
514
- section = wwid.guess_section(options[:s]) || options[:s].cap_first
528
+ if options[:section]
529
+ section = wwid.guess_section(options[:section]) || options[:section].cap_first
530
+ else
531
+ section = wwid.config['current_section']
532
+ end
515
533
 
516
534
  if options[:tag].nil?
517
535
  tags = []
@@ -564,6 +582,10 @@ command :finish do |c|
564
582
  c.arg_name 'INTERVAL'
565
583
  c.flag %i[t took]
566
584
 
585
+ c.desc %(Set finish date to specific date/time (natural langauge parsed, e.g. --at=1:30pm). If used, ignores --back.)
586
+ c.arg_name 'DATE_STRING'
587
+ c.flag [:at]
588
+
567
589
  c.desc 'Finish the last X entries containing TAG.
568
590
  Separate multiple tags with comma (--tag=tag1,tag2), combine with --bool'
569
591
  c.arg_name 'TAG'
@@ -590,17 +612,31 @@ command :finish do |c|
590
612
 
591
613
  c.desc 'Section'
592
614
  c.arg_name 'NAME'
593
- c.flag %i[s section], default_value: wwid.current_section
615
+ c.flag %i[s section]
594
616
 
595
617
  c.action do |_global_options, options, args|
596
- section = wwid.guess_section(options[:s]) || options[:s].cap_first
618
+ if options[:section]
619
+ section = wwid.guess_section(options[:section]) || options[:section].cap_first
620
+ else
621
+ section = wwid.config['current_section']
622
+ end
597
623
 
598
624
  unless options[:auto]
625
+ if options[:took]
626
+ took = wwid.chronify_qty(options[:took])
627
+ exit_now! 'Unable to parse date string for --took' if took.nil?
628
+ end
629
+
599
630
  exit_now! '--back and --took cannot be used together' if options[:back] && options[:took]
600
631
 
601
632
  exit_now! '--search and --tag cannot be used together' if options[:search] && options[:tag]
602
633
 
603
- if options[:back]
634
+ if options[:at]
635
+ finish_date = wwid.chronify(options[:at])
636
+ exit_now! 'Unable to parse date string for --at' if finish_date.nil?
637
+
638
+ date = options[:took] ? finish_date - took : finish_date
639
+ elsif options[:back]
604
640
  date = wwid.chronify(options[:back])
605
641
 
606
642
  exit_now! 'Unable to parse date string' if date.nil?
@@ -826,7 +862,7 @@ desc 'Mark last entry as highlighted'
826
862
  command [:mark, :flag] do |c|
827
863
  c.desc 'Section'
828
864
  c.arg_name 'NAME'
829
- c.flag %i[s section], default_value: wwid.current_section
865
+ c.flag %i[s section]
830
866
 
831
867
  c.desc 'Remove mark'
832
868
  c.switch %i[r remove], negatable: false, default_value: false
@@ -1386,7 +1422,11 @@ command :view do |c|
1386
1422
  wwid.guess_view(args[0])
1387
1423
  end
1388
1424
 
1389
- section = wwid.guess_section(options[:s]) || options[:s].cap_first if options[:s]
1425
+ if options[:section]
1426
+ section = wwid.guess_section(options[:section]) || options[:section].cap_first
1427
+ else
1428
+ section = wwid.config['current_section']
1429
+ end
1390
1430
 
1391
1431
  view = wwid.get_view(title)
1392
1432
  if view
@@ -1553,6 +1593,48 @@ command :archive do |c|
1553
1593
  end
1554
1594
  end
1555
1595
 
1596
+ desc 'Move entries to archive file'
1597
+ command :rotate do |c|
1598
+ c.desc 'How many items to keep in each section (most recent)'
1599
+ c.arg_name 'X'
1600
+ c.flag %i[k keep], must_match: /^\d+$/, type: Integer
1601
+
1602
+ c.desc 'Section to rotate'
1603
+ c.arg_name 'SECTION_NAME'
1604
+ c.flag %i[s section], default_value: 'All'
1605
+
1606
+ c.desc 'Tag filter, combine multiple tags with a comma. Added for compatibility with other commands.'
1607
+ c.arg_name 'TAG'
1608
+ c.flag [:tag]
1609
+
1610
+ c.desc 'Tag boolean (AND|OR|NOT)'
1611
+ c.arg_name 'BOOLEAN'
1612
+ c.flag [:bool], must_match: /(?:and|all|any|or|not|none)/i, default_value: 'AND'
1613
+
1614
+ c.desc 'Search filter'
1615
+ c.arg_name 'QUERY'
1616
+ c.flag [:search]
1617
+
1618
+ c.action do |_global_options, options, args|
1619
+ if options[:section] && options[:section] !~ /^all$/i
1620
+ options[:section] = wwid.guess_section(options[:section])
1621
+ end
1622
+
1623
+ options[:bool] = case options[:bool]
1624
+ when /(and|all)/i
1625
+ 'AND'
1626
+ when /(any|or)/i
1627
+ 'OR'
1628
+ when /(not|none)/i
1629
+ 'NOT'
1630
+ else
1631
+ 'AND'
1632
+ end
1633
+
1634
+ wwid.rotate(options)
1635
+ end
1636
+ end
1637
+
1556
1638
  desc 'Open the "doing" file in an editor'
1557
1639
  long_desc "`doing open` defaults to using the editor_app setting in #{wwid.config_file} (#{wwid.config.key?('editor_app') ? wwid.config['editor_app'] : 'not set'})"
1558
1640
  command :open do |c|
@@ -1662,12 +1744,15 @@ command :import do |c|
1662
1744
 
1663
1745
  c.desc 'Target section'
1664
1746
  c.arg_name 'NAME'
1665
- c.flag %i[s section], default_value: wwid.current_section
1747
+ c.flag %i[s section]
1666
1748
 
1667
1749
  c.desc 'Tag all imported entries'
1668
1750
  c.arg_name 'TAGS'
1669
1751
  c.flag :tag
1670
1752
 
1753
+ c.desc 'Autotag entries'
1754
+ c.switch :autotag, negatable: true, default_value: true
1755
+
1671
1756
  c.desc 'Prefix entries with'
1672
1757
  c.arg_name 'PREFIX'
1673
1758
  c.flag :prefix
@@ -1677,11 +1762,22 @@ command :import do |c|
1677
1762
 
1678
1763
  c.action do |_global_options, options, args|
1679
1764
 
1680
- section = wwid.guess_section(options[:s]) || options[:s].cap_first
1765
+ if options[:section]
1766
+ section = wwid.guess_section(options[:section]) || options[:section].cap_first
1767
+ else
1768
+ section = wwid.config['current_section']
1769
+ end
1681
1770
 
1682
1771
  if options[:type] =~ /^tim/i
1683
1772
  args.each do |path|
1684
- wwid.import_timing(path, { section: section, tag: options[:tag], prefix: options[:prefix], no_overlap: !options[:overlap] })
1773
+ options = {
1774
+ autotag: options[:autotag],
1775
+ no_overlap: !options[:overlap],
1776
+ prefix: options[:prefix],
1777
+ section: section,
1778
+ tag: options[:tag]
1779
+ }
1780
+ wwid.import_timing(path, options)
1685
1781
  wwid.write(wwid.doing_file)
1686
1782
  end
1687
1783
  else
data/lib/doing/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Doing
2
- VERSION = '1.0.83'
2
+ VERSION = '1.0.84'
3
3
  end
data/lib/doing/wwid.rb CHANGED
@@ -425,8 +425,8 @@ class WWID
425
425
  ## @param guessed (Boolean) already guessed and failed
426
426
  ##
427
427
  def guess_section(frag, guessed: false)
428
- return 'All' if frag =~ /all/i
429
-
428
+ return 'All' if frag =~ /^all$/i
429
+ frag ||= @current_section
430
430
  sections.each { |section| return section.cap_first if frag.downcase == section.downcase }
431
431
  section = false
432
432
  re = frag.split('').join('.*?')
@@ -627,6 +627,7 @@ class WWID
627
627
  def import_timing(path, opt = {})
628
628
  section = opt[:section] || @current_section
629
629
  opt[:no_overlap] ||= false
630
+ opt[:autotag] ||= @auto_tag
630
631
 
631
632
  add_section(section) unless @content.has_key?(section)
632
633
 
@@ -657,7 +658,7 @@ class WWID
657
658
  title += " @#{tag}"
658
659
  end
659
660
  end
660
- title = autotag(title) if @auto_tag
661
+ title = autotag(title) if opt[:autotag]
661
662
  title += " @done(#{end_time.strftime('%Y-%m-%d %H:%M')})"
662
663
  title.gsub!(/ +/, ' ')
663
664
  title.strip!
@@ -1521,6 +1522,77 @@ class WWID
1521
1522
  end
1522
1523
  end
1523
1524
 
1525
+ ##
1526
+ ## @brief Rename doing file with date and start fresh one
1527
+ ##
1528
+ def rotate(opt = {})
1529
+ count = opt[:keep] || 0
1530
+ tags = []
1531
+ tags.concat(opt[:tag].split(/ *, */).map { |t| t.sub(/^@/, '').strip }) if opt[:tag]
1532
+ bool = opt[:bool] || :and
1533
+ sect = opt[:section] !~ /^all$/i ? guess_section(opt[:section]) : 'all'
1534
+
1535
+ if sect =~ /^all$/i
1536
+ all_sections = sections.dup
1537
+ else
1538
+ all_sections = [sect]
1539
+ end
1540
+
1541
+ counter = 0
1542
+ new_content = {}
1543
+
1544
+
1545
+ all_sections.each do |section|
1546
+ items = @content[section]['items'].dup
1547
+ new_content[section] = {}
1548
+ new_content[section]['original'] = @content[section]['original']
1549
+ new_content[section]['items'] = []
1550
+
1551
+ moved_items = []
1552
+ if !tags.empty? || opt[:search]
1553
+ items.delete_if do |item|
1554
+ if ((!tags.empty? && item.has_tags?(tags, bool)) || (opt[:search] && item.matches_search?(opt[:search].to_s)))
1555
+ moved_items.push(item)
1556
+ counter += 1
1557
+ true
1558
+ else
1559
+ false
1560
+ end
1561
+ end
1562
+ @content[section]['items'] = items
1563
+ new_content[section]['items'] = moved_items
1564
+ @results.push("Rotated #{moved_items.length} items from #{section}")
1565
+ else
1566
+ new_content[section]['items'] = []
1567
+ moved_items = []
1568
+
1569
+ count = items.length if items.length < count
1570
+
1571
+ if items.count > count
1572
+ moved_items.concat(items[count..-1])
1573
+ else
1574
+ moved_items.concat(items)
1575
+ end
1576
+
1577
+ @content[section]['items'] = if count.zero?
1578
+ []
1579
+ else
1580
+ items[0..count - 1]
1581
+ end
1582
+ new_content[section]['items'] = moved_items
1583
+
1584
+ @results.push("Rotated #{items.length - count} items from #{section}")
1585
+ end
1586
+ end
1587
+
1588
+ write(@doing_file)
1589
+
1590
+ file = @doing_file.sub(/(\.\w+)$/, "_#{Time.now.strftime('%Y-%m-%d%H:%M')}\\1")
1591
+ @content = new_content
1592
+
1593
+ write(file)
1594
+ end
1595
+
1524
1596
  ##
1525
1597
  ## @brief Generate a menu of sections and allow user selection
1526
1598
  ##
@@ -1925,7 +1997,7 @@ class WWID
1925
1997
  ## @param section (String) The source section
1926
1998
  ## @param options (Hash) Options
1927
1999
  ##
1928
- def archive(section = 'Currently', options = {})
2000
+ def archive(section = @current_section, options = {})
1929
2001
  count = options[:keep] || 0
1930
2002
  destination = options[:destination] || 'Archive'
1931
2003
  tags = options[:tags] || []
@@ -1984,7 +2056,7 @@ class WWID
1984
2056
  end
1985
2057
  end
1986
2058
  moved_items.each do |item|
1987
- if label && section != 'Currently'
2059
+ if label && section != @current_section
1988
2060
  item['title'] =
1989
2061
  item['title'].sub(/(?:@from\(.*?\))?(.*)$/, "\\1 @from(#{section})")
1990
2062
  end
@@ -1997,7 +2069,7 @@ class WWID
1997
2069
  count = items.length if items.length < count
1998
2070
 
1999
2071
  items.map! do |item|
2000
- if label && section != 'Currently'
2072
+ if label && section != @current_section
2001
2073
  item['title'] =
2002
2074
  item['title'].sub(/(?:@from\(.*?\))?(.*)$/, "\\1 @from(#{section})")
2003
2075
  end
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.83
4
+ version: 1.0.84
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-13 00:00:00.000000000 Z
11
+ date: 2021-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake