doing 2.0.22 → 2.1.0pre

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/.yardoc/checksums +18 -15
  3. data/.yardoc/object_types +0 -0
  4. data/.yardoc/objects/root.dat +0 -0
  5. data/CHANGELOG.md +36 -1
  6. data/Gemfile.lock +8 -1
  7. data/README.md +7 -1
  8. data/Rakefile +23 -4
  9. data/bin/doing +323 -173
  10. data/doc/Array.html +354 -1
  11. data/doc/Doing/Color.html +104 -92
  12. data/doc/Doing/Completion.html +216 -0
  13. data/doc/Doing/Configuration.html +340 -5
  14. data/doc/Doing/Content.html +229 -0
  15. data/doc/Doing/Errors/DoingNoTraceError.html +1 -1
  16. data/doc/Doing/Errors/DoingRuntimeError.html +1 -1
  17. data/doc/Doing/Errors/DoingStandardError.html +1 -1
  18. data/doc/Doing/Errors/EmptyInput.html +1 -1
  19. data/doc/Doing/Errors/NoResults.html +1 -1
  20. data/doc/Doing/Errors/PluginException.html +1 -1
  21. data/doc/Doing/Errors/UserCancelled.html +1 -1
  22. data/doc/Doing/Errors/WrongCommand.html +1 -1
  23. data/doc/Doing/Errors.html +1 -1
  24. data/doc/Doing/Hooks.html +1 -1
  25. data/doc/Doing/Item.html +337 -49
  26. data/doc/Doing/Items.html +444 -35
  27. data/doc/Doing/LogAdapter.html +139 -51
  28. data/doc/Doing/Note.html +253 -22
  29. data/doc/Doing/Pager.html +74 -36
  30. data/doc/Doing/Plugins.html +1 -1
  31. data/doc/Doing/Prompt.html +674 -0
  32. data/doc/Doing/Section.html +354 -0
  33. data/doc/Doing/Util.html +57 -1
  34. data/doc/Doing/WWID.html +477 -670
  35. data/doc/Doing/WWIDFile.html +398 -0
  36. data/doc/Doing.html +5 -5
  37. data/doc/GLI/Commands/MarkdownDocumentListener.html +1 -1
  38. data/doc/GLI/Commands.html +1 -1
  39. data/doc/GLI.html +1 -1
  40. data/doc/Hash.html +97 -1
  41. data/doc/Status.html +37 -3
  42. data/doc/String.html +599 -23
  43. data/doc/Symbol.html +3 -3
  44. data/doc/Time.html +1 -1
  45. data/doc/_index.html +22 -1
  46. data/doc/class_list.html +1 -1
  47. data/doc/file.README.html +8 -2
  48. data/doc/index.html +8 -2
  49. data/doc/method_list.html +453 -173
  50. data/doc/top-level-namespace.html +1 -1
  51. data/doing.gemspec +3 -0
  52. data/doing.rdoc +79 -27
  53. data/example_plugin.rb +5 -5
  54. data/lib/completion/_doing.zsh +42 -42
  55. data/lib/completion/doing.bash +10 -10
  56. data/lib/completion/doing.fish +1 -280
  57. data/lib/doing/array.rb +36 -0
  58. data/lib/doing/colors.rb +70 -66
  59. data/lib/doing/completion/bash_completion.rb +1 -2
  60. data/lib/doing/completion/fish_completion.rb +1 -1
  61. data/lib/doing/completion/zsh_completion.rb +1 -1
  62. data/lib/doing/completion.rb +6 -0
  63. data/lib/doing/configuration.rb +134 -23
  64. data/lib/doing/hash.rb +37 -0
  65. data/lib/doing/item.rb +77 -12
  66. data/lib/doing/items.rb +125 -0
  67. data/lib/doing/log_adapter.rb +58 -4
  68. data/lib/doing/note.rb +53 -1
  69. data/lib/doing/pager.rb +49 -38
  70. data/lib/doing/plugins/export/markdown_export.rb +4 -4
  71. data/lib/doing/plugins/export/template_export.rb +2 -2
  72. data/lib/doing/plugins/import/calendar_import.rb +4 -4
  73. data/lib/doing/plugins/import/doing_import.rb +5 -7
  74. data/lib/doing/plugins/import/timing_import.rb +3 -3
  75. data/lib/doing/prompt.rb +206 -0
  76. data/lib/doing/section.rb +30 -0
  77. data/lib/doing/string.rb +123 -35
  78. data/lib/doing/util.rb +14 -6
  79. data/lib/doing/version.rb +1 -1
  80. data/lib/doing/wwid.rb +307 -614
  81. data/lib/doing.rb +6 -2
  82. data/lib/examples/plugins/capture_thing_import.rb +162 -0
  83. data/rdoc_to_mmd.rb +14 -8
  84. data/scripts/generate_bash_completions.rb +1 -1
  85. data/scripts/generate_fish_completions.rb +1 -1
  86. data/scripts/generate_zsh_completions.rb +1 -1
  87. metadata +73 -5
  88. data/lib/doing/wwidfile.rb +0 -117
data/bin/doing CHANGED
@@ -35,8 +35,10 @@ colors = Doing::Color
35
35
  wwid = Doing::WWID.new
36
36
 
37
37
  Doing.logger.log_level = :info
38
+ env_log_level = nil
38
39
 
39
40
  if ENV['DOING_LOG_LEVEL'] || ENV['DOING_DEBUG'] || ENV['DOING_QUIET'] || ENV['DOING_VERBOSE'] || ENV['DOING_PLUGIN_DEBUG']
41
+ env_log_level = true
40
42
  # Quiet always wins
41
43
  if ENV['DOING_QUIET'] && ENV['DOING_QUIET'].truthy?
42
44
  Doing.logger.log_level = :error
@@ -82,6 +84,12 @@ switch %i[p pager], default_value: settings['paginate']
82
84
  desc 'Answer yes/no menus with default option'
83
85
  switch [:default], default_value: false
84
86
 
87
+ desc 'Answer all yes/no menus with yes'
88
+ switch [:yes], negatable: false
89
+
90
+ desc 'Answer all yes/no menus with no'
91
+ switch [:no], negatable: false
92
+
85
93
  desc 'Exclude auto tags and default tags'
86
94
  switch %i[x noauto], default_value: false, negatable: false
87
95
 
@@ -121,9 +129,9 @@ command %i[now next] do |c|
121
129
  c.desc "Edit entry with #{Doing::Util.default_editor}"
122
130
  c.switch %i[e editor], negatable: false, default_value: false
123
131
 
124
- c.desc 'Backdate start time [4pm|20m|2h|yesterday noon]'
132
+ c.desc 'Backdate start time [4pm|20m|2h|"yesterday noon"]'
125
133
  c.arg_name 'DATE_STRING'
126
- c.flag %i[b back]
134
+ c.flag %i[b back started]
127
135
 
128
136
  c.desc 'Timed entry, marks last entry in section as @done'
129
137
  c.switch %i[f finish_last], negatable: false, default_value: false
@@ -151,29 +159,34 @@ command %i[now next] do |c|
151
159
  options[:section] = settings['current_section']
152
160
  end
153
161
 
154
- if options[:e] || (args.empty? && $stdin.stat.size.zero?)
162
+ if options[:editor] || (args.empty? && $stdin.stat.size.zero?)
155
163
  raise MissingEditor, 'No EDITOR variable defined in environment' if Doing::Util.default_editor.nil?
156
164
 
157
- input = ''
165
+ input = date.strftime('%F %R | ')
158
166
  input += args.join(' ') unless args.empty?
159
167
  input = wwid.fork_editor(input).strip
160
168
 
161
169
  raise EmptyInput, 'No content' if input.empty?
162
170
 
163
- title, note = wwid.format_input(input)
164
- note.push(options[:n]) if options[:n]
165
- wwid.add_item(title.cap_first, section, { note: note, back: date, timed: options[:f] })
171
+ date, title, note = wwid.format_input(input)
172
+ note.add(options[:note]) if options[:note]
173
+ wwid.add_item(title.cap_first, section, { note: note, back: date, timed: options[:finish_last] })
166
174
  wwid.write(wwid.doing_file)
167
175
  elsif args.length.positive?
168
- title, note = wwid.format_input(args.join(' '))
169
- note.push(options[:n]) if options[:n]
170
- wwid.add_item(title.cap_first, section, { note: note, back: date, timed: options[:f] })
176
+ d, title, note = wwid.format_input(args.join(' '))
177
+ date = d.nil? ? date : d
178
+ note.add(options[:note]) if options[:note]
179
+ wwid.add_item(title.cap_first, section, { note: note, back: date, timed: options[:finish_last] })
171
180
  wwid.write(wwid.doing_file)
172
181
  elsif $stdin.stat.size.positive?
173
- input = $stdin.read
174
- title, note = wwid.format_input(input)
175
- note.push(options[:n]) if options[:n]
176
- wwid.add_item(title.cap_first, section, { note: note, back: date, timed: options[:f] })
182
+ input = $stdin.read.strip
183
+ d, title, note = wwid.format_input(input)
184
+ unless d.nil?
185
+ Doing.logger.debug('Parser:', 'Date detected in input, overriding command line values')
186
+ date = d
187
+ end
188
+ note.add(options[:note]) if options[:note]
189
+ wwid.add_item(title.cap_first, section, { note: note, back: date, timed: options[:finish_last] })
177
190
  wwid.write(wwid.doing_file)
178
191
  else
179
192
  raise EmptyInput, 'You must provide content when creating a new entry'
@@ -238,14 +251,13 @@ command %i[reset begin] do |c|
238
251
  items = wwid.filter_items([], opt: options)
239
252
 
240
253
  if options[:interactive]
241
- last_entry = wwid.choose_from_items(items, {
254
+ last_entry = Doing::Prompt.choose_from_items(items, include_section: options[:section].nil?,
242
255
  menu: true,
243
256
  header: '',
244
257
  prompt: 'Select an entry to start/reset > ',
245
258
  multiple: false,
246
259
  sort: false,
247
- show_if_single: true
248
- }, include_section: options[:section].nil? )
260
+ show_if_single: true)
249
261
  else
250
262
  last_entry = items.last
251
263
  end
@@ -344,7 +356,7 @@ command :note do |c|
344
356
  last_note = last_entry.note || Doing::Note.new
345
357
  new_note = Doing::Note.new
346
358
 
347
- if options[:e] || (args.empty? && $stdin.stat.size.zero? && !options[:r])
359
+ if options[:editor] || (args.empty? && $stdin.stat.size.zero? && !options[:remove])
348
360
  raise MissingEditor, 'No EDITOR variable defined in environment' if Doing::Util.default_editor.nil?
349
361
 
350
362
  input = !args.empty? ? args.join(' ') : ''
@@ -357,14 +369,14 @@ command :note do |c|
357
369
 
358
370
  input = prev_input.add(input)
359
371
 
360
- input = wwid.fork_editor([last_entry.title, '### Edit below this line', input.to_s].join("\n")).strip
361
- _title, note = wwid.format_input(input)
372
+ input = wwid.fork_editor(prev_input.strip_lines.join("\n"), message: nil).strip
373
+ note = input
362
374
  options[:remove] = true
363
375
  new_note.add(note)
364
376
  elsif !args.empty?
365
377
  new_note.add(args.join(' '))
366
378
  elsif $stdin.stat.size.positive?
367
- new_note.add($stdin.read)
379
+ new_note.add($stdin.read.strip)
368
380
  else
369
381
  raise EmptyInput, 'You must provide content when adding a note' unless options[:remove]
370
382
  end
@@ -423,31 +435,35 @@ command :meanwhile do |c|
423
435
  end
424
436
  input = ''
425
437
 
426
- if options[:e]
438
+ if options[:editor]
427
439
  raise MissingEditor, 'No EDITOR variable defined in environment' if Doing::Util.default_editor.nil?
428
-
440
+ input += date.strftime('%F %R | ')
429
441
  input += args.join(' ') unless args.empty?
430
442
  input = wwid.fork_editor(input).strip
431
443
  elsif !args.empty?
432
444
  input = args.join(' ')
433
445
  elsif $stdin.stat.size.positive?
434
- input = $stdin.read
446
+ input = $stdin.read.strip
435
447
  end
436
448
 
437
449
  if input && !input.empty?
438
- input, note = wwid.format_input(input)
450
+ d, input, note = wwid.format_input(input)
451
+ unless d.nil?
452
+ Doing.logger.debug('Parser:', 'Date detected in input, overriding command line values')
453
+ date = d
454
+ end
439
455
  else
440
456
  input = nil
441
457
  note = []
442
458
  end
443
459
 
444
- if options[:n]
445
- note.push(options[:n])
460
+ if options[:note]
461
+ note.push(options[:note])
446
462
  elsif note.empty?
447
463
  note = nil
448
464
  end
449
465
 
450
- wwid.stop_start('meanwhile', { new_item: input, back: date, section: section, archive: options[:a], note: note })
466
+ wwid.stop_start('meanwhile', { new_item: input, back: date, section: section, archive: options[:archive], note: note })
451
467
  wwid.write(wwid.doing_file)
452
468
  end
453
469
  end
@@ -465,11 +481,11 @@ command :template do |c|
465
481
  c.switch %i[l list], negatable: false
466
482
 
467
483
  c.desc 'List in single column for completion'
468
- c.switch %i[c]
484
+ c.switch %i[c column]
469
485
 
470
486
  c.action do |_global_options, options, args|
471
- if options[:list] || options[:c]
472
- if options[:c]
487
+ if options[:list] || options[:column]
488
+ if options[:column]
473
489
  $stdout.print Doing::Plugins.plugin_templates.join("\n")
474
490
  else
475
491
  $stdout.puts "Available templates: #{Doing::Plugins.plugin_templates.join(', ')}"
@@ -478,7 +494,7 @@ command :template do |c|
478
494
  end
479
495
 
480
496
  if args.empty?
481
- type = wwid.choose_from(Doing::Plugins.plugin_templates, sorted: false, prompt: 'Select template type > ')
497
+ type = Doing::Prompt.choose_from(Doing::Plugins.plugin_templates, sorted: false, prompt: 'Select template type > ')
482
498
  else
483
499
  type = args[0]
484
500
  end
@@ -613,22 +629,29 @@ command :later do |c|
613
629
  if options[:editor] || (args.empty? && $stdin.stat.size.zero?)
614
630
  raise MissingEditor, 'No EDITOR variable defined in environment' if Doing::Util.default_editor.nil?
615
631
 
616
- input = args.empty? ? '' : args.join(' ')
632
+ input += date.strftime('%F %R | ')
633
+ input += args.empty? ? '' : args.join(' ')
617
634
  input = wwid.fork_editor(input).strip
618
635
  raise EmptyInput, 'No content' unless input && !input.empty?
619
636
 
620
- title, note = wwid.format_input(input)
621
- note.push(options[:n]) if options[:n]
637
+ d, title, note = wwid.format_input(input)
638
+ date = d.nil? ? date : d
639
+ note.add(options[:note]) if options[:note]
622
640
  wwid.add_item(title.cap_first, 'Later', { note: note, back: date })
623
641
  wwid.write(wwid.doing_file)
624
642
  elsif !args.empty?
625
- title, note = wwid.format_input(args.join(' '))
626
- note.push(options[:n]) if options[:n]
643
+ d, title, note = wwid.format_input(args.join(' '))
644
+ date = d.nil? ? date : d
645
+ note.add(options[:note]) if options[:note]
627
646
  wwid.add_item(title.cap_first, 'Later', { note: note, back: date })
628
647
  wwid.write(wwid.doing_file)
629
648
  elsif $stdin.stat.size.positive?
630
- title, note = wwid.format_input($stdin.read)
631
- note.push(options[:n]) if options[:n]
649
+ d, title, note = wwid.format_input($stdin.read)
650
+ unless d.nil?
651
+ Doing.logger.debug('Parser:', 'Date detected in input, overriding command line values')
652
+ date = d
653
+ end
654
+ note.add(options[:note]) if options[:note]
632
655
  wwid.add_item(title.cap_first, 'Later', { note: note, back: date })
633
656
  wwid.write(wwid.doing_file)
634
657
  else
@@ -659,9 +682,9 @@ command %i[done did] do |c|
659
682
  c.arg_name 'DATE_STRING'
660
683
  c.flag [:at]
661
684
 
662
- c.desc 'Backdate start date by interval [4pm|20m|2h|yesterday noon]'
685
+ c.desc 'Backdate start date by interval or set to time [4pm|20m|2h|"yesterday noon"]'
663
686
  c.arg_name 'DATE_STRING'
664
- c.flag %i[b back]
687
+ c.flag %i[b back started]
665
688
 
