doing 2.1.3 → 2.1.4pre

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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.yardoc/checksums +13 -10
  3. data/.yardoc/object_types +0 -0
  4. data/.yardoc/objects/root.dat +0 -0
  5. data/CHANGELOG.md +27 -0
  6. data/Gemfile.lock +23 -1
  7. data/README.md +1 -1
  8. data/bin/doing +253 -63
  9. data/doc/Array.html +1 -1
  10. data/doc/Doing/Color.html +1 -1
  11. data/doc/Doing/Completion.html +1 -1
  12. data/doc/Doing/Configuration.html +42 -1
  13. data/doc/Doing/Errors/DoingNoTraceError.html +1 -1
  14. data/doc/Doing/Errors/DoingRuntimeError.html +1 -1
  15. data/doc/Doing/Errors/DoingStandardError.html +1 -1
  16. data/doc/Doing/Errors/EmptyInput.html +1 -1
  17. data/doc/Doing/Errors/NoResults.html +1 -1
  18. data/doc/Doing/Errors/PluginException.html +1 -1
  19. data/doc/Doing/Errors/UserCancelled.html +1 -1
  20. data/doc/Doing/Errors/WrongCommand.html +1 -1
  21. data/doc/Doing/Errors.html +1 -1
  22. data/doc/Doing/Hooks.html +1 -1
  23. data/doc/Doing/Item.html +37 -3
  24. data/doc/Doing/Items.html +35 -1
  25. data/doc/Doing/LogAdapter.html +1 -1
  26. data/doc/Doing/Note.html +1 -1
  27. data/doc/Doing/Pager.html +1 -1
  28. data/doc/Doing/Plugins.html +1 -1
  29. data/doc/Doing/Prompt.html +35 -1
  30. data/doc/Doing/Section.html +1 -1
  31. data/doc/Doing/Util.html +16 -4
  32. data/doc/Doing/WWID.html +131 -71
  33. data/doc/Doing.html +3 -3
  34. data/doc/GLI/Commands/MarkdownDocumentListener.html +1 -1
  35. data/doc/GLI/Commands.html +1 -1
  36. data/doc/GLI.html +1 -1
  37. data/doc/Hash.html +1 -1
  38. data/doc/Status.html +1 -1
  39. data/doc/String.html +104 -2
  40. data/doc/Symbol.html +1 -1
  41. data/doc/Time.html +70 -2
  42. data/doc/_index.html +125 -4
  43. data/doc/class_list.html +1 -1
  44. data/doc/file.README.html +2 -2
  45. data/doc/index.html +2 -2
  46. data/doc/method_list.html +480 -144
  47. data/doc/top-level-namespace.html +2 -2
  48. data/doing.gemspec +2 -0
  49. data/doing.rdoc +155 -66
  50. data/lib/doing/boolean_term_parser.rb +86 -0
  51. data/lib/doing/configuration.rb +13 -4
  52. data/lib/doing/item.rb +94 -8
  53. data/lib/doing/items.rb +6 -0
  54. data/lib/doing/phrase_parser.rb +124 -0
  55. data/lib/doing/prompt.rb +8 -0
  56. data/lib/doing/string.rb +16 -2
  57. data/lib/doing/string_chronify.rb +5 -1
  58. data/lib/doing/time.rb +32 -0
  59. data/lib/doing/util.rb +2 -5
  60. data/lib/doing/util_backup.rb +235 -0
  61. data/lib/doing/version.rb +1 -1
  62. data/lib/doing/wwid.rb +81 -26
  63. data/lib/doing.rb +6 -0
  64. metadata +47 -4
data/lib/doing/wwid.rb CHANGED
@@ -183,7 +183,25 @@ module Doing
183
183
 
184
184
  date = nil
185
185
  iso_rx = /\d{4}-\d\d-\d\d \d\d:\d\d/
