doing 2.0.25 → 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 (81) 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 +28 -0
  6. data/Gemfile.lock +8 -1
  7. data/README.md +1 -1
  8. data/Rakefile +23 -4
  9. data/bin/doing +205 -127
  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 +40 -12
  53. data/example_plugin.rb +3 -3
  54. data/lib/completion/_doing.zsh +1 -1
  55. data/lib/completion/doing.bash +8 -8
  56. data/lib/completion/doing.fish +1 -1
  57. data/lib/doing/array.rb +36 -0
  58. data/lib/doing/colors.rb +70 -66
  59. data/lib/doing/completion.rb +6 -0
  60. data/lib/doing/configuration.rb +69 -28
  61. data/lib/doing/hash.rb +37 -0
  62. data/lib/doing/item.rb +77 -12
  63. data/lib/doing/items.rb +125 -0
  64. data/lib/doing/log_adapter.rb +55 -3
  65. data/lib/doing/note.rb +53 -1
  66. data/lib/doing/pager.rb +49 -38
  67. data/lib/doing/plugins/export/markdown_export.rb +4 -4
  68. data/lib/doing/plugins/export/template_export.rb +2 -2
  69. data/lib/doing/plugins/import/calendar_import.rb +4 -4
  70. data/lib/doing/plugins/import/doing_import.rb +5 -7
  71. data/lib/doing/plugins/import/timing_import.rb +3 -3
  72. data/lib/doing/prompt.rb +206 -0
  73. data/lib/doing/section.rb +30 -0
  74. data/lib/doing/string.rb +103 -27
  75. data/lib/doing/util.rb +14 -6
  76. data/lib/doing/version.rb +1 -1
  77. data/lib/doing/wwid.rb +306 -621
  78. data/lib/doing.rb +6 -2
  79. data/lib/examples/plugins/capture_thing_import.rb +162 -0
  80. metadata +73 -5
  81. data/lib/doing/wwidfile.rb +0 -117
@@ -102,7 +102,7 @@
102
102
  </div>
103
103
 
104
104
  <div id="footer">
105
- Generated on Thu Nov 18 16:39:11 2021 by
105
+ Generated on Sat Nov 27 10:06:03 2021 by
106
106
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
107
107
  0.9.26 (ruby-3.0.1).
108
108
  </div>
data/doing.gemspec CHANGED
@@ -31,10 +31,13 @@ spec = Gem::Specification.new do |s|
31
31
  s.add_development_dependency 'redcarpet', '~> 3.5', '>= 3.5.1'
32
32
  s.add_development_dependency 'github-markup', '~> 4.0', '>= 4.0.0'
33
33
  s.add_development_dependency 'parallel_tests', '~> 3.7', '>= 3.7.3'
34
+ s.add_development_dependency 'tty-spinner', '~> 0.9', '>= 0.9.3'
34
35
  s.add_runtime_dependency('tty-progressbar', '~> 0.18', '>= 0.18.2')
35
36
  s.add_runtime_dependency('gli', '~> 2.19', '>= 2.19.2')
36
37
  s.add_runtime_dependency('haml','~>5.0.0', '>= 5.0.0')
37
38
  s.add_runtime_dependency('chronic','~> 0.10', '>= 0.10.2')
38
39
  s.add_runtime_dependency('deep_merge', '~> 1.2', '>= 1.2.1')
40
+ s.add_runtime_dependency('tty-link', '~> 0.1', '>= 0.1.1')
41
+ s.add_runtime_dependency('tty-which', '~> 0.5', '>= 0.5.0')
39
42
  # s.add_runtime_dependency('amatch', '~> 0.4', '>= 0.4.0')
40
43
  end
data/doing.rdoc CHANGED
@@ -5,7 +5,7 @@ record of what you've been doing, complete with tag-based time tracking. The
5
5
  command line tool allows you to add entries, annotate with tags and notes, and
6
6
  view your entries with myriad options, with a focus on a "natural" language syntax.
7
7
 
8
- v2.0.25
8
+ v2.1.0pre
9
9
 
10
10
  === Global Options
11
11
  === --config_file arg
@@ -42,6 +42,11 @@ Show this message
42
42
 
43
43
 
44
44
 
45
+ === --no
46
+ Answer all yes/no menus with no
47
+
48
+
49
+
45
50
  === --[no-]notes
46
51
  Output notes if included in the template
47
52
 
@@ -72,6 +77,11 @@ Exclude auto tags and default tags
72
77
 
73
78
 
74
79
 
80
+ === --yes
81
+ Answer all yes/no menus with yes
82
+
83
+
84
+
75
85
  === Commands
76
86
  ==== Command: <tt>add_section SECTION_NAME</tt>
77
87
  Add a new section to the "doing" file
@@ -414,14 +424,14 @@ Open config file in editor
414
424
 
415
425
 
416
426
  ======= Options
417
- ======= -a APP_NAME
427
+ ======= -a|--app APP_NAME
418
428
 
419
429
  Application to use
420
430
 
421
431
  [Default Value] None
422
432
 
423
433
 
424
- ======= -b BUNDLE_ID
434
+ ======= -b|--bundle_id BUNDLE_ID
425
435
 
426
436
  Application bundle id to use
427
437
 
@@ -435,7 +445,7 @@ Editor to use
435
445
  [Default Value] None
436
446
 
437
447
 
438
- ======= -x
448
+ ======= -x|--[no-]default
439
449
  Use the config_editor_app defined in ~/.config/doing/config.yml (config_editor_app not set)
440
450
 
441
451
 
@@ -453,10 +463,21 @@ Format for output (json|yaml|raw)
453
463
  [Must Match] (?-mix:^(?:y(?:aml)?|j(?:son)?|r(?:aw)?)$)
454
464
 
455
465
 
466
+ ====== Command: <tt>list </tt>
467
+ List configuration paths, including .doingrc files in the current and parent directories
468
+
469
+ Config files are listed in order of precedence (if there are multiple configs detected).
470
+ Values defined in the top item in the list will override values in configutations below it.
456
471
  ====== Command: <tt>set </tt>
457
472
  Set a key's value in the config file
458
473
 
459
474
 
475
+ ======= Options
476
+ ======= -r|--remove
477
+ Delete specified key
478
+
479
+
480
+
460
481
  ====== Command: <tt>undo </tt>
461
482
  Undo the last change to a config file
462
483
 
@@ -479,9 +500,9 @@ Set finish date to specific date/time (natural langauge parsed, e.g. --at=1:30pm
479
500
  [Default Value] None
480
501
 
481
502
 
482
- ===== -b|--back DATE_STRING
503
+ ===== -b|--back|--started DATE_STRING
483
504
 
484
- Backdate start date by interval [4pm|20m|2h|yesterday noon]
505
+ Backdate start date by interval or set to time [4pm|20m|2h|"yesterday noon"]
485
506
 
486
507
  [Default Value] None
487
508
 
@@ -734,7 +755,7 @@ List commands one per line, to assist with shell completion
734
755
  ==== Command: <tt>import PATH</tt>
735
756
  Import entries from an external source
736
757
 
737
- Imports entries from other sources. Available plugins: calendar, doing, timing
758
+ Imports entries from other sources. Available plugins: calendar, capturething, doing, timing
738
759
  ===== Options
739
760
  ===== --after DATE_STRING
740
761
 
@@ -797,7 +818,7 @@ Tag all imported entries
797
818
 
798
819
  ===== --type TYPE
799
820
 
800
- Import type (calendar|doing|timing)
821
+ Import type (calendar|capturething|doing|timing)
801
822
 
802
823
  [Default Value] doing
803
824
 
@@ -1110,9 +1131,9 @@ A parenthetical at the end of the entry will be converted to a note.
1110
1131
 
1111
1132
  Run with no argument to create a new entry using vim.
1112
1133
  ===== Options
1113
- ===== -b|--back DATE_STRING
1134
+ ===== -b|--back|--started DATE_STRING
1114
1135
 
1115
- Backdate start time [4pm|20m|2h|yesterday noon]
1136
+ Backdate start time [4pm|20m|2h|"yesterday noon"]
1116
1137
 
1117
1138
  [Default Value] None
1118
1139
 
@@ -1199,6 +1220,13 @@ Open with app bundle id
1199
1220
  [Default Value] None
1200
1221
 
1201
1222
 
1223
+ ===== -e|--editor COMMAND
1224
+
1225
+ Open with editor command (e.g. vim, mate)
1226
+
1227
+ [Default Value] None
1228
+
1229
+
1202
1230
  ==== Command: <tt>plugins </tt>
1203
1231
  List installed plugins
1204
1232
 
@@ -1808,7 +1836,7 @@ Output HTML, CSS, and Markdown (ERB) templates for customization
1808
1836
  Templates are printed to STDOUT for piping to a file.
1809
1837
  Save them and use them in the configuration file under export_templates.
1810
1838
  ===== Options
1811
- ===== -c
1839
+ ===== -c|--[no-]column
1812
1840
  List in single column for completion
1813
1841
 
1814
1842
 
@@ -1874,7 +1902,7 @@ Show time totals at the end of output
1874
1902
 
1875
1903
 
1876
1904
  ==== Command: <tt>undo </tt>
1877
- Undo the last change to the doing_file
1905
+ Undo the last change to the Doing file
1878
1906
 
1879
1907
 
1880
1908
  ===== Options
data/example_plugin.rb CHANGED
@@ -136,9 +136,9 @@ module Doing
136
136
  # or :map to generate output.
137
137
  i = items[-1]
138
138
 
139
- # Format the item. Items are a hash with 4 keys: date,
140
- # title, section (parent section), and note. Start
141
- # time is in item.date. The wwid object has some
139
+ # Format the item. Items are an object with 4 methods:
140
+ # date, title, section (parent section), and note.
141
+ # Start time is in item.date. The wwid object has some
142
142
  # methods for calculation and formatting, including
143
143
  # wwid.item.end_date to convert the @done timestamp to
144
144
  # an end date.
@@ -48,7 +48,7 @@ function _doing() {
48
48
  'template:Output HTML'
49
49
  'test:Test Stuff'
50
50
  'today:List entries from today'
51
- 'undo:Undo the last change to the doing_file'
51
+ 'undo:Undo the last change to the Doing file'
52
52
  'view:Display a user-created view'
53
53
  'views:List available custom views'
54
54
  'wiki:Output a tag wiki'
@@ -81,9 +81,9 @@ _doing_config() {
81
81
  _doing_done() {
82
82
 
83
83
  if [[ "$token" == --* ]]; then
84
- COMPREPLY=( $( compgen -W '--archive --at --back --date --editor --note --remove --section --took --unfinished' -- $token ) )
84
+ COMPREPLY=( $( compgen -W '--archive --at --started --date --editor --note --remove --section --took --unfinished' -- $token ) )
85
85
  elif [[ "$token" == -* ]]; then
86
- COMPREPLY=( $( compgen -W '-a -b -e -n -r -s -t -u --archive --at --back --date --editor --note --remove --section --took --unfinished' -- $token ) )
86
+ COMPREPLY=( $( compgen -W '-a -e -n -r -s -t -u --archive --at --started --date --editor --note --remove --section --took --unfinished' -- $token ) )
87
87
 
88
88
  fi
89
89
  }
@@ -181,9 +181,9 @@ _doing_note() {
181
181
  _doing_now() {
182
182
 
183
183
  if [[ "$token" == --* ]]; then
184
- COMPREPLY=( $( compgen -W '--back --editor --finish_last --note --section' -- $token ) )
184
+ COMPREPLY=( $( compgen -W '--started --editor --finish_last --note --section' -- $token ) )
185
185
  elif [[ "$token" == -* ]]; then
186
- COMPREPLY=( $( compgen -W '-b -e -f -n -s --back --editor --finish_last --note --section' -- $token ) )
186
+ COMPREPLY=( $( compgen -W '-e -f -n -s --started --editor --finish_last --note --section' -- $token ) )
187
187
 
188
188
  fi
189
189
  }
@@ -201,9 +201,9 @@ _doing_on() {
201
201
  _doing_open() {
202
202
 
203
203
  if [[ "$token" == --* ]]; then
204
- COMPREPLY=( $( compgen -W '--app --bundle_id' -- $token ) )
204
+ COMPREPLY=( $( compgen -W '--app --bundle_id --editor' -- $token ) )
205
205
  elif [[ "$token" == -* ]]; then
206
- COMPREPLY=( $( compgen -W '-a -b --app --bundle_id' -- $token ) )
206
+ COMPREPLY=( $( compgen -W '-a -b -e --app --bundle_id --editor' -- $token ) )
207
207
 
208
208
  fi
209
209
  }
@@ -321,9 +321,9 @@ _doing_tag() {
321
321
  _doing_template() {
322
322
 
323
323
  if [[ "$token" == --* ]]; then
324
- COMPREPLY=( $( compgen -W '--list' -- $token ) )
324
+ COMPREPLY=( $( compgen -W '--column --list' -- $token ) )
325
325
  elif [[ "$token" == -* ]]; then
326
- COMPREPLY=( $( compgen -W '-l --list' -- $token ) )
326
+ COMPREPLY=( $( compgen -W '-c -l --column --list' -- $token ) )
327
327
 
328
328
  fi
329
329
  }
@@ -91,7 +91,7 @@ complete -xc doing -n '__fish_doing_needs_command' -a 'tag' -d Add\ tag\(s\)\ to
91
91
  complete -xc doing -n '__fish_doing_needs_command' -a 'template' -d Output\ HTML
92
92
  complete -xc doing -n '__fish_doing_needs_command' -a 'test' -d Test\ Stuff
93
93
  complete -xc doing -n '__fish_doing_needs_command' -a 'today' -d List\ entries\ from\ today
94
- complete -xc doing -n '__fish_doing_needs_command' -a 'undo' -d Undo\ the\ last\ change\ to\ the\ doing_file
94
+ complete -xc doing -n '__fish_doing_needs_command' -a 'undo' -d Undo\ the\ last\ change\ to\ the\ Doing\ file
95
95
  complete -xc doing -n '__fish_doing_needs_command' -a 'view' -d Display\ a\ user-created\ view
96
96
  complete -xc doing -n '__fish_doing_needs_command' -a 'views' -d List\ available\ custom\ views
97
97
  complete -xc doing -n '__fish_doing_needs_command' -a 'wiki' -d Output\ a\ tag\ wiki
data/lib/doing/array.rb CHANGED
@@ -5,17 +5,53 @@ module Doing
5
5
  ## Array helpers
6
6
  ##
7
7
  class ::Array
8
+ # Convert strings to @tags
9
+ #
10
+ # @example `['one', '@two', 'three'].to_tags`
11
+ # @example `=> ['@one', '@two', '@three']`
12
+ # @return [Array] Array of @tags
13
+ #
8
14
  def to_tags
9
15
  map { |t| t.sub(/^@?/, '@') }
10
16
  end
11
17
 
18
+ def to_tags!
19
+ replace to_tags
20
+ end
21
+
22
+ ##
23
+ ## Hightlight @tags in string for console output
24
+ ##
25
+ ## @param color [String] the color to highlight
26
+ ## with
27
+ ##
28
+ ## @return [String] string with @tags highlighted
29
+ ##
12
30
  def highlight_tags(color = 'cyan')
13
31
  tag_color = Doing::Color.send(color)
14
32
  to_tags.map { |t| "#{tag_color}#{t}" }
15
33
  end
16
34
 
35
+ ##
36
+ ## Tag array for logging
37
+ ##
38
+ ## @return [String] Highlighted tag array joined with comma
39
+ ##
17
40
  def log_tags
18
41
  highlight_tags.join(', ')
19
42
  end
43
+
44
+ ##
45
+ ## Convert array to nested hash, setting last key to value
46
+ ##
47
+ ## @param value The value to set
48
+ ##
49
+ def nested_hash(value)
50
+ raise StandardError, 'Value can not be nil' if value.nil?
51
+
52
+ hsh = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }
53
+ hsh.dig(*self[0..-2])[self.fetch(-1)] = value
54
+ hsh
55
+ end
20
56
  end
21
57
  end
data/lib/doing/colors.rb CHANGED
@@ -1,64 +1,65 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Cribbed from <https://github.com/flori/term-ansicolor>
2
4
  module Doing
5
+ # Terminal color functions
3
6
  module Color
4
-
5
7
  # :stopdoc:
6
8
  ATTRIBUTES = [
7
- [ :clear , 0 ], # String#clear is already used to empty string in Ruby 1.9
8
- [ :reset , 0 ], # synonym for :clear
9
- [ :bold , 1 ],
10
- [ :dark , 2 ],
11
- [ :italic , 3 ], # not widely implemented
12
- [ :underline , 4 ],
13
- [ :underscore , 4 ], # synonym for :underline
14
- [ :blink , 5 ],
15
- [ :rapid_blink , 6 ], # not widely implemented
16
- [ :negative , 7 ], # no reverse because of String#reverse
17
- [ :concealed , 8 ],
18
- [ :strikethrough , 9 ], # not widely implemented
19
- [ :black , 30 ],
20
- [ :red , 31 ],
21
- [ :green , 32 ],
22
- [ :yellow , 33 ],
23
- [ :blue , 34 ],
24
- [ :magenta , 35 ],
25
- [ :cyan , 36 ],
26
- [ :white , 37 ],
27
- [ :bgblack , 40 ],
28
- [ :bgred , 41 ],
29
- [ :bggreen , 42 ],
30
- [ :bgyellow , 43 ],
31
- [ :bgblue , 44 ],
32
- [ :bgmagenta , 45 ],
33
- [ :bgcyan , 46 ],
34
- [ :bgwhite , 47 ],
35
- [ :boldblack , 90 ], # High intensity, aixterm (works in OS X)
36
- [ :boldred , 91 ],
37
- [ :boldgreen , 92 ],
38
- [ :boldyellow , 93 ],
39
- [ :boldblue , 94 ],
40
- [ :boldmagenta , 95 ],
41
- [ :boldcyan , 96 ],
42
- [ :boldwhite , 97 ],
43
- [ :boldbgblack , 100 ], # High intensity background, aixterm (works in OS X)
44
- [ :boldbgred , 101 ],
45
- [ :boldbggreen , 102 ],
46
- [ :boldbgyellow , 103 ],
47
- [ :boldbgblue , 104 ],
48
- [ :boldbgmagenta , 105 ],
49
- [ :boldbgcyan , 106 ],
50
- [ :boldbgwhite , 107 ],
51
- [ :softpurple , '0;35;40'],
52
- [ :hotpants , '7;34;40'],
53
- [ :knightrider , '7;30;40'],
54
- [ :flamingo , '7;31;47'],
55
- [ :yeller , '1;37;43'],
56
- [ :whiteboard , '1;30;47'],
57
- [ :default , '0;39' ]
58
- ]
9
+ [:clear, 0], # String#clear is already used to empty string in Ruby 1.9
10
+ [:reset, 0], # synonym for :clear
11
+ [:bold, 1],
12
+ [:dark, 2],
13
+ [:italic, 3], # not widely implemented
14
+ [:underline, 4],
15
+ [:underscore, 4], # synonym for :underline
16
+ [:blink, 5],
17
+ [:rapid_blink, 6], # not widely implemented
18
+ [:negative, 7], # no reverse because of String#reverse
19
+ [:concealed, 8],
20
+ [:strikethrough, 9], # not widely implemented
21
+ [:black, 30],
22
+ [:red, 31],
23
+ [:green, 32],
24
+ [:yellow, 33],
25
+ [:blue, 34],
26
+ [:magenta, 35],
27
+ [:cyan, 36],
28
+ [:white, 37],
29
+ [:bgblack, 40],
30
+ [:bgred, 41],
31
+ [:bggreen, 42],
32
+ [:bgyellow, 43],
33
+ [:bgblue, 44],
34
+ [:bgmagenta, 45],
35
+ [:bgcyan, 46],
36
+ [:bgwhite, 47],
37
+ [:boldblack, 90], # High intensity, aixterm (works in OS X)
38
+ [:boldred, 91],
39
+ [:boldgreen, 92],
40
+ [:boldyellow, 93],
41
+ [:boldblue, 94],
42
+ [:boldmagenta, 95],
43
+ [:boldcyan, 96],
44
+ [:boldwhite, 97],
45
+ [:boldbgblack, 100], # High intensity background, aixterm (works in OS X)
46
+ [:boldbgred, 101],
47
+ [:boldbggreen, 102],
48
+ [:boldbgyellow, 103],
49
+ [:boldbgblue, 104],
50
+ [:boldbgmagenta, 105],
51
+ [:boldbgcyan, 106],
52
+ [:boldbgwhite, 107],
53
+ [:softpurple, '0;35;40'],
54
+ [:hotpants, '7;34;40'],
55
+ [:knightrider, '7;30;40'],
56
+ [:flamingo, '7;31;47'],
57
+ [:yeller, '1;37;43'],
58
+ [:whiteboard, '1;30;47'],
59
+ [:default, '0;39']
60
+ ].map(&:freeze).freeze
59
61
 
60
62
  ATTRIBUTE_NAMES = ATTRIBUTES.transpose.first
61
- # :startdoc:
62
63
 
63
64
  # Returns true if Doing::Color supports the +feature+.
64
65
  #
@@ -72,19 +73,23 @@ module Doing
72
73
  !String.instance_methods(false).map(&:to_sym).include?(:clear)
73
74
  end
74
75
  end
75
- # Returns true, if the coloring function of this module
76
- # is switched on, false otherwise.
77
- def self.coloring?
78
- @coloring
79
- end
80
76
 
81
- # Turns the coloring on or off globally, so you can easily do
82
- # this for example:
83
- # Doing::Color::coloring = STDOUT.isatty
84
- def self.coloring=(val)
85
- @coloring = val
77
+ class << self
78
+ # Returns true, if the coloring function of this module
79
+ # is switched on, false otherwise.
80
+ def coloring?
81
+ @coloring
82
+ end
83
+
84
+ # Turns the coloring on or off globally, so you can easily do
85
+ # this for example:
86
+ # Doing::Color::coloring = STDOUT.isatty
87
+ attr_writer :coloring
88
+
89
+ def coloring
90
+ @coloring ||= true
91
+ end
86
92
  end
87
- self.coloring = true
88
93
 
89
94
  ATTRIBUTES.each do |c, v|
90
95
  eval <<-EOT
@@ -133,4 +138,3 @@ module Doing
133
138
  extend self
134
139
  end
135
140
  end
136
-
@@ -12,6 +12,12 @@ module Doing
12
12
  # Completion script generator
13
13
  module Completion
14
14
  class << self
15
+ # Generate a completion script and output to file or
16
+ # stdout
17
+ #
18
+ # @param type [String] shell to generate for (zsh|bash|fish)
19
+ # @param file [String] Path to save to, or 'stdout'
20
+ #
15
21
  def generate_completion(type: 'zsh', file: 'stdout')
16
22
 
17
23
  generator = case type.to_s
@@ -99,6 +99,10 @@ module Doing
99
99
  @config_file ||= default_config_file
100
100
  end
101
101
 
102
+ def config_file=(file)
103
+ @config_file = file
104
+ end
105
+
102
106
  def config_dir
103
107
  @config_dir ||= File.join(Util.user_home, '.config', 'doing')
104
108
  # @config_dir ||= Util.user_home
@@ -116,20 +120,20 @@ module Doing
116
120
  File.join(config_dir, 'config.yml')
117
121
  end
118
122
 
119
- def config_file=(file)
120
- @config_file = file
121
- end
122
-
123
-
124
123
  def additional_configs
125
124
  @additional_configs ||= find_local_config
126
125
  end
127
126
 
127
+ ##
128
+ ## Present a menu if there are multiple configs found
129
+ ##
130
+ ## @return [String] file path
131
+ ##
128
132
  def choose_config
129
133
  if @additional_configs.count.positive?
130
134
  choices = [@config_file]
131
135
  choices.concat(@additional_configs)
132
- res = Doing::WWID.new.choose_from(choices.uniq.sort.reverse, sorted: false, prompt: 'Local configs found, select which to update > ')
136
+ res = Doing::Prompt.choose_from(choices.uniq.sort.reverse, sorted: false, prompt: 'Local configs found, select which to update > ')
133
137
 
134
138
  raise UserCancelled, 'Cancelled' unless res
135
139
 
@@ -139,6 +143,16 @@ module Doing
139
143
  end
140
144
  end
141
145
 
146
+ ##
147
+ ## Resolve a fuzzy-matched key path
148
+ ##
149
+ ## @param keypath [String] A dot-separated key
150
+ ## path, e.g.
151
+ ## "plugins.plugin_path". Will also
152
+ ## work with "plug.path" (fuzzy
153
+ ## matched, first match wins)
154
+ ## @return [Array] ordered array of resolved keys
155
+ ##
142
156
  def resolve_key_path(keypath)
143
157
  cfg = @settings
144
158
  real_path = []
@@ -166,12 +180,22 @@ module Doing
166
180
  real_path
167
181
  end
168
182
 
183
+ ##
184
+ ## Get the value for a fuzzy-matched key path
185
+ ##
186
+ ## @param keypath [String] A dot-separated key
187
+ ## path, e.g.
188
+ ## "plugins.plugin_path". Will also
189
+ ## work with "plug.path" (fuzzy
190
+ ## matched, first match wins)
191
+ ## @return [Hash] Config value
192
+ ##
169
193
  def value_for_key(keypath = '')
170
194
  cfg = @settings
171
195
  real_path = ['config']
172
196
  unless keypath =~ /^[.*]?$/
173
197
  real_path = resolve_key_path(keypath)
174
- return nil unless real_path && real_path.count.positive?
198
+ return nil unless real_path&.count&.positive?
175
199
 
176
200
  cfg = cfg.dig(*real_path)
177
201
  end
@@ -188,6 +212,9 @@ module Doing
188
212
  Util.deep_merge_hashes(DEFAULTS, Configuration[user_config].stringify_keys)
189
213
  end
190
214
 
215
+ ##
216
+ ## Method for transitioning from ~/.doingrc to ~/.config/doing/config.yml
217
+ ##
191
218
  def update_deprecated_config
192
219
  # return # Until further notice
193
220
  return if File.exist?(default_config_file)
@@ -199,22 +226,23 @@ module Doing
199
226
  Doing.logger.log_now(:warn, 'Deprecated:', "main config file location has changed to #{config_file}")
200
227
  res = wwid.yn("Move #{old_file} to new location, preserving settings?", default_response: true)
201
228
 
202
- if res
203
- if File.exist?(default_config_file)
204
- res = wwid.yn("#{default_config_file} already exists, overwrite it?", default_response: false)
229
+ return unless res
205
230
 
206
- unless res
207
- @config_file = old_file
208
- return
209
- end
210
- end
231
+ if File.exist?(default_config_file)
232
+ res = wwid.yn("#{default_config_file} already exists, overwrite it?", default_response: false)
211
233
 
212
- FileUtils.mv old_file, default_config_file, force: true
213
- Doing.logger.log_now(:warn, 'Config:', "Config file moved to #{default_config_file}")
214
- Doing.logger.log_now(:warn, 'Config:', %(If ~/.config/doing/config.yml exists in the future, it will be considered a local
215
- config and its values will override the default configuration.))
216
- Process.exit 0
234
+ unless res
235
+ @config_file = old_file
236
+ return
237
+ end
217
238
  end
239
+
240
+ FileUtils.mv old_file, default_config_file, force: true
241
+ Doing.logger.log_now(:warn, 'Config:', "Config file moved to #{default_config_file}")
242
+ Doing.logger.log_now(:warn, 'Config:', %(If ~/.doingrc exists in the future,
243
+ it will be considered a local config and its values will override the
244
+ default configuration.))
245
+ Process.exit 0
218
246
  end
219
247
 
220
248
  ##
@@ -261,8 +289,23 @@ module Doing
261
289
  config
262
290
  end
263
291
 
292
+ # @private
293
+ def inspect
294
+ %(<Doing::Configuration #{@settings.hash}>)
295
+ end
296
+
297
+ # @private
298
+ def to_s
299
+ YAML.dump(@settings)
300
+ end
301
+
264
302
  private
265
303
 
304
+ ##
305
+ ## Test for deprecated config keys
306
+ ##
307
+ ## @param config The configuration
308
+ ##
266
309
  def find_deprecations(config)
267
310
  deprecated = false
268
311
  if config.key?('editor')
@@ -276,14 +319,16 @@ module Doing
276
319
  deprecated = true
277
320
  config['editors']['config'] = config['config_editor_app']
278
321
  config.delete('config_editor_app')
279
- Doing.logger.debug('Deprecated:', "config key 'config_editor_app' is now 'editors->config', please update your config.")
322
+ Doing.logger.debug('Deprecated:',
323
+ "config key 'config_editor_app' is now 'editors->config', please update your config.")
280
324
  end
281
325
 
282
326
  if config.key?('editor_app') && !config['editors']['doing_file']
283
327
  deprecated = true
284
328
  config['editors']['doing_file'] = config['editor_app']
285
329
  config.delete('editor_app')
286
- Doing.logger.debug('Deprecated:', "config key 'editor_app' is now 'editors->doing_file', please update your config.")
330
+ Doing.logger.debug('Deprecated:',
331
+ "config key 'editor_app' is now 'editors->doing_file', please update your config.")
287
332
  end
288
333
 
289
334
  Doing.logger.warn('Deprecated:', 'outdated keys found, please run `doing config --update`.') if deprecated
@@ -327,7 +372,7 @@ module Doing
327
372
  ##
328
373
  def read_config
329
374
  unless File.exist?(config_file)
330
- Doing.logger.info('Config:', 'Config file doesn\'t exist, using default configuration' )
375
+ Doing.logger.info('Config:', 'Config file doesn\'t exist, using default configuration')
331
376
  return {}.deep_merge(DEFAULTS)
332
377
  end
333
378
 
@@ -372,11 +417,7 @@ module Doing
372
417
  end
373
418
 
374
419
  def load_plugins(add_dir = nil)
375
- begin
376
- FileUtils.mkdir_p(add_dir) if add_dir && !File.exist?(add_dir)
377
- rescue
378
- nil
379
- end
420
+ FileUtils.mkdir_p(add_dir) if add_dir && !File.exist?(add_dir)
380
421
 
381
422
  Plugins.load_plugins(add_dir)
382
423
  end