666
689
  c.desc %(Set completion date to start date plus interval (XX[mhd] or HH:MM).
667
690
  If used without the --back option, the start date will be moved back to allow
@@ -710,8 +733,6 @@ command %i[done did] do |c|
710
733
  date = options[:took] ? finish_date - took : finish_date
711
734
  elsif options[:took]
712
735
  finish_date = date + took
713
- elsif options[:back]
714
- finish_date = date
715
736
  else
716
737
  finish_date = Time.now
717
738
  end
@@ -743,16 +764,17 @@ command %i[done did] do |c|
743
764
 
744
765
  old_entry = last_entry.dup
745
766
  last_entry.note.add(note)
746
- input = [last_entry.title, last_entry.note.to_s].join("\n")
767
+ input = ["#{last_entry.date.strftime('%F %R | ')}#{last_entry.title}", last_entry.note.strip_lines.join("\n")].join("\n")
747
768
  else
748
769
  is_new = true
749
- input = [args.join(' '), note.to_s].join("\n")
770
+ input = ["#{date.strftime('%F %R | ')}#{args.join(' ')}", note.strip_lines.join("\n")].join("\n")
750
771
  end
751
772
 
752
773
  input = wwid.fork_editor(input).strip
753
774
  raise EmptyInput, 'No content' unless input && !input.empty?
754
775
 
755
- title, note = wwid.format_input(input)
776
+ d, title, note = wwid.format_input(input)
777
+ date = d.nil? ? date : d
756
778
  new_entry = Doing::Item.new(date, title, section, note)
757
779
  if new_entry.should_finish?
758
780
  if new_entry.should_time?
@@ -763,23 +785,23 @@ command %i[done did] do |c|
763
785
  end
764
786
 
765
787
  if (is_new)
766
- wwid.content[section][:items].push(new_entry)
788
+ wwid.content.push(new_entry)
767
789
  else
768
- wwid.update_item(old_entry, new_entry)
790
+ wwid.content.update_item(old_entry, new_entry)
769
791
  end
770
792
 
771
- if options[:a]
793
+ if options[:archive]
772
794
  wwid.move_item(new_entry, 'Archive', label: true)
773
795
  end
774
796
 
775
797
  wwid.write(wwid.doing_file)
776
798
  elsif args.empty? && $stdin.stat.size.zero?
777
- if options[:r]
799
+ if options[:remove]
778
800
  wwid.tag_last({ tags: ['done'], count: 1, section: section, remove: true })
779
801
  else
780
802
  note = options[:note] ? Doing::Note.new(options[:note]) : nil
781
803
  opt = {
782
- archive: options[:a],
804
+ archive: options[:archive],
783
805
  back: finish_date,
784
806
  count: 1,
785
807
  date: options[:date],
@@ -793,9 +815,10 @@ command %i[done did] do |c|
793
815
  end
794
816
  elsif !args.empty?
795
817
  note = Doing::Note.new(options[:note])
796
- title, new_note = wwid.format_input([args.join(' '), note.to_s].join("\n"))
818
+ d, title, new_note = wwid.format_input([args.join(' '), note.strip_lines.join("\n")].join("\n"))
819
+ date = d.nil? ? date : d
797
820
  title.chomp!
798
- section = 'Archive' if options[:a]
821
+ section = 'Archive' if options[:archive]
799
822
  new_entry = Doing::Item.new(date, title, section, new_note)
800
823
  if new_entry.should_finish?
801
824
  if new_entry.should_time?
@@ -804,13 +827,17 @@ command %i[done did] do |c|
804
827
  new_entry.tag('done')
805
828
  end
806
829
  end
807
- wwid.content[section][:items].push(new_entry)
830
+ wwid.content.push(new_entry)
808
831
  wwid.write(wwid.doing_file)
809
832
  Doing.logger.info('Entry Added:', new_entry.title)
810
833
  elsif $stdin.stat.size.positive?
811
- title, note = wwid.format_input($stdin.read)
834
+ d, title, note = wwid.format_input($stdin.read.strip)
835
+ unless d.nil?
836
+ Doing.logger.debug('Parser:', 'Date detected in input, overriding command line values')
837
+ date = d
838
+ end
812
839
  note.add(options[:note]) if options[:note]
813
- section = options[:a] ? 'Archive' : section
840
+ section = options[:archive] ? 'Archive' : section
814
841
  new_entry = Doing::Item.new(date, title, section, note)
815
842
 
816
843
  if new_entry.should_finish?
@@ -821,7 +848,7 @@ command %i[done did] do |c|
821
848
  end
822
849
  end
823
850
 
824
- wwid.content[section][:items].push(new_entry)
851
+ wwid.content.push(new_entry)
825
852
  wwid.write(wwid.doing_file)
826
853
  Doing.logger.info('Entry Added:', new_entry.title)
827
854
  else
@@ -907,7 +934,7 @@ command :cancel do |c|
907
934
  end
908
935
 
909
936
  opts = {
910
- archive: options[:a],
937
+ archive: options[:archive],
911
938
  case: options[:case].normalize_case,
912
939
  count: count,
913
940
  date: false,
@@ -1188,7 +1215,7 @@ command :tag do |c|
1188
1215
  c.desc 'Tag last entry (or entries) not marked @done'
1189
1216
  c.switch %i[u unfinished], negatable: false, default_value: false
1190
1217
 
1191
- c.desc 'Autotag entries based on autotag configuration in ~/.doingrc'
1218
+ c.desc 'Autotag entries based on autotag configuration in ~/.config/doing/config.yml'
1192
1219
  c.switch %i[a autotag], negatable: false, default_value: false
1193
1220
 
1194
1221
  c.desc 'Tag the last X entries containing TAG.
@@ -1279,15 +1306,15 @@ command :tag do |c|
1279
1306
  end
1280
1307
 
1281
1308
 
1282
- question = if options[:a]
1309
+ question = if options[:aarchive]
1283
1310
  "Are you sure you want to autotag all records#{section_q}"
1284
- elsif options[:r]
1311
+ elsif options[:remove]
1285
1312
  "Are you sure you want to remove #{tags.join(' and ')} from all records#{section_q}"
1286
1313
  else
1287
1314
  "Are you sure you want to add #{tags.join(' and ')} to all records#{section_q}"
1288
1315
  end
1289
1316
 
1290
- res = wwid.yn(question, default_response: false)
1317
+ res = Doing::Prompt.yn(question, default_response: false)
1291
1318
 
1292
1319
  raise UserCancelled unless res
1293
1320
  end
@@ -1408,7 +1435,7 @@ command [:mark, :flag] do |c|
1408
1435
  "Are you sure you want to flag all records#{section_q}"
1409
1436
  end
1410
1437
 
1411
- res = wwid.yn(question, default_response: false)
1438
+ res = Doing::Prompt.yn(question, default_response: false)
1412
1439
 
1413
1440
  exit_now! 'Cancelled' unless res
1414
1441
  end
@@ -1598,7 +1625,6 @@ command :show do |c|
1598
1625
  end
1599
1626
 
1600
1627
  opt = options.dup
1601
-
1602
1628
  opt[:sort_tags] = options[:tag_sort] =~ /^n/i
1603
1629
  opt[:count] = options[:count].to_i
1604
1630
  opt[:date_filter] = dates
@@ -1729,7 +1755,7 @@ command :recent do |c|
1729
1755
  c.switch %i[i interactive], negatable: false, default_value: false
1730
1756
 
1731
1757
  c.action do |global_options, options, args|
1732
- section = wwid.guess_section(options[:s]) || options[:s].cap_first
1758
+ section = wwid.guess_section(options[:section]) || options[:section].cap_first
1733
1759
 
1734
1760
  unless global_options[:version]
1735
1761
  if settings['templates']['recent'].key?('count')
@@ -1744,7 +1770,7 @@ command :recent do |c|
1744
1770
  count = args.empty? ? config_count : args[0].to_i
1745
1771
  end
1746
1772
 
1747
- options[:t] = true if options[:totals]
1773
+ options[:times] = true if options[:totals]
1748
1774
  options[:sort_tags] = options[:tag_sort] =~ /^n/i
1749
1775
 
1750
1776
  template = settings['templates']['recent'].deep_merge(settings['templates']['default'])
@@ -1753,7 +1779,7 @@ command :recent do |c|
1753
1779
  opts = {
1754
1780
  sort_tags: options[:sort_tags],
1755
1781
  tags_color: tags_color,
1756
- times: options[:t],
1782
+ times: options[:times],
1757
1783
  totals: options[:totals],
1758
1784
  interactive: options[:interactive]
1759
1785
  }
@@ -1802,7 +1828,7 @@ command :today do |c|
1802
1828
  c.action do |_global_options, options, _args|
1803
1829
  raise DoingRuntimeError, %(Invalid output type "#{options[:output]}") if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
1804
1830
 
1805
- options[:t] = true if options[:totals]
1831
+ options[:times] = true if options[:totals]
1806
1832
  options[:sort_tags] = options[:tag_sort] =~ /^n/i
1807
1833
  opt = {
1808
1834
  after: options[:after],
@@ -1863,14 +1889,14 @@ command :on do |c|
1863
1889
 
1864
1890
  raise InvalidTimeExpression, 'Unrecognized date string' unless start
1865
1891
 
1866
- message = "Date interpreted as #{start}"
1892
+ message = "date interpreted as #{start}"
1867
1893
  message += " to #{finish}" if finish
1868
- Doing.logger.debug(message)
1894
+ Doing.logger.debug('Interpreter:', message)
1869
1895
 
1870
- options[:t] = true if options[:totals]
1896
+ options[:times] = true if options[:totals]
1871
1897
  options[:sort_tags] = options[:tag_sort] =~ /^n/i
1872
1898
 
1873
- Doing::Pager.page wwid.list_date([start, finish], options[:s], options[:t], options[:output],
1899
+ Doing::Pager.page wwid.list_date([start, finish], options[:section], options[:times], options[:output],
1874
1900
  { totals: options[:totals], sort_tags: options[:sort_tags] }).chomp
1875
1901
  end
1876
1902
  end
@@ -1918,12 +1944,12 @@ command :since do |c|
1918
1944
 
1919
1945
  raise InvalidTimeExpression, 'Unrecognized date string' unless start
1920
1946
 
1921
- Doing.logger.debug("Date interpreted as #{start} through the current time")
1947
+ Doing.logger.debug('Interpreter:', "date interpreted as #{start} through the current time")
1922
1948
 
1923
- options[:t] = true if options[:totals]
1949
+ options[:times] = true if options[:totals]
1924
1950
  options[:sort_tags] = options[:tag_sort] =~ /^n/i
1925
1951
 
1926
- Doing::Pager.page wwid.list_date([start, finish], options[:s], options[:t], options[:output],
1952
+ Doing::Pager.page wwid.list_date([start, finish], options[:section], options[:times], options[:output],
1927
1953
  { totals: options[:totals], sort_tags: options[:sort_tags] }).chomp
1928
1954
  end
1929
1955
  end
@@ -2053,9 +2079,9 @@ command :last do |c|
2053
2079
  end
2054
2080
 
2055
2081
  if options[:editor]
2056
- wwid.edit_last(section: options[:s], options: { search: search, fuzzy: options[:fuzzy], case: options[:case], tag: tags, tag_bool: options[:bool], not: options[:not] })
2082
+ wwid.edit_last(section: options[:section], options: { search: search, fuzzy: options[:fuzzy], case: options[:case], tag: tags, tag_bool: options[:bool], not: options[:not] })
2057
2083
  else
2058
- Doing::Pager::page wwid.last(times: true, section: options[:s],
2084
+ Doing::Pager::page wwid.last(times: true, section: options[:section],
2059
2085
  options: { search: search, fuzzy: options[:fuzzy], case: options[:case], negate: options[:not], tag: tags, tag_bool: options[:bool] }).strip
2060
2086
  end
2061
2087
  end
@@ -2067,8 +2093,8 @@ command :sections do |c|
2067
2093
  c.switch %i[c column], negatable: false, default_value: false
2068
2094
 
2069
2095
  c.action do |_global_options, options, _args|
2070
- joiner = options[:c] ? "\n" : "\t"
2071
- print wwid.sections.join(joiner)
2096
+ joiner = options[:column] ? "\n" : "\t"
2097
+ print wwid.content.section_titles.join(joiner)
2072
2098
  end
2073
2099
  end
2074
2100
 
@@ -2089,7 +2115,7 @@ command :add_section do |c|
2089
2115
  c.action do |_global_options, _options, args|
2090
2116
  raise InvalidArgument, "Section #{args[0]} already exists" if wwid.sections.include?(args[0])
2091
2117
 
2092
- wwid.add_section(args.join(' ').cap_first)
2118
+ wwid.content.add_section(args.join(' ').cap_first, log: true)
2093
2119
  wwid.write(wwid.doing_file)
2094
2120
  end
2095
2121
  end
@@ -2247,6 +2273,7 @@ command :view do |c|
2247
2273
  rescue WrongCommand => exception
2248
2274
  cmd = commands[:show]
2249
2275
  options[:sort] = 'asc'
2276
+ options[:tag_order] = 'asc'
2250
2277
  action = cmd.send(:get_action, nil)
2251
2278
  return action.call(global_options, options, args)
2252
2279
  end
@@ -2289,12 +2316,9 @@ command :view do |c|
2289
2316
  # If the -o/--output flag was specified, override any default in the view template
2290
2317
  options[:output] ||= view.key?('output_format') ? view['output_format'] : 'template'
2291
2318
 
2292
- count = if options[:c]
2293
- options[:c]
2294
- else
2295
- view.key?('count') ? view['count'] : 10
2296
- end
2297
- section = if options[:s]
2319
+ count = options[:count] ? options[:count] : view.key?('count') ? view['count'] : 10
2320
+
2321
+ section = if options[:section]
2298
2322
  section
2299
2323
  else
2300
2324
  view.key?('section') ? view['section'] : settings['current_section']
@@ -2312,7 +2336,7 @@ command :view do |c|
2312
2336
  view.key?('tag_order') ? view['tag_order'].normalize_order : 'asc'
2313
2337
  end
2314
2338
 
2315
- options[:t] = true if totals
2339
+ options[:times] = true if totals
2316
2340
  output_format = options[:output]&.downcase || 'template'
2317
2341
 
2318
2342
  options[:sort_tags] = if options[:tag_sort]
@@ -2386,7 +2410,7 @@ command :views do |c|
2386
2410
  c.switch %i[c column], default_value: false
2387
2411
 
2388
2412
  c.action do |_global_options, options, _args|
2389
- joiner = options[:c] ? "\n" : "\t"
2413
+ joiner = options[:column] ? "\n" : "\t"
2390
2414
  print wwid.views.join(joiner)
2391
2415
  end
2392
2416
  end
@@ -2552,6 +2576,10 @@ end
2552
2576
  desc 'Open the "doing" file in an editor'
2553
2577
  long_desc "`doing open` defaults to using the editor_app setting in #{config.config_file} (#{settings.key?('editor_app') ? settings['editor_app'] : 'not set'})."
2554
2578
  command :open do |c|
2579
+ c.desc 'Open with editor command (e.g. vim, mate)'
2580
+ c.arg_name 'COMMAND'
2581
+ c.flag %i[e editor]
2582
+
2555
2583
  if `uname` =~ /Darwin/
2556
2584
  c.desc 'Open with app name'
2557
2585
  c.arg_name 'APP_NAME'
@@ -2567,11 +2595,17 @@ command :open do |c|
2567
2595
  params.delete_if do |k, v|
2568
2596
  k.instance_of?(String) || v.nil? || v == false
2569
2597
  end
2570
- if `uname` =~ /Darwin/
2598
+
2599
+ if options[:editor]
2600
+ raise MissingEditor, "Editor #{options[:editor]} not found" unless Doing::Util.exec_available(options[:editor])
2601
+
2602
+ editor = TTY::Which.which(options[:editor])
2603
+ system %(#{editor} "#{File.expand_path(wwid.doing_file)}")
2604
+ elsif `uname` =~ /Darwin/
2571
2605
  if options[:app]
2572
- system %(open -a "#{options[:a]}" "#{File.expand_path(wwid.doing_file)}")
2606
+ system %(open -a "#{options[:app]}" "#{File.expand_path(wwid.doing_file)}")
2573
2607
  elsif options[:bundle_id]
2574
- system %(open -b "#{options[:b]}" "#{File.expand_path(wwid.doing_file)}")
2608
+ system %(open -b "#{options[:bundle_id]}" "#{File.expand_path(wwid.doing_file)}")
2575
2609
  elsif Doing::Util.find_default_editor('doing_file')
2576
2610
  editor = Doing::Util.find_default_editor('doing_file')
2577
2611
  if Doing::Util.exec_available(editor)
@@ -2591,132 +2625,240 @@ command :open do |c|
2591
2625
  end
2592
2626
 
2593
2627
  desc 'Edit the configuration file or output a value from it'
2594
- long_desc %(Run without arguments, `doing config` opens your `.doingrc` in an editor.
2628
+ long_desc %(Run without arguments, `doing config` opens your `config.yml` in an editor.
2595
2629
  If local configurations are found in the path between the current directory
2596
- and `~/.doingrc`, a menu will allow you to select which to open in the editor.
2630
+ and the root (/), a menu will allow you to select which to open in the editor.
2597
2631
 
2598
2632
  It will use the editor defined in `config_editor_app`, or one specified with `--editor`.
2599
2633
 
2600
- Use `doing config -d` to output the configuration to the terminal, and
2634
+ Use `doing config get` to output the configuration to the terminal, and
2601
2635
  provide a dot-separated key path to get a specific value. Shows the current value
2602
2636
  including keys/overrides set by local configs.)
2603
- arg_name 'KEY_PATH'
2604
2637
  command :config do |c|
2605
2638
  c.example 'doing config', desc: "Open an active configuration in #{Doing::Util.find_default_editor('config')}"
2606
- c.example 'doing config -d doing_file', desc: 'Output the value of a config key as YAML'
2607
- c.example 'doing config -d plugins.say.say_voice -o json', desc: 'Output the value of a key path as JSON'
2639
+ c.example 'doing config get doing_file', desc: 'Output the value of a config key as YAML'
2640
+ c.example 'doing config get plugins.plugin_path -o json', desc: 'Output the value of a key path as JSON'
2641
+ c.example 'doing config set plugins.say.say_voice Alex', desc: 'Set the value of a key path and update config file'
2642
+ c.example 'doing config set plug.say.voice Zarvox', desc: 'Key paths for get and set are fuzzy matched'
2608
2643
 
2609
- c.desc 'Editor to use'
2610
- c.arg_name 'EDITOR'
2611
- c.flag %i[e editor], default_value: nil
2644
+ c.default_command :edit
2612
2645
 
2613
- c.desc 'Show a config key value based on arguments. Separate key paths with colons or dots, e.g. "export_templates.html". Empty arguments outputs the entire config.'
2614
- c.switch %i[d dump], negatable: false
2646
+ c.desc 'DEPRECATED'
2647
+ c.switch %i[d dump]
2615
2648
 
2616
- c.desc 'Format for --dump (json|yaml|raw)'
2617
- c.arg_name 'FORMAT'
2618
- c.flag %i[o output], default_value: 'yaml', must_match: /^(?:y(?:aml)?|j(?:son)?|r(?:aw)?)$/
2649
+ c.desc 'DEPRECATED'
2650
+ c.switch %i[u update]
2619
2651
 
2620
- c.desc 'Update config file with missing configuration options'
2621
- c.switch %i[u update], default_value: false, negatable: false
2652
+ c.desc 'List configuration paths, including .doingrc files in the current and parent directories'
2653
+ c.long_desc 'Config files are listed in order of precedence (if there are multiple configs detected).
2654
+ Values defined in the top item in the list will override values in configutations below it.'
2655
+ c.command :list do |list|
2656
+ list.action do |global, options, args|
2657
+ puts config.additional_configs.join("\n")
2658
+ puts config.config_file
2659
+ end
2660
+ end
2622
2661
 
2623
- if `uname` =~ /Darwin/
2624
- c.desc 'Application to use'
2625
- c.arg_name 'APP_NAME'
2626
- c.flag [:a]
2662
+ c.desc 'Open config file in editor'
2663
+ c.command :edit do |edit|
2664
+ edit.example 'doing config edit', desc: 'Open a config file in the default editor'
2665
+ edit.example 'doing config edit --editor vim', desc: 'Open config in specific editor'
2627
2666
 
2628
- c.desc 'Application bundle id to use'
2629
- c.arg_name 'BUNDLE_ID'
2630
- c.flag [:b]
2667
+ edit.desc 'Editor to use'
2668
+ edit.arg_name 'EDITOR'
2669
+ edit.flag %i[e editor], default_value: nil
2670
+
2671
+ if `uname` =~ /Darwin/
2672
+ edit.desc 'Application to use'
2673
+ edit.arg_name 'APP_NAME'
2674
+ edit.flag %i[a app]
2675
+
2676
+ edit.desc 'Application bundle id to use'
2677
+ edit.arg_name 'BUNDLE_ID'
2678
+ edit.flag %i[b bundle_id]
2679
+
2680
+ 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'})"
2681
+ edit.switch %i[x default]
2682
+ end
2683
+
2684
+ edit.action do |global, options, args|
2685
+ if options[:update] || options[:dump]
2686
+ cmd = commands[:config]
2687
+ if options[:update]
2688
+ cmd = cmd.commands[:update]
2689
+ elsif options[:dump]
2690
+ cmd = cmd.commands[:get]
2691
+ end
2692
+ action = cmd.send(:get_action, nil)
2693
+ action.call(global, options, args)
2694
+ Doing.logger.warn('Deprecated:', '--dump and --update are deprecated,
2695
+ use `doing config get` and `doing config update`')
2696
+ Doing.logger.output_results
2697
+ return
2698
+ end
2699
+
2700
+ config_file = config.choose_config
2701
+
2702
+ if `uname` =~ /Darwin/
2703
+ if options[:default]
2704
+ editor = Doing::Util.find_default_editor('config')
2705
+ if editor
2706
+ if Doing::Util.exec_available(editor)
2707
+ system %(#{editor} "#{config_file}")
2708
+ else
2709
+ `open -a "#{editor}" "#{config_file}"`
2710
+ end
2711
+ else
2712
+ raise InvalidArgument, 'No viable editor found in config or environment.'
2713
+ end
2714
+ elsif options[:app] || options[:bundle_id]
2715
+ if options[:app]
2716
+ `open -a "#{options[:app]}" "#{config_file}"`
2717
+ elsif options[:bundle_id]
2718
+ `open -b #{options[:bundle_id]} "#{config_file}"`
2719
+ end
2720
+ else
2721
+ editor = options[:editor] || Doing::Util.find_default_editor('config')
2722
+
2723
+ raise MissingEditor, 'No viable editor defined in config or environment' unless editor
2631
2724
 
2632
- c.desc "Use the config_editor_app defined in ~/.doingrc (#{settings.key?('config_editor_app') ? settings['config_editor_app'] : 'config_editor_app not set'})"
2633
- c.switch [:x]
2725
+ if Doing::Util.exec_available(editor)
2726
+ system %(#{editor} "#{config_file}")
2727
+ else
2728
+ `open -a "#{editor}" "#{config_file}"`
2729
+ end
2730
+ end
2731
+ else
2732
+ editor = options[:editor] || Doing::Util.default_editor
2733
+ raise MissingEditor, 'No EDITOR variable defined in environment' unless editor && Doing::Util.exec_available(editor)
2734
+
2735
+ system %(#{editor} "#{config_file}")
2736
+ end
2737
+ end
2634
2738
  end
2635
2739
 
2636
- c.action do |_global_options, options, args|
2637
- if options[:update]
2740
+ c.desc 'Update default config file, adding any missing keys'
2741
+ c.command %i[update refresh] do |update|
2742
+ update.action do |_global, options, args|
2638
2743
  config.configure({rewrite: true, ignore_local: true})
2639
- return
2744
+ Doing.logger.warn('Config:', 'config refreshed')
2640
2745
  end
2746
+ end
2747
+
2748
+ c.desc 'Undo the last change to a config file'
2749
+ c.command :undo do |undo|
2750
+ undo.action do |_global, options, args|
2751
+ config_file = config.choose_config
2752
+ wwid.restore_backup(config_file)
2753
+ end
2754
+ end
2755
+
2756
+ c.desc 'Output a key\'s value'
2757
+ c.arg 'KEY_PATH'
2758
+ c.command %i[get dump] do |dump|
2759
+ dump.example 'doing config get', desc: 'Output the entire configuration'
2760
+ dump.example 'doing config get timer_format --output raw', desc: 'Output the value of timer_format as a plain string'
2761
+ dump.example 'doing config get doing_file', desc: 'Output the value of the doing_file setting, respecting local configurations'
2762
+ dump.example 'doing config get -o json plug.plugpath', desc: 'Key path is fuzzy matched: output the value of plugins->plugin_path as JSON'
2763
+
2764
+ dump.desc 'Format for output (json|yaml|raw)'
2765
+ dump.arg_name 'FORMAT'
2766
+ dump.flag %i[o output], default_value: 'yaml', must_match: /^(?:y(?:aml)?|j(?:son)?|r(?:aw)?)$/
2767
+
2768
+ dump.action do |_global, options, args|
2641
2769
 
2642
- if options[:dump]
2643
2770
  keypath = args.join('.')
2644
2771
  cfg = config.value_for_key(keypath)
2772
+ real_path = config.resolve_key_path(keypath)
2645
2773
 
2646
2774
  if cfg
2647
- $stdout.puts case options[:output]
2648
- when /^j/
2649
- JSON.pretty_generate(cfg)
2650
- when /^r/
2651
- cfg.map {|k, v| v.to_s }
2652
- else
2653
- YAML.dump(cfg)
2654
- end
2775
+ val = cfg.map {|k, v| v }[0]
2776
+ if real_path.count.positive?
2777
+ nested_cfg = {}
2778
+ nested_cfg.deep_set(real_path, val)
2779
+ else
2780
+ nested_cfg = val
2781
+ end
2782
+
2783
+ if options[:output] =~ /^r/
2784
+ if val.is_a?(Hash)
2785
+ $stdout.puts YAML.dump(val)
2786
+ elsif val.is_a?(Array)
2787
+ $stdout.puts val.join(', ')
2788
+ else
2789
+ $stdout.puts val.to_s
2790
+ end
2791
+ else
2792
+ $stdout.puts case options[:output]
2793
+ when /^j/
2794
+ JSON.pretty_generate(val)
2795
+ else
2796
+ YAML.dump(nested_cfg)
2797
+ end
2798
+ end
2655
2799
  else
2656
2800
  Doing.logger.log_now(:error, 'Config:', "Key #{keypath} not found")
2657
2801
  end
2658
2802
  Doing.logger.output_results
2659
2803
  return
2660
2804
  end
2805
+ end
2661
2806
 
2662
- if config.additional_configs.count.positive?
2663
- choices = [config.config_file]
2664
- choices.concat(config.additional_configs)
2665
- res = wwid.choose_from(choices.uniq.sort.reverse, sorted: false, prompt: 'Local configs found, select which to edit > ')
2807
+ c.desc 'Set a key\'s value in the config file'
2808
+ c.arg 'KEY VALUE'
2809
+ c.command :set do |set|
2810
+ set.example 'doing config set timer_format human', desc: 'Set the value of timer_format to "human"'
2811
+ set.example 'doing config set plug.plugpath ~/my_plugins', desc: 'Key path is fuzzy matched: set the value of plugins->plugin_path'
2666
2812
 
2667
- raise UserCancelled, 'Cancelled' unless res
2813
+ set.desc 'Delete specified key'
2814
+ set.switch %i[r remove], default_value: false, negatable: false
2668
2815
 
2669
- config_file = res.strip || config.config_file
2670
- else
2671
- config_file = config.config_file
2672
- end
2816
+ set.action do |_global, options, args|
2817
+ if args.count < 2 && !options[:remove]
2818
+ raise InvalidArgument, 'config set requires at least two arguments, key path and value'
2673
2819
 
2674
- if `uname` =~ /Darwin/
2675
- if options[:x]
2676
- editor = Doing::Util.find_default_editor('config')
2677
- if editor
2678
- if Doing::Util.exec_available(editor)
2679
- system %(#{editor} "#{config_file}")
2680
- else
2681
- `open -a "#{editor}" "#{config_file}"`
2682
- end
2683
- else
2684
- raise InvalidArgument, 'No viable editor found in config or environment.'
2685
- end
2686
- elsif options[:a] || options[:b]
2687
- if options[:a]
2688
- `open -a "#{options[:a]}" "#{config_file}"`
2689
- elsif options[:b]
2690
- `open -b #{options[:b]} "#{config_file}"`
2691
- end
2692
- else
2693
- editor = options[:e] || Doing::Util.find_default_editor('config')
2820
+ end
2694
2821
 
2695
- raise MissingEditor, 'No viable editor defined in config or environment' unless editor
2822
+ value = options[:remove] ? nil : args.pop
2823
+ keypath = args.join('.')
2824
+ old_value = config.value_for_key(keypath).map { |k, v| v.to_s }
2825
+ real_path = config.resolve_key_path(keypath)
2826
+ raise InvalidArgument, 'Invalid key path' if real_path.empty?
2696
2827
 
2697
- if Doing::Util.exec_available(editor)
2698
- system %(#{editor} "#{config_file}")
2699
- else
2700
- `open -a "#{editor}" "#{config_file}"`
2701
- end
2828
+ config_file = config.choose_config
2829
+ cfg = YAML.safe_load_file(config_file) || {}
2830
+
2831
+ $stderr.puts "Updating #{config_file}".yellow
2832
+
2833
+ if options[:remove]
2834
+ cfg.deep_set(real_path, nil)
2835
+ $stderr.puts "#{'Deleting key:'.yellow} #{real_path.join('->').boldwhite}"
2836
+ else
2837
+ old_value = cfg.dig(*real_path) || 'empty'
2838
+ cfg.deep_set(real_path, value.set_type)
2839
+ $stderr.puts "#{'Key path:'.yellow} #{real_path.join('->').boldwhite}"
2840
+ $stderr.puts "#{'Previous:'.yellow} #{old_value.to_s.boldwhite}"
2841
+ $stderr.puts "#{' New:'.yellow} #{value.set_type.to_s.boldwhite}"
2702
2842
  end
2703
- else
2704
- editor = options[:e] || Doing::Util.default_editor
2705
- raise MissingEditor, 'No EDITOR variable defined in environment' unless editor && Doing::Util.exec_available(editor)
2706
2843
 
2707
- system %(#{editor} "#{config_file}")
2844
+ res = Doing::Prompt.yn('Update selected config', default_response: true)
2845
+
2846
+ raise UserCancelled, 'Cancelled' unless res
2847
+
2848
+ Doing::Util.write_to_file(config_file, YAML.dump(cfg), backup: true)
2849
+ Doing.logger.warn('Config:', "#{config_file} updated")
2708
2850
  end
2709
2851
  end
2710
2852
  end
2711
2853
 
2712
- desc 'Undo the last change to the doing_file'
2854
+ desc 'Undo the last change to the Doing file'
2713
2855
  command :undo do |c|
2714
2856
  c.desc 'Specify alternate doing file'
2715
2857
  c.arg_name 'PATH'
2716
2858
  c.flag %i[f file], default_value: wwid.doing_file
2717
2859
 
2718
2860
  c.action do |_global_options, options, _args|
2719
- file = options[:f] || wwid.doing_file
2861
+ file = options[:file] || wwid.doing_file
2720
2862
  wwid.restore_backup(file)
2721
2863
  end
2722
2864
  end
@@ -2823,9 +2965,9 @@ pre do |global, _command, _options, _args|
2823
2965
 
2824
2966
  $stdout.puts "doing v#{Doing::VERSION}" if global[:version]
2825
2967
  unless STDOUT.isatty
2826
- Doing::Color::coloring = global[:pager] ? global[:color] : false
2968
+ Doing::Color.coloring = global[:pager] ? global[:color] : false
2827
2969
  else
2828
- Doing::Color::coloring = global[:color]
2970
+ Doing::Color.coloring = global[:color]
2829
2971
  end
2830
2972
 
2831
2973
  # Return true to proceed; false to abort and not call the
@@ -2853,13 +2995,21 @@ end
2853
2995
 
2854
2996
  around do |global, command, options, arguments, code|
2855
2997
  # Doing.logger.debug('Pager:', "Global: #{global[:pager]}, Config: #{settings['paginate']}, Pager: #{Doing::Pager.paginate}")
2856
- Doing.logger.adjust_verbosity(global)
2998
+ if env_log_level.nil?
2999
+ Doing.logger.adjust_verbosity(global)
3000
+ end
2857
3001
 
2858
3002
  if global[:stdout]
2859
3003
  Doing.logger.logdev = $stdout
2860
3004
  end
2861
3005
 
2862
- wwid.default_option = global[:default]
3006
+ if global[:yes]
3007
+ Doing::Prompt.force_answer = true
3008
+ elsif global[:no]
3009
+ Doing::Prompt.force_answer = false
3010
+ else
3011
+ Doing::Prompt.default_answer = global[:default]
3012
+ end
2863
3013
 
2864
3014
  if global[:config_file] && global[:config_file] != config.config_file
2865
3015
  Doing.logger.warn(format('%sWARNING:%s %sThe use of --config_file is deprecated, please set the environment variable DOING_CONFIG instead.', colors.flamingo, colors.default, colors.boldred))