186
- done_rx = /(?<=^| )@(?<tag>done|finished|completed?)\((?<date>.*?)\)/i
186
+ watch_tags = [
187
+ 'start(?:ed)?',
188
+ 'beg[ia]n',
189
+ 'done',
190
+ 'finished',
191
+ 'completed?',
192
+ 'waiting',
193
+ 'defer(?:red)?'
194
+ ]
195
+ if @config['date_tags']
196
+ date_tags = @config['date_tags']
197
+ date_tags = date_tags.split(/ *, */) if date_tags.is_a?(String)
198
+ date_tags.map! do |tag|
199
+ tag.sub(/^@/, '').gsub(/\((?!\?:)(.*?)\)/, '(?:\1)').strip
200
+ end
201
+ watch_tags.concat(date_tags).uniq!
202
+ end
203
+
204
+ done_rx = /(?<=^| )@(?<tag>#{watch_tags.join('|')})\((?<date>.*?)\)/i
187
205
  date_rx = /^(?:\s*- )?(?<date>.*?) \| (?=\S)/
188
206
 
189
207
  title.gsub!(done_rx) do
@@ -423,8 +441,9 @@ module Doing
423
441
  # @param item [Item] the item to reset/resume
424
442
  # @param resume [Boolean] removing @done tag if true
425
443
  #
426
- def reset_item(item, resume: false)
427
- item.date = Time.now
444
+ def reset_item(item, date: nil, resume: false)
445
+ date ||= Time.now
446
+ item.date = date
428
447
  item.tag('done', remove: true) if resume
429
448
  logger.info('Reset:', %(Reset #{resume ? 'and resumed ' : ''} "#{item.title}" in #{item.section}))
430
449
  item
@@ -528,10 +547,25 @@ module Doing
528
547
  last_entry
529
548
  end
530
549
 
531
- def all_tags(items, opt: {})
532
- all_tags = []
533
- items.each { |item| all_tags.concat(item.tags).uniq! }
534
- all_tags.sort
550
+ def all_tags(items, opt: {}, counts: false)
551
+ if counts
552
+ all_tags = {}
553
+ items.each do |item|
554
+ item.tags.each do |tag|
555
+ if all_tags.key?(tag.downcase)
556
+ all_tags[tag.downcase] += 1
557
+ else
558
+ all_tags[tag.downcase] = 1
559
+ end
560
+ end
561
+ end
562
+
563
+ all_tags.sort_by { |tag, count| count }
564
+ else
565
+ all_tags = []
566
+ items.each { |item| all_tags.concat(item.tags.map(&:downcase)).uniq! }
567
+ all_tags.sort
568
+ end
535
569
  end
536
570
 
537
571
  def tag_groups(items, opt: {})
@@ -656,6 +690,7 @@ module Doing
656
690
  end
657
691
 
658
692
  if keep && opt[:tag]
693
+ opt[:tag_bool] = opt[:bool].normalize_bool if opt[:bool]
659
694
  opt[:tag_bool] ||= :and
660
695
  tag_match = opt[:tag].nil? || opt[:tag].empty? ? true : item.tags?(opt[:tag], opt[:tag_bool])
661
696
  keep = false unless tag_match
@@ -666,7 +701,7 @@ module Doing
666
701
  search_match = if opt[:search].nil? || opt[:search].empty?
667
702
  true
668
703
  else
669
- item.search(opt[:search], case_type: opt[:case].normalize_case, fuzzy: opt[:fuzzy])
704
+ item.search(opt[:search], case_type: opt[:case].normalize_case)
670
705
  end
671
706
 
672
707
  keep = false unless search_match
@@ -708,7 +743,7 @@ module Doing
708
743
 
709
744
  keep = false if keep && opt[:only_timed] && !item.interval
710
745
 
711
- if keep && opt[:tag_filter] && !opt[:tag_filter]['tags'].empty?
746
+ if keep && opt[:tag_filter]
712
747
  keep = item.tags?(opt[:tag_filter]['tags'], opt[:tag_filter]['bool'])
713
748
  keep = opt[:not] ? !keep : keep
714
749
  end
@@ -914,12 +949,19 @@ module Doing
914
949
  if opt[:resume] && !opt[:reset]
915
950
  repeat_item(item, { editor: opt[:editor] })
916
951
  elsif opt[:reset]
952
+ res = Prompt.enter_text('Start date (blank for current time)', default_response: '')
953
+ if res =~ /^ *$/
954
+ date = Time.now
955
+ else
956
+ date = res.chronify(guess: :begin)
957
+ end
958
+
917
959
  res = if item.tags?('done', :and) && !opt[:resume]
918
960
  opt[:force] ? true : Prompt.yn('Remove @done tag?', default_response: 'y')
919
961
  else
920
962
  opt[:resume]
921
963
  end
922
- @content.update_item(item, reset_item(item, resume: res))
964
+ @content.update_item(item, reset_item(item, date: date, resume: res))
923
965
  end
924
966
  write(@doing_file)
925
967
 
@@ -1309,20 +1351,6 @@ module Doing
1309
1351
  end
1310
1352
  end
1311
1353
 
1312
- ##
1313
- ## Restore a backed up version of a file
1314
- ##
1315
- ## @param file [String] The filepath to restore
1316
- ##
1317
- def restore_backup(file)
1318
- if File.exist?("#{file}~")
1319
- FileUtils.cp("#{file}~", file)
1320
- logger.warn('File update:', "Restored #{file.sub(/^#{Util.user_home}/, '~')}")
1321
- else
1322
- logger.error('Restore error:', 'No backup file found')
1323
- end
1324
- end
1325
-
1326
1354
  ##
1327
1355
  ## Rename doing file with date and start fresh one
1328
1356
  ##
@@ -1387,8 +1415,35 @@ module Doing
1387
1415
  ##
1388
1416
  ## @return [String] The selected section name
1389
1417
  ##
1390
- def choose_section
1391
- choice = Prompt.choose_from(@content.section_titles.sort, prompt: 'Choose a section > ', fzf_args: ['--height=60%'])
1418
+ def choose_section(include_all: false)
1419
+ options = @content.section_titles.sort
1420
+ options.unshift('All') if include_all
1421
+ choice = Prompt.choose_from(options, prompt: 'Choose a section > ', fzf_args: ['--height=60%'])
1422
+ choice ? choice.strip : choice
1423
+ end
1424
+
1425
+ ##
1426
+ ## Generate a menu of tags and allow user selection
1427
+ ##
1428
+ ## @return [String] The selected tag name
1429
+ ##
1430
+ def choose_tag(section = 'All', include_all: false)
1431
+ items = @content.in_section(section)
1432
+ tags = all_tags(items, counts: true).map { |t, c| "@#{t} (#{c})" }
1433
+ tags.unshift('No tag filter') if include_all
1434
+ choice = Prompt.choose_from(tags, sorted: false, multiple: true, prompt: 'Choose a tag > ', fzf_args: ['--height=60%'])
1435
+ choice ? choice.split(/\n/).map { |t| t.strip.sub(/ \(.*?\)$/, '')}.join(' ') : choice
1436
+ end
1437
+
1438
+ ##
1439
+ ## Generate a menu of sections and tags and allow user selection
1440
+ ##
1441
+ ## @return [String] The selected section or tag name
1442
+ ##
1443
+ def choose_section_tag
1444
+ options = @content.section_titles.sort
1445
+ options.concat(@content.all_tags.sort.map { |t| "@#{t}" })
1446
+ choice = Prompt.choose_from(options, prompt: 'Choose a section or tag > ', fzf_args: ['--height=60%'])
1392
1447
  choice ? choice.strip : choice
1393
1448
  end
1394
1449
 
data/lib/doing.rb CHANGED
@@ -6,9 +6,12 @@ require 'yaml'
6
6
  require 'pp'
7
7
  require 'csv'
8
8
  require 'tempfile'
9
+ require 'zlib'
10
+ require 'base64'
9
11
  require 'chronic'
10
12
  require 'tty-link'
11
13
  require 'tty-which'
14
+ require 'tty-markdown'
12
15
  # require 'amatch'
13
16
  require 'haml'
14
17
  require 'json'
@@ -22,6 +25,7 @@ require 'doing/time'
22
25
  require 'doing/array'
23
26
  require 'doing/symbol'
24
27
  require 'doing/util'
28
+ require 'doing/util_backup'
25
29
  require 'doing/configuration'
26
30
  require 'doing/section'
27
31
  require 'doing/items'
@@ -35,6 +39,8 @@ require 'doing/hooks'
35
39
  require 'doing/plugin_manager'
36
40
  require 'doing/pager'
37
41
  require 'doing/completion'
42
+ require 'doing/boolean_term_parser'
43
+ require 'doing/phrase_parser'
38
44
  # require 'doing/markdown_document_listener'
39
45
 
40
46
  # Main doing module
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: 2.1.3
4
+ version: 2.1.4pre
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-12-16 00:00:00.000000000 Z
11
+ date: 2021-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: safe_yaml
@@ -326,6 +326,46 @@ dependencies:
326
326
  - - ">="
327
327
  - !ruby/object:Gem::Version
328
328
  version: 0.5.0
329
+ - !ruby/object:Gem::Dependency
330
+ name: tty-markdown
331
+ requirement: !ruby/object:Gem::Requirement
332
+ requirements:
333
+ - - "~>"
334
+ - !ruby/object:Gem::Version
335
+ version: '0.7'
336
+ - - ">="
337
+ - !ruby/object:Gem::Version
338
+ version: 0.7.0
339
+ type: :runtime
340
+ prerelease: false
341
+ version_requirements: !ruby/object:Gem::Requirement
342
+ requirements:
343
+ - - "~>"
344
+ - !ruby/object:Gem::Version
345
+ version: '0.7'
346
+ - - ">="
347
+ - !ruby/object:Gem::Version
348
+ version: 0.7.0
349
+ - !ruby/object:Gem::Dependency
350
+ name: parslet
351
+ requirement: !ruby/object:Gem::Requirement
352
+ requirements:
353
+ - - "~>"
354
+ - !ruby/object:Gem::Version
355
+ version: '2.0'
356
+ - - ">="
357
+ - !ruby/object:Gem::Version
358
+ version: 2.0.0
359
+ type: :runtime
360
+ prerelease: false
361
+ version_requirements: !ruby/object:Gem::Requirement
362
+ requirements:
363
+ - - "~>"
364
+ - !ruby/object:Gem::Version
365
+ version: '2.0'
366
+ - - ">="
367
+ - !ruby/object:Gem::Version
368
+ version: 2.0.0
329
369
  description: A tool for managing a TaskPaper-like file of recent activites. Perfect
330
370
  for the late-night hacker on too much caffeine to remember what they accomplished
331
371
  at 2 in the morning.
@@ -413,6 +453,7 @@ files:
413
453
  - lib/completion/doing.fish
414
454
  - lib/doing.rb
415
455
  - lib/doing/array.rb
456
+ - lib/doing/boolean_term_parser.rb
416
457
  - lib/doing/cli_status.rb
417
458
  - lib/doing/colors.rb
418
459
  - lib/doing/completion.rb
@@ -430,6 +471,7 @@ files:
430
471
  - lib/doing/markdown_document_listener.rb
431
472
  - lib/doing/note.rb
432
473
  - lib/doing/pager.rb
474
+ - lib/doing/phrase_parser.rb
433
475
  - lib/doing/plugin_manager.rb
434
476
  - lib/doing/plugins/export/csv_export.rb
435
477
  - lib/doing/plugins/export/html_export.rb
@@ -448,6 +490,7 @@ files:
448
490
  - lib/doing/symbol.rb
449
491
  - lib/doing/time.rb
450
492
  - lib/doing/util.rb
493
+ - lib/doing/util_backup.rb
451
494
  - lib/doing/version.rb
452
495
  - lib/doing/wwid.rb
453
496
  - lib/examples/commands/autotag.rb
@@ -581,9 +624,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
581
624
  version: '0'
582
625
  required_rubygems_version: !ruby/object:Gem::Requirement
583
626
  requirements:
584
- - - ">="
627
+ - - ">"
585
628
  - !ruby/object:Gem::Version
586
- version: '0'
629
+ version: 1.3.1
587
630
  requirements: []
588
631
  rubygems_version: 3.2.16
589
632
  signing_key: