doing 2.1.42 → 2.1.43

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 (137) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +1 -1
  5. data/bin/commands/changes.rb +11 -1
  6. data/bin/commands/flag.rb +1 -1
  7. data/bin/commands/grep.rb +3 -1
  8. data/bin/commands/last.rb +2 -0
  9. data/bin/commands/on.rb +8 -1
  10. data/bin/commands/recent.rb +3 -1
  11. data/bin/commands/show.rb +3 -0
  12. data/bin/commands/since.rb +2 -1
  13. data/bin/commands/template.rb +14 -25
  14. data/bin/commands/today.rb +3 -1
  15. data/bin/commands/view.rb +36 -73
  16. data/bin/commands/views.rb +40 -4
  17. data/bin/commands/yesterday.rb +3 -1
  18. data/bin/doing +7 -3
  19. data/docs/doc/Array.html +1 -1
  20. data/docs/doc/BooleanTermParser/Clause.html +1 -1
  21. data/docs/doc/BooleanTermParser/Operator.html +1 -1
  22. data/docs/doc/BooleanTermParser/Query.html +1 -1
  23. data/docs/doc/BooleanTermParser/QueryParser.html +1 -1
  24. data/docs/doc/BooleanTermParser/QueryTransformer.html +1 -1
  25. data/docs/doc/BooleanTermParser.html +1 -1
  26. data/docs/doc/Doing/ArrayCleanup.html +316 -0
  27. data/docs/doc/Doing/ArrayNestedHash.html +1 -1
  28. data/docs/doc/Doing/ArrayTags.html +1 -1
  29. data/docs/doc/Doing/CSVExport.html +1 -1
  30. data/docs/doc/Doing/CalendarImport.html +1 -1
  31. data/docs/doc/Doing/Change.html +74 -3
  32. data/docs/doc/Doing/Changes.html +3 -3
  33. data/docs/doc/Doing/ChronifyArray.html +1 -1
  34. data/docs/doc/Doing/ChronifyNumeric.html +1 -1
  35. data/docs/doc/Doing/ChronifyString.html +1 -1
  36. data/docs/doc/Doing/Color.html +1 -1
  37. data/docs/doc/Doing/Completion/BashCompletions.html +1 -1
  38. data/docs/doc/Doing/Completion/FishCompletions.html +1 -1
  39. data/docs/doc/Doing/Completion/StringUtils.html +1 -1
  40. data/docs/doc/Doing/Completion/ZshCompletions.html +1 -1
  41. data/docs/doc/Doing/Completion.html +1 -1
  42. data/docs/doc/Doing/Configuration.html +80 -1
  43. data/docs/doc/Doing/DayOneRenderer.html +1 -1
  44. data/docs/doc/Doing/DayoneExport.html +1 -1
  45. data/docs/doc/Doing/DoingImport.html +1 -1
  46. data/docs/doc/Doing/Entry.html +109 -4
  47. data/docs/doc/Doing/Errors/DoingNoTraceError.html +1 -1
  48. data/docs/doc/Doing/Errors/DoingRuntimeError.html +1 -1
  49. data/docs/doc/Doing/Errors/DoingStandardError.html +1 -1
  50. data/docs/doc/Doing/Errors/EmptyInput.html +1 -1
  51. data/docs/doc/Doing/Errors/HistoryLimitError.html +1 -1
  52. data/docs/doc/Doing/Errors/InvalidPlugin.html +1 -1
  53. data/docs/doc/Doing/Errors/MissingBackupFile.html +1 -1
  54. data/docs/doc/Doing/Errors/NoResults.html +1 -1
  55. data/docs/doc/Doing/Errors/PluginException.html +1 -1
  56. data/docs/doc/Doing/Errors/UserCancelled.html +1 -1
  57. data/docs/doc/Doing/Errors/WrongCommand.html +1 -1
  58. data/docs/doc/Doing/Errors.html +1 -1
  59. data/docs/doc/Doing/HTMLExport.html +1 -1
  60. data/docs/doc/Doing/Hooks.html +1 -1
  61. data/docs/doc/Doing/Item.html +1 -1
  62. data/docs/doc/Doing/ItemDates.html +1 -1
  63. data/docs/doc/Doing/ItemQuery.html +1 -1
  64. data/docs/doc/Doing/ItemState.html +1 -1
  65. data/docs/doc/Doing/ItemTags.html +1 -1
  66. data/docs/doc/Doing/Items.html +1 -1
  67. data/docs/doc/Doing/JSONExport.html +1 -1
  68. data/docs/doc/Doing/Logger.html +1 -1
  69. data/docs/doc/Doing/MarkdownExport.html +1 -1
  70. data/docs/doc/Doing/Note.html +1 -1
  71. data/docs/doc/Doing/Pager.html +1 -1
  72. data/docs/doc/Doing/Plugins.html +1 -1
  73. data/docs/doc/Doing/Prompt.html +1 -1
  74. data/docs/doc/Doing/PromptChoose.html +1 -1
  75. data/docs/doc/Doing/PromptFZF.html +1 -1
  76. data/docs/doc/Doing/PromptInput.html +1 -1
  77. data/docs/doc/Doing/PromptSTD.html +1 -1
  78. data/docs/doc/Doing/PromptYN.html +1 -1
  79. data/docs/doc/Doing/Section.html +1 -1
  80. data/docs/doc/Doing/StringHighlight.html +1 -1
  81. data/docs/doc/Doing/StringNormalize.html +35 -1
  82. data/docs/doc/Doing/StringQuery.html +1 -1
  83. data/docs/doc/Doing/StringTags.html +1 -1
  84. data/docs/doc/Doing/StringTransform.html +1 -1
  85. data/docs/doc/Doing/StringTruncate.html +1 -1
  86. data/docs/doc/Doing/StringURL.html +1 -1
  87. data/docs/doc/Doing/SymbolNormalize.html +1 -1
  88. data/docs/doc/Doing/TaskPaperExport.html +1 -1
  89. data/docs/doc/Doing/TemplateExport.html +1 -1
  90. data/docs/doc/Doing/TemplateString.html +2 -2
  91. data/docs/doc/Doing/TimingImport.html +1 -1
  92. data/docs/doc/Doing/Types.html +1 -1
  93. data/docs/doc/Doing/Util/Backup.html +1 -1
  94. data/docs/doc/Doing/Util.html +1 -1
  95. data/docs/doc/Doing/Version.html +1 -1
  96. data/docs/doc/Doing/WWID.html +71 -3
  97. data/docs/doc/Doing.html +2 -2
  98. data/docs/doc/FalseClass.html +1 -1
  99. data/docs/doc/GLI/Commands/Help.html +1 -1
  100. data/docs/doc/GLI/Commands/MarkdownDocumentListener.html +1 -1
  101. data/docs/doc/GLI/Commands.html +1 -1
  102. data/docs/doc/GLI.html +1 -1
  103. data/docs/doc/Hash.html +461 -6
  104. data/docs/doc/Numeric.html +1 -1
  105. data/docs/doc/Object.html +1 -1
  106. data/docs/doc/PhraseParser/Operator.html +1 -1
  107. data/docs/doc/PhraseParser/PhraseClause.html +1 -1
  108. data/docs/doc/PhraseParser/Query.html +1 -1
  109. data/docs/doc/PhraseParser/QueryParser.html +1 -1
  110. data/docs/doc/PhraseParser/QueryTransformer.html +1 -1
  111. data/docs/doc/PhraseParser/TermClause.html +1 -1
  112. data/docs/doc/PhraseParser.html +1 -1
  113. data/docs/doc/Status.html +1 -1
  114. data/docs/doc/String.html +2 -2
  115. data/docs/doc/Symbol.html +1 -1
  116. data/docs/doc/Time.html +1 -1
  117. data/docs/doc/TrueClass.html +1 -1
  118. data/docs/doc/_index.html +1 -1
  119. data/docs/doc/file.README.html +2 -2
  120. data/docs/doc/index.html +2 -2
  121. data/docs/doc/method_list.html +484 -388
  122. data/docs/doc/top-level-namespace.html +3 -1
  123. data/doing.rdoc +101 -6
  124. data/lib/completion/_doing.zsh +13 -13
  125. data/lib/completion/doing.bash +22 -22
  126. data/lib/completion/doing.fish +15 -1
  127. data/lib/doing/add_options.rb +35 -0
  128. data/lib/doing/changelog/change.rb +13 -5
  129. data/lib/doing/changelog/changes.rb +11 -2
  130. data/lib/doing/changelog/entry.rb +9 -2
  131. data/lib/doing/configuration.rb +17 -0
  132. data/lib/doing/hash.rb +126 -22
  133. data/lib/doing/normalize.rb +13 -0
  134. data/lib/doing/pager.rb +1 -1
  135. data/lib/doing/version.rb +1 -1
  136. data/lib/doing/wwid/wwid.rb +21 -3
  137. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8021e76952eb60e4eb68c5aa013f558e7e9e5db454bad792c1ae7e5cc495e24c
4
- data.tar.gz: 5eda874992b4f9648c421afdc4429963f2614d08aabba8fb338d4d27c353e258
3
+ metadata.gz: f66c677c6389d032b16de0fc8f8e10c1c07c3acfe17598acae8cedb06f633265
4
+ data.tar.gz: 9b0563a648269c91c290fabe908f0f0e32e789be4cf8147ddd1c9ef260b99466
5
5
  SHA512:
6
- metadata.gz: 37ce93cc4868cbb5565f18b8cd2a77d61099f9692c5b6bcaacdf9329876faa4bc9ff240adc29ea2f8e4cff76adbadc697f583131dfcdb61379dc998a91d40de4
7
- data.tar.gz: 06d59cd04607005a65f166701873107a8d4817986007940489dfda3247d97d567a4072d62eb05687f50e1ba93eb6341f1db8f5a317df948836fa56945270a8fa
6
+ metadata.gz: a0bcf6d549f921706060ea8d7d3df0d493e4bc8304beaa324f9f7a7a14bf3fd47c55eb5f236c6bb312901e4d586655c7b95e809a7b35477da720bee57af4f7f0
7
+ data.tar.gz: 2744cea9d2f5d7620d5983d29e892dca4e8066d54b5cc191445e4845ef852682f328297e821d2085df4770edc67c7a7872d42d5adf44bd8189e0fe1c71146791
data/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ ### 2.1.43
2
+
3
+ 2022-03-20 12:44
4
+
5
+ #### NEW
6
+
7
+ - 'parent' key in view config allows inheritance
8
+ - Use `--save NAME` with view commands to store command line options as a view in config
9
+ - Views function as commands, so you can run `doing custom` and get `doing view custom` if 'custom' is not a recognized command
10
+ - Breaking change - boolean switches on the command line no longer override views
11
+ - Add an argument to `doing views` to dump the YAML for a single view
12
+ - Use `doing views NAME --editor` to open the YAML for a single view in the default editor, saving the result to main config
13
+ - Use `doing views [-e] -o json NAME` to dump or edit a view as json instead of YAML
14
+
15
+ #### IMPROVED
16
+
17
+ - `doing changes --only [changed,new,improved,fixed]` to only show changes of a type
18
+ - Allow all show options in view config
19
+ - Disable autocorrect for command names so custom views can better override similarly-spelled commands
20
+ - `doing changes --prefix` will output each change with a type prefix
21
+ - Include -F switch in `less` when paging to avoid pager if less than one screen
22
+
23
+ #### FIXED
24
+
25
+ - `doing templates --list` returning error
26
+
1
27
  ### 2.1.42
2
28
 
3
29
  2022-03-17 09:38
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- doing (2.1.42)
4
+ doing (2.1.43)
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)
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.41<!--END VER-->.
11
+ The current version of `doing` is <!--VER-->2.1.42<!--END VER-->.
12
12
 
13
13
  Find all of the documentation in the [doing wiki][wiki].
14
14
 
@@ -40,6 +40,13 @@ module Doing
40
40
  cmd.desc 'Only output changes, no version numbers, headers, or dates'
41
41
  cmd.switch %i[C changes], default_value: false, negatable: false
42
42
 
43
+ cmd.desc 'Include (CHANGE|NEW|IMPROVED|FIXED) prefix on each line'
44
+ cmd.switch %i[p prefix]
45
+
46
+ cmd.desc 'Only show changes of type(s), comma-separated'
47
+ cmd.arg_name 'TYPES'
48
+ cmd.flag %i[only], default_value: 'changed,new,improved,fixed'
49
+
43
50
  cmd.desc 'Output raw Markdown'
44
51
  cmd.switch %i[m md markdown], default_value: false, negatable: false
45
52
 
@@ -72,10 +79,13 @@ command %i[changes changelog] do |c|
72
79
  cmd.add_examples(c)
73
80
 
74
81
  c.action do |_global_options, options, _args|
82
+ only = options[:only].split(/ *, */).map(&:normalize_change_type)
75
83
  cl = Doing::Changes.new(lookup: options[:lookup],
76
84
  search: options[:search],
77
85
  changes: options[:changes],
78
- sort: options[:sort])
86
+ prefix: options[:prefix],
87
+ sort: options[:sort],
88
+ only: only)
79
89
 
80
90
  if options[:interactive]
81
91
  cl.interactive
data/bin/commands/flag.rb CHANGED
@@ -8,7 +8,7 @@ command %i[mark flag] do |c|
8
8
  c.example 'doing flag --tag project1 --count 2', desc: 'Add @flagged to the last 2 entries tagged @project1'
9
9
  c.example 'doing flag --interactive --search "/(develop|cod)ing/"',
10
10
  desc: 'Find entries matching regular expression and create a menu allowing multiple selections,
11
- selected items will be @flagged'
11
+ selected items will be @flagged'
12
12
 
13
13
  c.desc 'Section'
14
14
  c.arg_name 'SECTION_NAME'
data/bin/commands/grep.rb CHANGED
@@ -25,7 +25,7 @@ command %i[grep search] do |c|
25
25
  c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
26
26
  c.arg_name 'TYPE'
27
27
  c.flag [:case], must_match: REGEX_CASE,
28
- default_value: Doing.settings.dig('search', 'case').normalize_case,
28
+ default_value: Doing.setting('search.case', :smart).normalize_case,
29
29
  type: CaseSymbol
30
30
 
31
31
  c.desc "Highlight search matches in output. Only affects command line output"
@@ -44,6 +44,7 @@ command %i[grep search] do |c|
44
44
  add_options(:tag_filter, c)
45
45
  add_options(:date_filter, c)
46
46
  add_options(:time_display, c)
47
+ add_options(:save, c)
47
48
 
48
49
  c.action do |_global_options, options, args|
49
50
  options[:fuzzy] = false
@@ -66,5 +67,6 @@ command %i[grep search] do |c|
66
67
  options[:tags_color] = tags_color
67
68
 
68
69
  Doing::Pager.page @wwid.list_section(options)
70
+ Doing.config.save_view(options.to_view, options[:save].downcase) if options[:save]
69
71
  end
70
72
  end
data/bin/commands/last.rb CHANGED
@@ -30,6 +30,7 @@ command :last do |c|
30
30
  add_options(:output_template, c, default_template: 'last')
31
31
  add_options(:search, c)
32
32
  add_options(:tag_filter, c)
33
+ add_options(:save, c)
33
34
 
34
35
  c.action do |global_options, options, _args|
35
36
  options[:fuzzy] = false
@@ -70,6 +71,7 @@ command :last do |c|
70
71
  val: options[:val]
71
72
  })
72
73
  Doing::Pager::page last.strip if last
74
+ Doing.config.save_view(options.to_view, options[:save].downcase) if options[:save]
73
75
  end
74
76
  end
75
77
  end
data/bin/commands/on.rb CHANGED
@@ -20,6 +20,7 @@ command :on do |c|
20
20
  add_options(:search, c)
21
21
  add_options(:tag_filter, c)
22
22
  add_options(:time_filter, c)
23
+ add_options(:save, c)
23
24
 
24
25
  c.action do |_global_options, options, args|
25
26
  if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
@@ -43,6 +44,12 @@ command :on do |c|
43
44
  options[:times] = true if options[:totals]
44
45
  options[:sort_tags] = options[:tag_sort]
45
46
 
46
- Doing::Pager.page @wwid.list_date([start, finish], options[:section], options[:times], options[:output], options).chomp
47
+ Doing::Pager.page @wwid.list_date([start, finish],
48
+ options[:section],
49
+ options[:times],
50
+ options[:output],
51
+ options).chomp
52
+
53
+ Doing.config.save_view(options.to_view, options[:save].downcase) if options[:save]
47
54
  end
48
55
  end
@@ -17,6 +17,7 @@ command :recent do |c|
17
17
 
18
18
  add_options(:output_template, c, default_template: 'recent')
19
19
  add_options(:time_display, c)
20
+ add_options(:save, c)
20
21
 
21
22
  c.action do |global_options, options, args|
22
23
  section = @wwid.guess_section(options[:section]) || options[:section].cap_first
@@ -53,7 +54,8 @@ command :recent do |c|
53
54
  }
54
55
 
55
56
  Doing::Pager::page @wwid.recent(count, section.cap_first, opts)
56
-
57
+ opts[:count] = count
58
+ Doing.config.save_view(opts.to_view, options[:save].downcase) if options[:save]
57
59
  end
58
60
  end
59
61
  end
data/bin/commands/show.rb CHANGED
@@ -47,6 +47,7 @@ command :show do |c|
47
47
  add_options(:search, c)
48
48
  add_options(:tag_filter, c)
49
49
  add_options(:date_filter, c)
50
+ add_options(:save, c)
50
51
 
51
52
  c.action do |global_options, options, args|
52
53
  options[:fuzzy] = false
@@ -153,5 +154,7 @@ command :show do |c|
153
154
  opt[:tags_color] = template['tags_color']
154
155
 
155
156
  Doing::Pager.page @wwid.list_section(opt, items: items)
157
+
158
+ Doing.config.save_view(opt.to_view, options[:save].downcase) if options[:save]
156
159
  end
157
160
  end
@@ -15,7 +15,7 @@ command :since do |c|
15
15
  add_options(:time_display, c)
16
16
  add_options(:tag_filter, c)
17
17
  add_options(:search, c)
18
-
18
+ add_options(:save, c)
19
19
  c.action do |_global_options, options, args|
20
20
  raise DoingRuntimeError, %(Invalid output type "#{options[:output]}") if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
21
21
 
@@ -37,5 +37,6 @@ command :since do |c|
37
37
  options[:sort_tags] = options[:tag_sort]
38
38
 
39
39
  Doing::Pager.page @wwid.list_date([start, finish], options[:section], options[:times], options[:output], options).chomp
40
+ Doing.config.save_view(options.to_view, options[:save].downcase) if options[:save]
40
41
  end
41
42
  end
@@ -28,34 +28,23 @@ command :template do |c|
28
28
  else
29
29
  $stdout.puts "Available templates: #{Doing::Plugins.plugin_templates.join(', ')}"
30
30
  end
31
- return
32
- end
33
-
34
- if args.empty?
35
- type = Doing::Prompt.choose_from(Doing::Plugins.plugin_templates, sorted: false, prompt: 'Select template type > ')
36
- type.sub!(/ \(.*?\)$/, '').strip!
37
- options[:save] = Doing::Prompt.yn("Save to #{options[:path]}? (No outputs to STDOUT)", default_response: false)
38
31
  else
39
- type = args[0]
40
- end
41
32
 
42
- raise InvalidPluginType, "No type specified, use `doing template [#{Doing::Plugins.plugin_templates.join('|')}]`" unless type
33
+ if args.empty?
34
+ type = Doing::Prompt.choose_from(Doing::Plugins.plugin_templates, sorted: false, prompt: 'Select template type > ')
35
+ type.sub!(/ \(.*?\)$/, '').strip!
36
+ options[:save] = Doing::Prompt.yn("Save to #{options[:path]}? (No outputs to STDOUT)", default_response: false)
37
+ else
38
+ type = args[0]
39
+ end
40
+
41
+ raise InvalidPluginType, "No type specified, use `doing template [#{Doing::Plugins.plugin_templates.join('|')}]`" unless type
43
42
 
44
- if options[:save]
45
- Doing::Plugins.template_for_trigger(type, save_to: options[:path])
46
- else
47
- $stdout.puts Doing::Plugins.template_for_trigger(type, save_to: nil)
43
+ if options[:save]
44
+ Doing::Plugins.template_for_trigger(type, save_to: options[:path])
45
+ else
46
+ $stdout.puts Doing::Plugins.template_for_trigger(type, save_to: nil)
47
+ end
48
48
  end
49
-
50
- # case args[0]
51
- # when /html|haml/i
52
- # $stdout.puts @wwid.haml_template
53
- # when /css/i
54
- # $stdout.puts @wwid.css_template
55
- # when /markdown|md|erb/i
56
- # $stdout.puts @wwid.markdown_template
57
- # else
58
- # exit_now! 'Invalid type specified, must be HAML or CSS'
59
- # end
60
49
  end
61
50
  end
@@ -15,6 +15,7 @@ command :today do |c|
15
15
  add_options(:output_template, c, default_template: 'today')
16
16
  add_options(:time_filter, c)
17
17
  add_options(:time_display, c)
18
+ add_options(:save, c)
18
19
 
19
20
  c.action do |_global_options, options, _args|
20
21
  raise InvalidPlugin.new('output', options[:output]) if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
@@ -22,7 +23,8 @@ command :today do |c|
22
23
  options[:times] = true if options[:totals]
23
24
  options[:sort_tags] = options[:tag_sort]
24
25
  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] }
25
-
26
+ filter_options[:today] = true
26
27
  Doing::Pager.page @wwid.today(options[:times], options[:output], filter_options).chomp
28
+ Doing.config.save_view(filter_options.to_view, options[:save].downcase) if options[:save]
27
29
  end
28
30
  end
data/bin/commands/view.rb CHANGED
@@ -15,28 +15,24 @@ command :view do |c|
15
15
  c.arg_name 'COUNT'
16
16
  c.flag %i[c count], must_match: /^\d+$/, type: Integer
17
17
 
18
- c.desc "Output to export format (#{Doing::Plugins.plugin_names(type: :export)})"
19
- c.arg_name 'FORMAT'
20
- c.flag %i[o output]
21
-
22
18
  c.desc 'Age (oldest|newest)'
23
19
  c.arg_name 'AGE'
24
- c.flag %i[age], default_value: :newest, type: AgeSymbol
20
+ c.flag %i[age], type: AgeSymbol
25
21
 
26
22
  c.desc 'Show time intervals on @done tasks'
27
23
  c.switch %i[t times], default_value: true, negatable: true
28
24
 
29
25
  c.desc 'Show elapsed time on entries without @done tag'
30
- c.switch [:duration]
26
+ c.switch [:duration], default_value: false, negatable: false
31
27
 
32
28
  c.desc 'Show intervals with totals at the end of output'
33
29
  c.switch [:totals], default_value: false, negatable: false
34
30
 
35
31
  c.desc 'Include colors in output'
36
- c.switch [:color], default_value: true, negatable: true
32
+ c.switch [:color], negatable: true
37
33
 
38
34
  c.desc "Highlight search matches in output. Only affects command line output"
39
- c.switch %i[h hilite], default_value: Doing.settings.dig('search', 'highlight')
35
+ c.switch %i[h hilite], default_value: false, negatable: true
40
36
 
41
37
  c.desc 'Sort tags by (name|time)'
42
38
  c.arg_name 'KEY'
@@ -53,8 +49,9 @@ command :view do |c|
53
49
  c.switch %i[i interactive], negatable: false, default_value: false
54
50
 
55
51
  add_options(:search, c)
56
- add_options(:tag_filter, c)
52
+ add_options(:tag_filter_no_defaults, c)
57
53
  add_options(:date_filter, c)
54
+ add_options(:output_template_no_defaults, c)
58
55
 
59
56
  c.action do |global_options, options, args|
60
57
  options[:fuzzy] = false
@@ -85,83 +82,55 @@ command :view do |c|
85
82
  Doing.setting('current_section')
86
83
  end
87
84
 
88
- view = @wwid.get_view(title)
85
+ view = @wwid.view_to_options(title)
89
86
 
90
87
  if view
91
- page_title = view['title'] || title.cap_first
92
- only_timed = if (view.key?('only_timed') && view['only_timed']) || options[:only_timed]
93
- true
94
- else
95
- false
96
- end
88
+ options = Doing::Util.deep_merge_hashes(view, options)
97
89
 
98
- template = view['template'] || nil
99
- date_format = view['date_format'] || nil
90
+ options[:totals] = view[:totals] unless options[:totals]
91
+ options[:only_timed] = view[:only_timed] unless options[:only_timed]
92
+ options[:times] = view[:times] if options[:times]
93
+ options[:duration] = view[:duration] unless options[:duration]
94
+ options[:hilite] = view[:hilite] unless options[:hilite]
100
95
 
101
- tags_color = view['tags_color'] || nil
96
+ page_title = options[:title] || title.cap_first
102
97
  tag_filter = false
103
- if options[:tag]
98
+ if options[:tag] && options[:tag].good
104
99
  tag_filter = { 'tags' => [], 'bool' => 'OR' }
105
- bool = options[:bool]
100
+ bool = options[:bool].normalize_bool
106
101
  tag_filter['bool'] = bool
107
102
  tag_filter['tags'] = if bool == :pattern
108
103
  options[:tag]
109
104
  else
110
105
  options[:tag].gsub(/[, ]+/, ' ').split(' ').map(&:strip)
111
106
  end
112
- elsif view.key?('tags') && view['tags'].good?
107
+ options[:tags] = nil
108
+ options[:bool] = bool
109
+ elsif options[:tags]
113
110
  tag_filter = { 'tags' => [], 'bool' => 'OR' }
114
- bool = view.key?('tags_bool') && !view['tags_bool'].nil? ? view['tags_bool'].normalize_bool : :pattern
111
+ bool = options[:bool] ? options[:bool].normalize_bool : :pattern
115
112
  tag_filter['bool'] = bool
116
- tag_filter['tags'] = if view['tags'].instance_of?(Array)
117
- bool == :pattern ? view['tags'].join(' ').strip : view['tags'].map(&:strip)
113
+ tag_filter['tags'] = if options[:tags].instance_of?(Array)
114
+ bool == :pattern ? options[:tags].join(' ').strip : options[:tags].map(&:strip)
118
115
  else
119
- bool == :pattern ? view['tags'].strip : view['tags'].gsub(/[, ]+/, ' ').split(' ').map(&:strip)
116
+ bool == :pattern ? options[:tags].strip : options[:tags].gsub(/[, ]+/, ' ').split(' ').map(&:strip)
120
117
  end
118
+ options[:tags] = nil
119
+ options[:bool] = bool
121
120
  end
122
121
 
123
- # If the -o/--output flag was specified, override any default in the view template
124
- options[:output] ||= view.key?('output_format') ? view['output_format'] : 'template'
125
-
126
- count = if options[:count]
127
- options[:count]
128
- elsif view.key?('count')
129
- view['count']
130
- else
131
- 10
132
- end
133
-
134
- section = if options[:section]
135
- section
136
- else
137
- view['section'] || Doing.setting('current_section')
138
- end
139
- order = if view.key?('order')
140
- view['order'].normalize_order
141
- else
142
- :asc
143
- end
144
-
145
- totals = if options[:totals]
146
- true
147
- else
148
- view['totals'] || false
149
- end
150
- tag_order = options[:tag_order] || view['tag_order']&.normalize_order || :asc
151
-
152
- options[:times] = true if totals
122
+ section = options[:section] || Doing.setting('current_section')
123
+ order = options[:order]&.normalize_order || :asc
124
+ totals = options[:totals] || false
125
+ tag_order = options[:tag_order]&.normalize_order || :asc
153
126
  output_format = options[:output]&.downcase || 'template'
154
127
 
155
- options[:sort_tags] = if options[:tag_sort]
156
- options[:tag_sort]
157
- elsif view.key?('tag_sort')
158
- view['tag_sort'].normalize_tag_sort
159
- else
160
- false
161
- end
162
-
163
- %w[before after from duration].each { |k| options[k.to_sym] = view[k] if view.key?(k) && !options[k.to_sym] }
128
+ options[:times] = true if totals
164
129
 
130
+ options.rename_key(:tag_sort, :sort_tags)
131
+ options[:sort_tags] ||= :name
132
+ options.rename_key(:date_format, :format)
133
+ options.rename_key(:color, :highlight)
165
134
  search = nil
166
135
 
167
136
  if options[:search]
@@ -172,12 +141,8 @@ command :view do |c|
172
141
  options[:age] ||= :newest
173
142
 
174
143
  opts = options.clone
175
- opts[:age] = options[:age]
176
- opts[:count] = count
177
- opts[:format] = date_format
178
- opts[:highlight] = options[:color]
179
- opts[:hilite] = options[:hilite]
180
- opts[:only_timed] = only_timed
144
+
145
+ opts[:count] ||= 10
181
146
  opts[:order] = order
182
147
  opts[:output] = options[:interactive] ? nil : options[:output]
183
148
  opts[:output] = output_format
@@ -186,8 +151,6 @@ command :view do |c|
186
151
  opts[:section] = section
187
152
  opts[:tag_filter] = tag_filter
188
153
  opts[:tag_order] = tag_order
189
- opts[:tags_color] = tags_color
190
- opts[:template] = template
191
154
  opts[:totals] = totals
192
155
  opts[:view_template] = title
193
156
 
@@ -1,11 +1,47 @@
1
1
  # @@views
2
- desc 'List available custom views'
2
+ desc 'List available custom views. Specify view names to see YAML configurations.'
3
+ arg_name 'NAME(S)', optional: true
3
4
  command :views do |c|
5
+ c.example 'doing views', desc: 'list all views'
6
+ c.example 'doing views -c', desc: 'list views in column, ideal for shell completion'
7
+ c.example 'doing views color', desc: 'dump the YAML for a single view'
8
+ c.example 'doing views -e color', desc: 'edit the YAML configuration for a single view'
9
+ c.example 'doing views -e -o json color finished', desc: 'edit multiple view configs as JSON'
10
+
4
11
  c.desc 'List in single column'
5
12
  c.switch %i[c column], default_value: false
6
13
 
7
- c.action do |_global_options, options, _args|
8
- joiner = options[:column] ? "\n" : "\t"
9
- print @wwid.views.join(joiner)
14
+ c.desc 'Open YAML for view in editor (requires argument)'
15
+ c.switch %i[e editor]
16
+
17
+ c.desc 'Output/edit view in alternative format (json, yaml)'
18
+ c.arg_name 'FORMAT'
19
+ c.flag %i[o output], must_match: /^[jy]/i, default_value: 'yaml'
20
+
21
+ c.action do |_global_options, options, args|
22
+ if args.count.positive?
23
+ views = {}
24
+ args.each { |v| views[v] = @wwid.get_view(v) }
25
+
26
+ if options[:editor]
27
+ res = if options[:output] =~ /^j/i
28
+ JSON.parse(@wwid.fork_editor(JSON.pretty_generate(views), message: nil))
29
+ else
30
+ YAML.safe_load(@wwid.fork_editor(YAML.dump(views), message: nil))
31
+ end
32
+ args.each { |v| Doing.set("views.#{v}", res[v]) }
33
+ Doing::Util.write_to_file(Doing.config.config_file, YAML.dump(Doing.settings), backup: true)
34
+ Doing.logger.warn('Config:', "#{Doing.config.config_file} updated")
35
+ elsif options[:output] =~ /^j/i
36
+ out = JSON.pretty_generate(views)
37
+ Doing::Pager.page out
38
+ else
39
+ out = YAML.dump(views)
40
+ Doing::Pager.page out
41
+ end
42
+ else
43
+ joiner = options[:column] ? "\n" : "\t"
44
+ print @wwid.views.join(joiner)
45
+ end
10
46
  end
