doing 2.1.33 → 2.1.34

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 (96) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/Gemfile.lock +1 -1
  4. data/bin/commands/config.rb +9 -9
  5. data/bin/commands/done.rb +1 -1
  6. data/bin/commands/grep.rb +2 -29
  7. data/bin/commands/meanwhile.rb +1 -1
  8. data/bin/commands/now.rb +1 -1
  9. data/bin/commands/on.rb +6 -16
  10. data/bin/commands/recent.rb +2 -14
  11. data/bin/commands/rotate.rb +17 -0
  12. data/bin/commands/sections.rb +82 -7
  13. data/bin/commands/show.rb +1 -21
  14. data/bin/commands/since.rb +5 -16
  15. data/bin/commands/today.rb +3 -28
  16. data/bin/commands/yesterday.rb +2 -35
  17. data/bin/doing +5 -6
  18. data/docs/doc/Array.html +1 -1
  19. data/docs/doc/BooleanTermParser/Clause.html +1 -1
  20. data/docs/doc/BooleanTermParser/Operator.html +1 -1
  21. data/docs/doc/BooleanTermParser/Query.html +1 -1
  22. data/docs/doc/BooleanTermParser/QueryParser.html +1 -1
  23. data/docs/doc/BooleanTermParser/QueryTransformer.html +1 -1
  24. data/docs/doc/BooleanTermParser.html +1 -1
  25. data/docs/doc/Doing/Color.html +1 -1
  26. data/docs/doc/Doing/Completion.html +1 -1
  27. data/docs/doc/Doing/Configuration.html +1 -1
  28. data/docs/doc/Doing/Errors/DoingNoTraceError.html +1 -1
  29. data/docs/doc/Doing/Errors/DoingRuntimeError.html +1 -1
  30. data/docs/doc/Doing/Errors/DoingStandardError.html +1 -1
  31. data/docs/doc/Doing/Errors/EmptyInput.html +1 -1
  32. data/docs/doc/Doing/Errors/NoResults.html +1 -1
  33. data/docs/doc/Doing/Errors/PluginException.html +1 -1
  34. data/docs/doc/Doing/Errors/UserCancelled.html +1 -1
  35. data/docs/doc/Doing/Errors/WrongCommand.html +1 -1
  36. data/docs/doc/Doing/Errors.html +1 -1
  37. data/docs/doc/Doing/Hooks.html +1 -1
  38. data/docs/doc/Doing/Item.html +20 -3
  39. data/docs/doc/Doing/Items.html +209 -1
  40. data/docs/doc/Doing/Logger.html +1807 -0
  41. data/docs/doc/Doing/Note.html +1 -1
  42. data/docs/doc/Doing/Pager.html +1 -1
  43. data/docs/doc/Doing/Plugins.html +1 -1
  44. data/docs/doc/Doing/Prompt.html +1 -1
  45. data/docs/doc/Doing/Section.html +1 -1
  46. data/docs/doc/Doing/TemplateString.html +1 -1
  47. data/docs/doc/Doing/Types.html +2 -2
  48. data/docs/doc/Doing/Util/Backup.html +1 -1
  49. data/docs/doc/Doing/Util.html +1 -1
  50. data/docs/doc/Doing/WWID.html +3 -53
  51. data/docs/doc/Doing.html +4 -4
  52. data/docs/doc/FalseClass.html +1 -1
  53. data/docs/doc/GLI/Commands/Help.html +1 -1
  54. data/docs/doc/GLI/Commands/MarkdownDocumentListener.html +1 -1
  55. data/docs/doc/GLI/Commands.html +1 -1
  56. data/docs/doc/GLI.html +1 -1
  57. data/docs/doc/Hash.html +1 -1
  58. data/docs/doc/Object.html +1 -1
  59. data/docs/doc/PhraseParser/Operator.html +1 -1
  60. data/docs/doc/PhraseParser/PhraseClause.html +1 -1
  61. data/docs/doc/PhraseParser/Query.html +1 -1
  62. data/docs/doc/PhraseParser/QueryParser.html +1 -1
  63. data/docs/doc/PhraseParser/QueryTransformer.html +1 -1
  64. data/docs/doc/PhraseParser/TermClause.html +1 -1
  65. data/docs/doc/PhraseParser.html +1 -1
  66. data/docs/doc/Status.html +1 -1
  67. data/docs/doc/String.html +1 -1
  68. data/docs/doc/Symbol.html +1 -1
  69. data/docs/doc/Time.html +1 -1
  70. data/docs/doc/TrueClass.html +1 -1
  71. data/docs/doc/_index.html +10 -10
  72. data/docs/doc/class_list.html +1 -1
  73. data/docs/doc/file.README.html +1 -1
  74. data/docs/doc/index.html +1 -1
  75. data/docs/doc/method_list.html +407 -383
  76. data/docs/doc/top-level-namespace.html +1 -1
  77. data/doing.rdoc +229 -17
  78. data/lib/completion/_doing.zsh +11 -15
  79. data/lib/completion/doing.bash +12 -23
  80. data/lib/completion/doing.fish +38 -12
  81. data/lib/doing/add_options.rb +36 -1
  82. data/lib/doing/chronify/string.rb +1 -1
  83. data/lib/doing/item.rb +9 -2
  84. data/lib/doing/items.rb +48 -0
  85. data/lib/doing/{log_adapter.rb → logger.rb} +8 -2
  86. data/lib/doing/plugins/import/calendar_import.rb +1 -1
  87. data/lib/doing/plugins/import/doing_import.rb +1 -1
  88. data/lib/doing/plugins/import/timing_import.rb +1 -1
  89. data/lib/doing/string/tags.rb +1 -1
  90. data/lib/doing/types.rb +1 -1
  91. data/lib/doing/version.rb +1 -1
  92. data/lib/doing/wwid.rb +43 -43
  93. data/lib/doing.rb +4 -3
  94. data/lib/examples/plugins/capture_thing_import.rb +1 -1
  95. metadata +4 -4
  96. data/bin/commands/add_section.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce292893553246aabe46ccbabe4bfe508107e43e74ec78f52f617504d80d2304
4
- data.tar.gz: 32039a7f2af7742f57955fd20424fca0a3f4ef382dc2dccf0bff43044e937d3a
3
+ metadata.gz: e42589eab6439f41b35af5350d17f553a08956ef891c3f358c5aa1dcced7b665
4
+ data.tar.gz: 29094627b77593714a4baa25fb315b76efc951e0195f9c22cf36dd7d93f54827
5
5
  SHA512:
6
- metadata.gz: 2c567803b19db9141e602600d1ef26a59d7d5ac467d6b006fa05d8ead16e6a1fde636515c7515d1fe5325acd1eff622ee5488f97ab4c4017ccddfd4785ac7ea9
7
- data.tar.gz: dac1f74ea6992cd368b6f6012b5edcbb237a016df323540962b3d0702634874f1fa62f18ce32d334b4c18c99e387512085bc7e44c3189b4810ac50e00e834f83
6
+ metadata.gz: 8454793d8a71346f17029a8e60acf1f5b47813d838dda5fa79841e5e5606a310f702bc4a61185c922b2b78af6a653ac9f946274a071678b9fe7f682fffc26cb1
7
+ data.tar.gz: 39db99c92d185fd802e0966988ecc70036052f0850c19c2e8c86bdf7881100d3ad0d57660a56cdeb5df3be7a81bed9b87adf3f4a91fcf2fb239489fdb17fc9af
data/CHANGELOG.md CHANGED
@@ -1,3 +1,26 @@
1
+ ### 2.1.34
2
+
3
+ 2022-02-20 09:32
4
+
5
+ #### IMPROVED
6
+
7
+ - Allow `--from 8am` time range without end time to mean `8am to 11:59pm`
8
+ - `--tag_order` for commands with `--totals` output that were missing it
9
+ - Tag and search filters for on, since, today and yesterday
10
+ - Time filters for today and yesterday
11
+ - `--only_timed` filter for yesterday
12
+ - `--only_timed` for today
13
+ - Remove exact duplicates from content before saving
14
+ - `doing sections` now has subcommands -- `sections list`, `sections add SECTION` (replaces `add_section`) and `sections remove SECTION` allows removal of a section and archiving of its contents
15
+
16
+ #### FIXED
17
+
18
+ - `doing yesterday --from` not filtering time range
19
+ - Don't return a duration or interval for entries configured as never_time or never_finish
20
+ - `--from` time filter for yesterday
21
+ - Regex error in `doing archive`
22
+ - `--times` error in `doing today`
23
+
1
24
  ### 2.1.33
2
25
 
3
26
  2022-02-18 12:09
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- doing (2.1.33)
4
+ doing (2.1.34)
5
5
  chronic (~> 0.10, >= 0.10.2)
6
6
  deep_merge (~> 1.2, >= 1.2.1)
7
7
  gli (~> 2.20, >= 2.20.1)
@@ -43,7 +43,7 @@ command :config do |c|
43
43
 
44
44
  edit.desc 'Editor to use'
45
45
  edit.arg_name 'EDITOR'
46
- edit.flag %i[e editor], default_value: nil
46
+ edit.flag %i[e editor]
47
47
 
48
48
  if Sys::Platform.mac?
49
49
  edit.desc 'Application to use'
@@ -54,8 +54,8 @@ command :config do |c|
54
54
  edit.arg_name 'BUNDLE_ID'
55
55
  edit.flag %i[b bundle_id]
56
56
 
57
- edit.desc "Use the config_editor_app defined in ~/.config/doing/config.yml (#{@settings.key?('config_editor_app') ? @settings['config_editor_app'] : 'config_editor_app not set'})"
58
- edit.switch %i[x default]
57
+ edit.desc "Use the config editor defined in ~/.config/doing/config.yml (#{Doing.setting('editors.config', 'editors.config not set')})"
58
+ edit.switch %i[x default], negatable: false
59
59
  end
60
60
 
61
61
  edit.action do |global, options, args|
@@ -205,7 +205,7 @@ command :config do |c|
205
205
  value = options[:remove] ? nil : args.pop
206
206
  keypath = args.join('.')
207
207
  real_path = Doing.config.resolve_key_path(keypath, create: true)
208
- old_value = @settings.dig(*real_path)
208
+ old_value = Doing.config.settings.dig(*real_path)
209
209
  old_type = old_value&.class.to_s || nil
210
210
 
211
211
  if old_value.is_a?(Hash) && !options[:remove]
@@ -223,7 +223,7 @@ command :config do |c|
223
223
 
224
224
  cfg = Doing::Util.safe_load_file(config_file) || {}
225
225
 
226
- $stderr.puts "Updating #{config_file}".yellow
226
+ $stderr.puts "> Config: Updating #{config_file}".yellow
227
227
 
228
228
  if options[:remove]
229
229
  cfg.deep_set(real_path, nil)
@@ -231,10 +231,10 @@ command :config do |c|
231
231
  else
232
232
  current_value = cfg.dig(*real_path)
233
233
  cfg.deep_set(real_path, value.set_type(old_type))
234
- $stderr.puts "#{' Key path:'.yellow} #{real_path.join('.').boldwhite}"
235
- $stderr.puts "#{'Inherited:'.yellow} #{(old_value ? old_value.to_s : 'empty').boldwhite}"
236
- $stderr.puts "#{' Current:'.yellow} #{ (current_value ? current_value.to_s : 'empty').boldwhite }"
237
- $stderr.puts "#{' New:'.yellow} #{value.set_type(old_type).to_s.boldwhite}"
234
+ $stderr.puts "#{' Key path:'.yellow} #{real_path.join('.').boldwhite}"
235
+ $stderr.puts "#{' Inherited:'.yellow} #{(old_value ? old_value.to_s : 'empty').boldwhite}"
236
+ $stderr.puts "#{' Current:'.yellow} #{ (current_value ? current_value.to_s : 'empty').boldwhite }"
237
+ $stderr.puts "#{' New:'.yellow} #{value.set_type(old_type).to_s.boldwhite}"
238
238
  end
239
239
 
240
240
  res = Doing::Prompt.yn('Update selected config', default_response: true)
data/bin/commands/done.rb CHANGED
@@ -47,7 +47,7 @@ command %i[done did] do |c|
47
47
  add_options(:add_entry, c)
48
48
 
49
49
  c.action do |_global_options, options, args|
50
- @wwid.auto_tag = !options[:noauto]
50
+ Doing.auto_tag = !options[:noauto]
51
51
 
52
52
  took = 0
53
53
  donedate = nil
data/bin/commands/grep.rb CHANGED
@@ -28,31 +28,12 @@ command %i[grep search] do |c|
28
28
  c.arg_name 'TEMPLATE_STRING'
29
29
  c.flag [:template]
30
30
 
31
- c.desc 'Show time intervals on @done tasks'
32
- c.switch %i[t times], default_value: true, negatable: true
33
-
34
- c.desc 'Show elapsed time on entries without @done tag'
35
- c.switch [:duration]
36
-
37
- c.desc 'Show intervals with totals at the end of output'
38
- c.switch [:totals], default_value: false, negatable: false
39
-
40
- c.desc 'Sort tags by (name|time)'
41
- default = Doing.setting('tag_sort').normalize_tag_sort || :name
42
- c.arg_name 'KEY'
43
- c.flag [:tag_sort], must_match: REGEX_TAG_SORT, default_value: default, type: TagSortSymbol
44
-
45
- c.desc 'Only show items with recorded time intervals'
46
- c.switch [:only_timed], default_value: false, negatable: false
47
-
48
31
  # c.desc '[DEPRECATED] Use alternative fuzzy matching for search string'
49
32
  # c.switch [:fuzzy], default_value: false, negatable: false
50
33
 
51
34
  c.desc 'Force exact string matching (case sensitive)'
52
35
  c.switch %i[x exact], default_value: Doing.config.exact_match?, negatable: Doing.config.exact_match?
53
36
 
54
- c.desc 'Show items that *don\'t* match search string'
55
- c.switch [:not], default_value: false, negatable: false
56
37
 
57
38
  c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
58
39
  c.arg_name 'TYPE'
@@ -72,17 +53,9 @@ command %i[grep search] do |c|
72
53
  c.desc 'Display an interactive menu of results to perform further operations'
73
54
  c.switch %i[i interactive], default_value: false, negatable: false
74
55
 
75
- c.desc 'Perform a tag value query ("@done > two hours ago" or "@progress < 50"). May be used multiple times, combined with --bool'
76
- c.arg_name 'QUERY'
77
- c.flag [:val], multiple: true, must_match: REGEX_VALUE_QUERY
78
-
79
- c.desc 'Combine multiple tags or value queries using AND, OR, or NOT'
80
- c.arg_name 'BOOLEAN'
81
- c.flag [:bool], must_match: REGEX_BOOL,
82
- default_value: :pattern,
83
- type: BooleanSymbol
84
-
56
+ add_options(:tag_filter, c)
85
57
  add_options(:date_filter, c)
58
+ add_options(:time_display, c)
86
59
 
87
60
  c.action do |_global_options, options, args|
88
61
  options[:fuzzy] = false
@@ -21,7 +21,7 @@ command :meanwhile do |c|
21
21
  add_options(:add_entry, c)
22
22
 
23
23
  c.action do |_global_options, options, args|
24
- @wwid.auto_tag = !options[:noauto]
24
+ Doing.auto_tag = !options[:noauto]
25
25
 
26
26
  if options[:back]
27
27
  date = options[:back]
data/bin/commands/now.rb CHANGED
@@ -37,7 +37,7 @@ command %i[now next] do |c|
37
37
  # # c.flag [:a, :app]
38
38
 
39
39
  c.action do |_global_options, options, args|
40
- @wwid.auto_tag = !options[:noauto]
40
+ Doing.auto_tag = !options[:noauto]
41
41
 
42
42
  raise InvalidArgument, '--back and --from cannot be used together' if options[:back] && options[:from]
43
43
 
data/bin/commands/on.rb CHANGED
@@ -13,20 +13,6 @@ command :on do |c|
13
13
  c.arg_name 'NAME'
14
14
  c.flag %i[s section], default_value: 'All'
15
15
 
16
- c.desc 'Show time intervals on @done tasks'
17
- c.switch %i[t times], default_value: true, negatable: true
18
-
19
- c.desc 'Show elapsed time on entries without @done tag'
20
- c.switch [:duration]
21
-
22
- c.desc 'Show time totals at the end of output'
23
- c.switch [:totals], default_value: false, negatable: false
24
-
25
- c.desc 'Sort tags by (name|time)'
26
- default = Doing.setting('tag_sort').normalize_tag_sort || :name
27
- c.arg_name 'KEY'
28
- c.flag [:tag_sort], must_match: REGEX_TAG_SORT, default_value: default, type: TagSortSymbol
29
-
30
16
  c.desc "Output to export format (#{Doing::Plugins.plugin_names(type: :export)})"
31
17
  c.arg_name 'FORMAT'
32
18
  c.flag %i[o output]
@@ -39,6 +25,11 @@ command :on do |c|
39
25
  c.arg_name 'TEMPLATE_STRING'
40
26
  c.flag [:template]
41
27
 
28
+ add_options(:time_display, c)
29
+ add_options(:search, c)
30
+ add_options(:tag_filter, c)
31
+ add_options(:time_filter, c)
32
+
42
33
  c.action do |_global_options, options, args|
43
34
  raise DoingRuntimeError, %(Invalid output type "#{options[:output]}") if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
44
35
 
@@ -59,7 +50,6 @@ command :on do |c|
59
50
  options[:times] = true if options[:totals]
60
51
  options[:sort_tags] = options[:tag_sort]
61
52
 
62
- Doing::Pager.page @wwid.list_date([start, finish], options[:section], options[:times], options[:output],
63
- { template: options[:template], config_template: options[:config_template], duration: options[:duration], totals: options[:totals], sort_tags: options[:sort_tags] }).chomp
53
+ Doing::Pager.page @wwid.list_date([start, finish], options[:section], options[:times], options[:output], options).chomp
64
54
  end
65
55
  end
@@ -12,9 +12,6 @@ command :recent do |c|
12
12
  c.arg_name 'NAME'
13
13
  c.flag %i[s section], default_value: 'All'
14
14
 
15
- c.desc 'Show time intervals on @done tasks'
16
- c.switch %i[t times], default_value: true, negatable: true
17
-
18
15
  c.desc "Output using a template from configuration"
19
16
  c.arg_name 'TEMPLATE_KEY'
20
17
  c.flag [:config_template], type: TemplateName, default_value: 'recent'
@@ -23,20 +20,11 @@ command :recent do |c|
23
20
  c.arg_name 'TEMPLATE_STRING'
24
21
  c.flag [:template]
25
22
 
26
- c.desc 'Show elapsed time on entries without @done tag'
27
- c.switch [:duration]
28
-
29
- c.desc 'Show intervals with totals at the end of output'
30
- c.switch [:totals], default_value: false, negatable: false
31
-
32
- c.desc 'Sort tags by (name|time)'
33
- default = Doing.setting('tag_sort').normalize_tag_sort || :name
34
- c.arg_name 'KEY'
35
- c.flag [:tag_sort], must_match: REGEX_TAG_SORT, default_value: default, type: TagSortSymbol
36
-
37
23
  c.desc 'Select from a menu of matching entries to perform additional operations'
38
24
  c.switch %i[i interactive], negatable: false, default_value: false
39
25
 
26
+ add_options(:time_display, c)
27
+
40
28
  c.action do |global_options, options, args|
41
29
  section = @wwid.guess_section(options[:section]) || options[:section].cap_first
42
30
 
@@ -40,3 +40,20 @@ command :rotate do |c|
40
40
  @wwid.rotate(options)
41
41
  end
42
42
  end
43
+
44
+ # # @@doctor
45
+
46
+ # desc 'Doing file maintenance.'
47
+ # long_desc %(Duplicate entries compressed to a single entry. This will modify the doing file.)
48
+ # command :doctor do |c|
49
+ # c.example 'doing doctor', desc: 'Clean up the Doing file, sorting and removing duplicates'
50
+
51
+ # c.desc 'Only remove duplicates in the same section'
52
+ # c.switch %i[s same_section], negatable: false, default_value: false
53
+
54
+ # c.action do |_global_options, options, _args|
55
+ # @wwid.content.dedup!(match_section: options[:same_section])
56
+ # @wwid.write(@wwid.doing_file)
57
+ # end
58
+ # end
59
+
@@ -1,11 +1,86 @@
1
- # @@sections
2
- desc 'List sections'
1
+ # frozen_string_literal: true
2
+
3
+ # @@add_section
4
+ desc 'List, add, or remove sections in the Doing file'
3
5
  command :sections do |c|
4
- c.desc 'List in single column'
5
- c.switch %i[c column], negatable: false, default_value: false
6
+ c.default_command :list
7
+
8
+ c.example 'doing sections add Ideas', desc: 'Add a section called Ideas to the doing file'
9
+ c.example 'doing sections remove Reminders', desc: 'Remove the section Reminders'
10
+ c.example 'doing sections list', desc: 'List all sections'
11
+
12
+ c.desc 'Add a section'
13
+ c.arg_name 'SECTION_NAME'
14
+ c.command :add do |add|
15
+ add.action do |_g, _o, args|
16
+ raise InvalidArgument, "Section #{args[0]} already exists" if @wwid.sections.include?(args[0])
17
+
18
+ @wwid.content.add_section(args.join(' ').cap_first, log: true)
19
+ @wwid.write(@wwid.doing_file)
20
+ end
21
+ end
22
+
23
+ c.desc 'List sections'
24
+ c.command :list do |list|
25
+ list.desc 'List in single column'
26
+ list.switch %i[c column], negatable: false, default_value: false
27
+
28
+ list.action do |_global_options, options, _args|
29
+ joiner = options[:column] ? "\n" : "\t"
30
+ print @wwid.content.section_titles.join(joiner)
31
+ end
32
+ end
33
+
34
+ c.desc 'Remove a section'
35
+ c.arg_name 'SECTION_NAME'
36
+ c.command :remove do |remove|
37
+ remove.desc 'Archive entries in section before deleting. --no-archive permanently deletes section contents'
38
+ remove.switch %i[a archive], default_value: true, negatable: true
39
+
40
+ remove.action do |_g, options, args|
41
+ raise InvalidArgument, '--delete cannot be used with --archive' if options[:delete] && options[:archive]
42
+
43
+ section = args[0].cap_first
44
+
45
+ unless @wwid.sections.include?(section)
46
+ Doing.logger.log_now(:warn, 'Section:', "#{section} not found, did you mean #{guess_section(section)}?")
47
+ raise InvalidArgument, "Section #{args[0]} doesn't exist"
6
48
 
7
- c.action do |_global_options, options, _args|
8
- joiner = options[:column] ? "\n" : "\t"
9
- print @wwid.content.section_titles.join(joiner)
49
+ end
50
+
51
+ items = @wwid.content.in_section(section)
52
+
53
+ if items.count.positive?
54
+ res = Doing::Prompt.yn("#{options[:archive] ? 'Archive' : 'Delete'} #{items.count} entries from #{section}", default_response: 'n')
55
+
56
+ if options[:archive] && res
57
+ @wwid.archive(section, {keep: 0})
58
+ elsif res
59
+ items.each { |item| @wwid.content.delete_item(item) }
60
+ end
61
+ end
62
+
63
+ @wwid.content.delete_section(section, log: true)
64
+
65
+ @wwid.write(@wwid.doing_file)
66
+ end
67
+ end
68
+ end
69
+
70
+ # For backward compatibility
71
+ # @@add_section
72
+ command :add_section do |c|
73
+ c.desc 'Archive entries in section before deleting'
74
+ c.switch %i[a archive], default_value: true, negatable: true
75
+
76
+ c.desc 'Permanently delete entries in section'
77
+ c.switch %i[d delete], default_value: false
78
+
79
+ c.action do |g, o, a|
80
+ cmd = commands[:sections].commands[:add]
81
+
82
+ action = cmd.send(:get_action, nil)
83
+ action.call(g, o, a)
10
84
  end
11
85
  end
86
+
data/bin/commands/show.rb CHANGED
@@ -33,27 +33,6 @@ command :show do |c|
33
33
  c.arg_name 'ORDER'
34
34
  c.flag %i[s sort], must_match: REGEX_SORT_ORDER, default_value: :asc, type: OrderSymbol
35
35
 
36
- c.desc 'Show time intervals on @done tasks'
37
- c.switch %i[t times], default_value: true, negatable: true
38
-
39
- c.desc 'Show elapsed time on entries without @done tag'
40
- c.switch [:duration]
41
-
42
- c.desc 'Show intervals with totals at the end of output'
43
- c.switch [:totals], default_value: false, negatable: false
44
-
45
- c.desc 'Sort tags by (name|time)'
46
- default = Doing.setting('tag_sort').normalize_tag_sort || :name
47
- c.arg_name 'KEY'
48
- c.flag [:tag_sort], must_match: REGEX_TAG_SORT, default_value: default, type: TagSortSymbol
49
-
50
- c.desc 'Tag sort direction (asc|desc)'
51
- c.arg_name 'DIRECTION'
52
- c.flag [:tag_order], must_match: REGEX_SORT_ORDER, default_value: :asc, type: OrderSymbol
53
-
54
- c.desc 'Only show items with recorded time intervals'
55
- c.switch [:only_timed], default_value: false, negatable: false
56
-
57
36
  c.desc "Output using a template from configuration"
58
37
  c.arg_name 'TEMPLATE_KEY'
59
38
  c.flag [:config_template], type: TemplateName, default_value: 'default'
@@ -72,6 +51,7 @@ command :show do |c|
72
51
  c.arg_name 'FORMAT'
73
52
  c.flag %i[o output]
74
53
 
54
+ add_options(:time_display, c)
75
55
  add_options(:search, c)
76
56
  add_options(:tag_filter, c)
77
57
  add_options(:date_filter, c)
@@ -11,20 +11,6 @@ command :since do |c|
11
11
  c.arg_name 'NAME'
12
12
  c.flag %i[s section], default_value: 'All'
13
13
 
14
- c.desc 'Show time intervals on @done tasks'
15
- c.switch %i[t times], default_value: true, negatable: true
16
-
17
- c.desc 'Show elapsed time on entries without @done tag'
18
- c.switch [:duration]
19
-
20
- c.desc 'Show time totals at the end of output'
21
- c.switch [:totals], default_value: false, negatable: false
22
-
23
- c.desc 'Sort tags by (name|time)'
24
- default = Doing.setting('tag_sort').normalize_tag_sort || :name
25
- c.arg_name 'KEY'
26
- c.flag [:tag_sort], must_match: REGEX_TAG_SORT, default_value: default, type: TagSortSymbol
27
-
28
14
  c.desc "Output to export format (#{Doing::Plugins.plugin_names(type: :export)})"
29
15
  c.arg_name 'FORMAT'
30
16
  c.flag %i[o output]
@@ -37,6 +23,10 @@ command :since do |c|
37
23
  c.arg_name 'TEMPLATE_STRING'
38
24
  c.flag [:template]
39
25
 
26
+ add_options(:time_display, c)
27
+ add_options(:tag_filter, c)
28
+ add_options(:search, c)
29
+
40
30
  c.action do |_global_options, options, args|
41
31
  raise DoingRuntimeError, %(Invalid output type "#{options[:output]}") if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
42
32
 
@@ -57,7 +47,6 @@ command :since do |c|
57
47
  options[:times] = true if options[:totals]
58
48
  options[:sort_tags] = options[:tag_sort]
59
49
 
60
- Doing::Pager.page @wwid.list_date([start, finish], options[:section], options[:times], options[:output],
61
- { template: options[:template], config_template: options[:config_template], duration: options[:duration], totals: options[:totals], sort_tags: options[:sort_tags] }).chomp
50
+ Doing::Pager.page @wwid.list_date([start, finish], options[:section], options[:times], options[:output], options).chomp
62
51
  end
63
52
  end
@@ -12,20 +12,6 @@ command :today do |c|
12
12
  c.arg_name 'NAME'
13
13
  c.flag %i[s section], default_value: 'All'
14
14
 
15
- c.desc 'Show time intervals on @done tasks'
16
- c.switch %i[t times], default_value: true, negatable: true
17
-
18
- c.desc 'Show elapsed time on entries without @done tag'
19
- c.switch [:duration]
20
-
21
- c.desc 'Show time totals at the end of output'
22
- c.switch [:totals], default_value: false, negatable: false
23
-
24
- c.desc 'Sort tags by (name|time)'
25
- default = Doing.setting('tag_sort').normalize_tag_sort || :name
26
- c.arg_name 'KEY'
27
- c.flag [:tag_sort], must_match: REGEX_TAG_SORT, default_value: default, type: TagSortSymbol
28
-
29
15
  c.desc "Output to export format (#{Doing::Plugins.plugin_names(type: :export)})"
30
16
  c.arg_name 'FORMAT'
31
17
  c.flag %i[o output]
@@ -38,26 +24,15 @@ command :today do |c|
38
24
  c.arg_name 'TEMPLATE_STRING'
39
25
  c.flag [:template]
40
26
 
41
- c.desc 'View entries before specified time (e.g. 8am, 12:30pm, 15:00)'
42
- c.arg_name 'TIME_STRING'
43
- c.flag [:before]
44
-
45
- c.desc 'View entries after specified time (e.g. 8am, 12:30pm, 15:00)'
46
- c.arg_name 'TIME_STRING'
47
- c.flag [:after]
48
-
49
- c.desc %(
50
- Time range to show `doing today --from "12pm to 4pm"`
51
- )
52
- c.arg_name 'TIME_RANGE'
53
- c.flag [:from], type: DateRangeString
27
+ add_options(:time_filter, c)
28
+ add_options(:time_display, c)
54
29
 
55
30
  c.action do |_global_options, options, _args|
56
31
  raise DoingRuntimeError, %(Invalid output type "#{options[:output]}") if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
57
32
 
58
33
  options[:times] = true if options[:totals]
59
34
  options[:sort_tags] = options[:tag_sort]
60
- filter_options = %i[after before duration from section sort_tags totals template config_template].each_with_object({}) { |k, hsh| hsh[k] = options[k] }
35
+ filter_options = %i[after before times duration from section sort_tags totals tag_order template config_template only_timed].each_with_object({}) { |k, hsh| hsh[k] = options[k] }
61
36
 
62
37
  Doing::Pager.page @wwid.today(options[:times], options[:output], filter_options).chomp
63
38
  end
@@ -23,47 +23,14 @@ command :yesterday do |c|
23
23
  c.arg_name 'TEMPLATE_STRING'
24
24
  c.flag [:template]
25
25
 
26
- c.desc 'Show time intervals on @done tasks'
27
- c.switch %i[t times], default_value: true, negatable: true
28
-
29
- c.desc 'Show elapsed time on entries without @done tag'
30
- c.switch [:duration]
31
-
32
- c.desc 'Show time totals at the end of output'
33
- c.switch [:totals], default_value: false, negatable: false
34
-
35
- c.desc 'Sort tags by (name|time)'
36
- default = Doing.setting('tag_sort').normalize_tag_sort || :name
37
- c.arg_name 'KEY'
38
- c.flag [:tag_sort], must_match: REGEX_TAG_SORT, default_value: default, type: TagSortSymbol
39
-
40
- c.desc 'View entries before specified time (e.g. 8am, 12:30pm, 15:00)'
41
- c.arg_name 'TIME_STRING'
42
- c.flag [:before]
43
-
44
- c.desc 'View entries after specified time (e.g. 8am, 12:30pm, 15:00)'
45
- c.arg_name 'TIME_STRING'
46
- c.flag [:after]
47
-
48
- c.desc 'Time range to show, e.g. `doing yesterday --from "1am to 8am"`'
49
- c.arg_name 'TIME_RANGE'
50
- c.flag [:from], must_match: REGEX_TIME_RANGE
51
-
52
- c.desc 'Tag sort direction (asc|desc)'
53
- c.arg_name 'DIRECTION'
54
- c.flag [:tag_order], must_match: REGEX_SORT_ORDER, default_value: :asc, type: OrderSymbol
26
+ add_options(:time_filter, c)
27
+ add_options(:time_display, c)
55
28
 
56
29
  c.action do |_global_options, options, _args|
57
30
  raise DoingRuntimeError, %(Invalid output type "#{options[:output]}") if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
58
31
 
59
32
  options[:sort_tags] = options[:tag_sort]
60
33
 
61
- if options[:from]
62
- options[:from] = options[:from].split(/#{REGEX_RANGE_INDICATOR}/).map do |time|
63
- "yesterday #{time.sub(/(?mi)(^.*?(?=\d+)|(?<=[ap]m).*?$)/, '')}"
64
- end.join(' to ').split_date_range
65
- end
66
-
67
34
  opt = options.clone
68
35
  opt[:order] = Doing.setting(['templates', options[:config_template], 'order'])
69
36
 
data/bin/doing CHANGED
@@ -63,7 +63,6 @@ Doing.set('backup_dir', ENV['DOING_BACKUP_DIR']) if ENV['DOING_BACKUP_DIR']
63
63
 
64
64
  # Set up class vars for backwards compatibility
65
65
  @settings = Doing.settings
66
- @wwid.config = Doing.settings
67
66
 
68
67
  accept BooleanSymbol do |value|
69
68
  value.normalize_bool(:pattern)
@@ -144,8 +143,6 @@ accept TagArray do |value|
144
143
  value.gsub(/[, ]+/, ' ').split(' ').map { |tag| tag.sub(/^@/, '') }.map(&:strip)
145
144
  end
146
145
 
147
- commands_from File.expand_path(Doing.setting('plugins.command_path')) if Doing.setting('plugins.command_path')
148
-
149
146
  program_desc 'A CLI for a What Was I Doing system'
150
147
  program_long_desc %(Doing uses a TaskPaper-like formatting to keep a plain text
151
148
  record of what you've been doing, complete with tag-based time tracking. The
@@ -214,7 +211,7 @@ add_commands(%w[undo redo])
214
211
  ## Hidden commands
215
212
  add_commands(%w[commands_accepting install_fzf])
216
213
  ## Optional commands
217
- add_commands(%w[again cancel flag meanwhile reset tags today yesterday since add_section tag_dir colors completion plugins sections template views changes])
214
+ add_commands(%w[again cancel flag meanwhile reset tags today yesterday since tag_dir colors completion plugins sections template views changes])
218
215
 
219
216
  pre do |global, _command, _options, _args|
220
217
  # global[:pager] ||= Doing.setting('paginate')
@@ -235,7 +232,7 @@ pre do |global, _command, _options, _args|
235
232
  end
236
233
 
237
234
  on_error do |exception|
238
- if exception.kind_of?(GLI::UnknownCommand)
235
+ if exception.kind_of?(GLI::UnknownCommand) && ARGV.count > 1
239
236
  exit run(['now'].concat(ARGV.unshift(@command)))
240
237
  elsif exception.kind_of?(SystemExit)
241
238
  false
@@ -298,7 +295,7 @@ around do |global, command, options, arguments, code|
298
295
  @wwid.init_doing_file
299
296
  end
300
297
  Doing.logger.benchmark(:init, :finish)
301
- @wwid.auto_tag = !global[:noauto]
298
+ Doing.auto_tag = !global[:noauto]
302
299
 
303
300
  Doing.set('include_notes', false) unless global[:notes]
304
301
 
@@ -309,6 +306,8 @@ around do |global, command, options, arguments, code|
309
306
  Doing.logger.benchmark("command_#{command.name.to_s}".to_sym, :finish)
310
307
  end
311
308
 
309
+ commands_from File.expand_path(Doing.setting('plugins.command_path')) if Doing.setting('plugins.command_path')
310
+
312
311
  @command = ARGV[0]
313
312
 
314
313
  exit run(ARGV)
data/docs/doc/Array.html CHANGED
@@ -195,7 +195,7 @@ has content</p>
195
195
  </div>
196
196
 
197
197
  <div id="footer">
198
- Generated on Fri Feb 18 12:22:35 2022 by
198
+ Generated on Sun Feb 20 09:36:52 2022 by
199
199
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
200
200
  0.9.27 (ruby-3.0.1).
201
201
  </div>
@@ -283,7 +283,7 @@
283
283
  </div>
284
284
 
285
285
  <div id="footer">
286
- Generated on Fri Feb 18 12:22:39 2022 by
286
+ Generated on Sun Feb 20 09:36:52 2022 by
287
287
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
288
288
  0.9.27 (ruby-3.0.1).
289
289
  </div>
@@ -162,7 +162,7 @@
162
162
  </div>
163
163
 
164
164
  <div id="footer">
165
- Generated on Fri Feb 18 12:22:39 2022 by
165
+ Generated on Sun Feb 20 09:36:52 2022 by
166
166
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
167
167
  0.9.27 (ruby-3.0.1).
168
168
  </div>
@@ -407,7 +407,7 @@
407
407
  </div>
408
408
 
409
409
  <div id="footer">
410
- Generated on Fri Feb 18 12:22:39 2022 by
410
+ Generated on Sun Feb 20 09:36:52 2022 by
411
411
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
412
412
  0.9.27 (ruby-3.0.1).
413
413
  </div>
@@ -125,7 +125,7 @@ parser. In order to do that, a new &quot;clause&quot; node is added to the parse
125
125
  </div>
126
126
 
127
127
  <div id="footer">
128
- Generated on Fri Feb 18 12:22:39 2022 by
128
+ Generated on Sun Feb 20 09:36:52 2022 by
129
129
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
130
130
  0.9.27 (ruby-3.0.1).
131
131
  </div>