doing 2.1.33 → 2.1.36

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 (99) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -0
  3. data/Gemfile.lock +1 -5
  4. data/README.md +1 -1
  5. data/bin/commands/config.rb +11 -11
  6. data/bin/commands/done.rb +2 -2
  7. data/bin/commands/grep.rb +2 -29
  8. data/bin/commands/meanwhile.rb +1 -1
  9. data/bin/commands/now.rb +1 -1
  10. data/bin/commands/on.rb +6 -16
  11. data/bin/commands/open.rb +2 -2
  12. data/bin/commands/recent.rb +2 -14
  13. data/bin/commands/rotate.rb +17 -0
  14. data/bin/commands/sections.rb +82 -7
  15. data/bin/commands/show.rb +1 -21
  16. data/bin/commands/since.rb +5 -16
  17. data/bin/commands/today.rb +3 -28
  18. data/bin/commands/yesterday.rb +2 -35
  19. data/bin/doing +5 -6
  20. data/docs/doc/Array.html +1 -1
  21. data/docs/doc/BooleanTermParser/Clause.html +1 -1
  22. data/docs/doc/BooleanTermParser/Operator.html +1 -1
  23. data/docs/doc/BooleanTermParser/Query.html +1 -1
  24. data/docs/doc/BooleanTermParser/QueryParser.html +1 -1
  25. data/docs/doc/BooleanTermParser/QueryTransformer.html +1 -1
  26. data/docs/doc/BooleanTermParser.html +1 -1
  27. data/docs/doc/Doing/Color.html +1 -1
  28. data/docs/doc/Doing/Completion.html +1 -1
  29. data/docs/doc/Doing/Configuration.html +1 -1
  30. data/docs/doc/Doing/Errors/DoingNoTraceError.html +1 -1
  31. data/docs/doc/Doing/Errors/DoingRuntimeError.html +1 -1
  32. data/docs/doc/Doing/Errors/DoingStandardError.html +1 -1
  33. data/docs/doc/Doing/Errors/EmptyInput.html +1 -1
  34. data/docs/doc/Doing/Errors/NoResults.html +1 -1
  35. data/docs/doc/Doing/Errors/PluginException.html +1 -1
  36. data/docs/doc/Doing/Errors/UserCancelled.html +1 -1
  37. data/docs/doc/Doing/Errors/WrongCommand.html +1 -1
  38. data/docs/doc/Doing/Errors.html +1 -1
  39. data/docs/doc/Doing/Hooks.html +1 -1
  40. data/docs/doc/Doing/Item.html +20 -3
  41. data/docs/doc/Doing/Items.html +209 -1
  42. data/docs/doc/Doing/Logger.html +1807 -0
  43. data/docs/doc/Doing/Note.html +1 -1
  44. data/docs/doc/Doing/Pager.html +1 -1
  45. data/docs/doc/Doing/Plugins.html +1 -1
  46. data/docs/doc/Doing/Prompt.html +1 -1
  47. data/docs/doc/Doing/Section.html +1 -1
  48. data/docs/doc/Doing/TemplateString.html +1 -1
  49. data/docs/doc/Doing/Types.html +2 -2
  50. data/docs/doc/Doing/Util/Backup.html +1 -1
  51. data/docs/doc/Doing/Util.html +1 -1
  52. data/docs/doc/Doing/WWID.html +3 -53
  53. data/docs/doc/Doing.html +4 -4
  54. data/docs/doc/FalseClass.html +1 -1
  55. data/docs/doc/GLI/Commands/Help.html +1 -1
  56. data/docs/doc/GLI/Commands/MarkdownDocumentListener.html +1 -1
  57. data/docs/doc/GLI/Commands.html +1 -1
  58. data/docs/doc/GLI.html +1 -1
  59. data/docs/doc/Hash.html +1 -1
  60. data/docs/doc/Object.html +1 -1
  61. data/docs/doc/PhraseParser/Operator.html +1 -1
  62. data/docs/doc/PhraseParser/PhraseClause.html +1 -1
  63. data/docs/doc/PhraseParser/Query.html +1 -1
  64. data/docs/doc/PhraseParser/QueryParser.html +1 -1
  65. data/docs/doc/PhraseParser/QueryTransformer.html +1 -1
  66. data/docs/doc/PhraseParser/TermClause.html +1 -1
  67. data/docs/doc/PhraseParser.html +1 -1
  68. data/docs/doc/Status.html +1 -1
  69. data/docs/doc/String.html +1 -1
  70. data/docs/doc/Symbol.html +1 -1
  71. data/docs/doc/Time.html +1 -1
  72. data/docs/doc/TrueClass.html +1 -1
  73. data/docs/doc/_index.html +10 -10
  74. data/docs/doc/class_list.html +1 -1
  75. data/docs/doc/file.README.html +2 -2
  76. data/docs/doc/index.html +2 -2
  77. data/docs/doc/method_list.html +407 -383
  78. data/docs/doc/top-level-namespace.html +1 -1
  79. data/doing.gemspec +0 -1
  80. data/doing.rdoc +229 -17
  81. data/lib/completion/_doing.zsh +11 -15
  82. data/lib/completion/doing.bash +12 -23
  83. data/lib/completion/doing.fish +38 -12
  84. data/lib/doing/add_options.rb +36 -1
  85. data/lib/doing/chronify/string.rb +1 -1
  86. data/lib/doing/item.rb +9 -2
  87. data/lib/doing/items.rb +48 -0
  88. data/lib/doing/{log_adapter.rb → logger.rb} +8 -2
  89. data/lib/doing/plugins/import/calendar_import.rb +1 -1
  90. data/lib/doing/plugins/import/doing_import.rb +1 -1
  91. data/lib/doing/plugins/import/timing_import.rb +1 -1
  92. data/lib/doing/string/tags.rb +1 -1
  93. data/lib/doing/types.rb +1 -1
  94. data/lib/doing/version.rb +1 -1
  95. data/lib/doing/wwid.rb +43 -43
  96. data/lib/doing.rb +4 -4
  97. data/lib/examples/plugins/capture_thing_import.rb +1 -1
  98. metadata +4 -24
  99. 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: 4b1f36d019cc1edb1f6e1cdf3fe5f6b31cbb010be429d466b9a680ecef3ad122
4
+ data.tar.gz: 143ad9abc312527232997eb51c87d0b1d0d3dc11a6857170dc3c22704dbc8f08
5
5
  SHA512:
6
- metadata.gz: 2c567803b19db9141e602600d1ef26a59d7d5ac467d6b006fa05d8ead16e6a1fde636515c7515d1fe5325acd1eff622ee5488f97ab4c4017ccddfd4785ac7ea9
7
- data.tar.gz: dac1f74ea6992cd368b6f6012b5edcbb237a016df323540962b3d0702634874f1fa62f18ce32d334b4c18c99e387512085bc7e44c3189b4810ac50e00e834f83
6
+ metadata.gz: 72bf009d051bbfeb05a2375251f52189970fd0d8e2c256a9e6f7372038090e3b09c64a9d7f5c0c7d7050657693998bb85e491b64ee8f98b25165145d3e2982ec
7
+ data.tar.gz: 783dec7a05f42ca67b58bbb61721792737a27a8454f05d2b07cc8c079f8bb6c2c2347e6f0bddef67b9ef9abb4262c2206e517103d2acab08895c32d67b748338
data/CHANGELOG.md CHANGED
@@ -1,3 +1,42 @@
1
+ ### 2.1.36
2
+
3
+ 2022-02-25 08:44
4
+
5
+ #### FIXED
6
+
7
+ - Warning when using `doing done --took`
8
+
9
+ ### 2.1.35
10
+
11
+ 2022-02-21 14:53
12
+
13
+ #### FIXED
14
+
15
+ - Revert switch to sys-uname, hopefully solve crash
16
+
17
+ ### 2.1.34
18
+
19
+ 2022-02-20 09:32
20
+
21
+ #### IMPROVED
22
+
23
+ - Allow `--from 8am` time range without end time to mean `8am to 11:59pm`
24
+ - `--tag_order` for commands with `--totals` output that were missing it
25
+ - Tag and search filters for on, since, today and yesterday
26
+ - Time filters for today and yesterday
27
+ - `--only_timed` filter for yesterday
28
+ - `--only_timed` for today
29
+ - Remove exact duplicates from content before saving
30
+ - `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
31
+
32
+ #### FIXED
33
+
34
+ - `doing yesterday --from` not filtering time range
35
+ - Don't return a duration or interval for entries configured as never_time or never_finish
36
+ - `--from` time filter for yesterday
37
+ - Regex error in `doing archive`
38
+ - `--times` error in `doing today`
39
+
1
40
  ### 2.1.33
2
41
 
3
42
  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.36)
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)
@@ -9,7 +9,6 @@ PATH
9
9
  parslet (~> 2.0, >= 2.0.0)
10
10
  plist (~> 3.6, >= 3.6.0)
11
11
  safe_yaml (~> 1.0)
12
- sys-uname (~> 1.2, >= 1.2.2)
13
12
  tty-link (~> 0.1, >= 0.1.1)
14
13
  tty-markdown (~> 0.7, >= 0.7.0)
15
14
  tty-progressbar (~> 0.18, >= 0.18.2)
@@ -22,7 +21,6 @@ GEM
22
21
  specs:
23
22
  chronic (0.10.2)
24
23
  deep_merge (1.2.2)
25
- ffi (1.15.5)
26
24
  github-markup (4.0.0)
27
25
  gli (2.20.1)
28
26
  haml (5.0.4)
@@ -49,8 +47,6 @@ GEM
49
47
  unicode-display_width (>= 1.5, < 3.0)
50
48
  unicode_utils (~> 1.4)
51
49
  strings-ansi (0.2.0)
52
- sys-uname (1.2.2)
53
- ffi (~> 1.1)
54
50
  temple (0.8.2)
55
51
  test-unit (3.4.9)
56
52
  power_assert
data/README.md CHANGED
@@ -8,7 +8,7 @@ _If you're one of the rare people like me who find this useful, feel free to
8
8
 
9
9
  <!--README-->
10
10
 
11
- The current version of `doing` is <!--VER-->2.1.31<!--END VER-->.
11
+ The current version of `doing` is <!--VER-->2.1.35<!--END VER-->.
12
12
 
13
13
  Find all of the documentation in the [doing wiki][wiki].
14
14
 
@@ -43,9 +43,9 @@ 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
- if Sys::Platform.mac?
48
+ if `uname` =~ /Darwin/
49
49
  edit.desc 'Application to use'
50
50
  edit.arg_name 'APP_NAME'
51
51
  edit.flag %i[a app]
@@ -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|
@@ -76,7 +76,7 @@ command :config do |c|
76
76
 
77
77
  config_file = Doing.config.choose_config
78
78
 
79
- if Sys::Platform.mac?
79
+ if `uname` =~ /Darwin/
80
80
  if options[:default]
81
81
  editor = Doing::Util.find_default_editor('config')
82
82
  if editor
@@ -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
@@ -89,7 +89,7 @@ command %i[done did] do |c|
89
89
  end
90
90
 
91
91
  if options[:date]
92
- date = date.chronify(guess: :begin, context: :today) if date =~ REGEX_TIME
92
+ date = date.chronify(guess: :begin, context: :today) if date.is_a? String
93
93
  finish_date = @wwid.verify_duration(date, finish_date) unless options[:took] || options[:from]
94
94
 
95
95
  donedate = finish_date.strftime('%F %R')
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
data/bin/commands/open.rb CHANGED
@@ -8,7 +8,7 @@ command :open do |c|
8
8
  c.arg_name 'COMMAND'
9
9
  c.flag %i[e editor]
10
10
 
11
- if Sys::Platform.mac?
11
+ if `uname` =~ /Darwin/
12
12
  c.desc 'Open with app name'
13
13
  c.arg_name 'APP_NAME'
14
14
  c.flag %i[a app]
@@ -29,7 +29,7 @@ command :open do |c|
29
29
 
30
30
  editor = TTY::Which.which(options[:editor])
31
31
  system %(#{editor} "#{File.expand_path(@wwid.doing_file)}")
32
- elsif Sys::Platform.mac?
32
+ elsif `uname` =~ /Darwin/
33
33
  if options[:app]
34
34
  system %(open -a "#{options[:app]}" "#{File.expand_path(@wwid.doing_file)}")
35
35
  elsif options[:bundle_id]
@@ -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