11
47
  end
@@ -14,6 +14,7 @@ command :yesterday do |c|
14
14
  add_options(:output_template, c, default_template: 'today')
15
15
  add_options(:time_filter, c)
16
16
  add_options(:time_display, c)
17
+ add_options(:save, c)
17
18
 
18
19
  c.action do |_global_options, options, _args|
19
20
  raise InvalidPlugin.new('output', options[:output]) if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
@@ -22,7 +23,8 @@ command :yesterday do |c|
22
23
 
23
24
  opt = options.clone
24
25
  opt[:order] = Doing.setting(['templates', options[:config_template], 'order'])
25
-
26
+ opt[:yesterday] = true
26
27
  Doing::Pager.page @wwid.yesterday(options[:section], options[:times], options[:output], opt).chomp
28
+ Doing.config.save_view(opt.to_view, options[:save].downcase) if options[:save]
27
29
  end
28
30
  end
data/bin/doing CHANGED
@@ -26,7 +26,7 @@ include Doing::Errors
26
26
 
27
27
  version Doing::VERSION
28
28
  hide_commands_without_desc true
29
- autocomplete_commands true
29
+ autocomplete_commands false
30
30
  wrap_help_text :one_line unless $stdout.isatty
31
31
 
32
32
  include Doing::Types
@@ -233,16 +233,20 @@ pre do |global, _command, _options, _args|
233
233
  end
234
234
 
235
235
  on_error do |exception|
236
- if exception.is_a?(GLI::UnknownCommand)
236
+ case exception
237
+ when GLI::UnknownCommand
237
238
  if ARGV.count > 1
239
+ exit run(['view'].concat(ARGV.unshift(@command))) if @wwid.get_view(@command, fallback: false)
238
240
  exit run(['now'].concat(ARGV.unshift(@command)))
239
241
  else
242
+ exit run(['view'].concat(ARGV.unshift(@command))) if @wwid.get_view(@command, fallback: false)
243
+
240
244
  Doing::Color.coloring = $stdout.isatty
241
245
  Doing.logger.error('Unknown Command:', @command)
242
246
  Doing.logger.output_results
243
247
  false
244
248
  end
245
- elsif exception.is_a?(SystemExit)
249
+ when SystemExit
246
250
  false
247
251
  else
248
252
  # Doing.logger.error('Fatal:', exception)
data/docs/doc/Array.html CHANGED
@@ -278,7 +278,7 @@ has content</p>
278
278
  </div>
279
279
 
280
280
  <div id="footer">
281
- Generated on Fri Mar 18 12:56:58 2022 by
281
+ Generated on Sun Mar 20 12:48:29 2022 by
282
282
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
283
283
  0.9.27 (ruby-3.0.1).
284
284
  </div>
@@ -283,7 +283,7 @@
283
283
  </div>
284
284
 
285
285
  <div id="footer">
286
- Generated on Fri Mar 18 12:56:58 2022 by
286
+ Generated on Sun Mar 20 12:48:30 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 Mar 18 12:56:58 2022 by
165
+ Generated on Sun Mar 20 12:48:30 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 Mar 18 12:56:58 2022 by
410
+ Generated on Sun Mar 20 12:48:30 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 Mar 18 12:56:58 2022 by
128
+ Generated on Sun Mar 20 12:48:30 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>
@@ -114,7 +114,7 @@
114
114
  </div>
115
115
 
116
116
  <div id="footer">
117
- Generated on Fri Mar 18 12:56:58 2022 by
117
+ Generated on Sun Mar 20 12:48:30 2022 by
118
118
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
119
119
  0.9.27 (ruby-3.0.1).
120
120
  </div>
@@ -105,7 +105,7 @@
105
105
  </div>
106
106
 
107
107
  <div id="footer">
108
- Generated on Fri Mar 18 12:56:58 2022 by
108
+ Generated on Sun Mar 20 12:48:29 2022 by
109
109
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
110
110
  0.9.27 (ruby-3.0.1).
111
111
  </div>