doing 2.1.3 → 2.1.4pre

Sign up to get free protection for your applications and to get access to all the features.
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: