doing 2.1.30 → 2.1.31pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/.irbrc +1 -0
  3. data/.yardoc/checksums +9 -8
  4. data/.yardoc/object_types +0 -0
  5. data/.yardoc/objects/root.dat +0 -0
  6. data/CHANGELOG.md +4923 -0
  7. data/Gemfile.lock +1 -1
  8. data/README.md +1 -1
  9. data/bin/commands/again.rb +1 -1
  10. data/bin/commands/archive.rb +3 -3
  11. data/bin/commands/cancel.rb +1 -1
  12. data/bin/commands/commands.rb +8 -8
  13. data/bin/commands/completion.rb +61 -19
  14. data/bin/commands/config.rb +9 -9
  15. data/bin/commands/done.rb +1 -1
  16. data/bin/commands/flag.rb +1 -1
  17. data/bin/commands/grep.rb +5 -5
  18. data/bin/commands/last.rb +1 -1
  19. data/bin/commands/meanwhile.rb +1 -1
  20. data/bin/commands/now.rb +1 -1
  21. data/bin/commands/on.rb +1 -1
  22. data/bin/commands/open.rb +1 -1
  23. data/bin/commands/recent.rb +4 -4
  24. data/bin/commands/show.rb +8 -8
  25. data/bin/commands/since.rb +1 -1
  26. data/bin/commands/today.rb +1 -1
  27. data/bin/commands/view.rb +3 -3
  28. data/bin/commands/yesterday.rb +2 -2
  29. data/bin/doing +22 -133
  30. data/docs/doc/Array.html +1 -1
  31. data/docs/doc/BooleanTermParser/Clause.html +1 -1
  32. data/docs/doc/BooleanTermParser/Operator.html +1 -1
  33. data/docs/doc/BooleanTermParser/Query.html +1 -1
  34. data/docs/doc/BooleanTermParser/QueryParser.html +1 -1
  35. data/docs/doc/BooleanTermParser/QueryTransformer.html +1 -1
  36. data/docs/doc/BooleanTermParser.html +1 -1
  37. data/docs/doc/Doing/Color.html +1 -1
  38. data/docs/doc/Doing/Completion.html +324 -4
  39. data/docs/doc/Doing/Configuration.html +1 -1
  40. data/docs/doc/Doing/Errors/DoingNoTraceError.html +1 -1
  41. data/docs/doc/Doing/Errors/DoingRuntimeError.html +1 -1
  42. data/docs/doc/Doing/Errors/DoingStandardError.html +1 -1
  43. data/docs/doc/Doing/Errors/EmptyInput.html +1 -1
  44. data/docs/doc/Doing/Errors/NoResults.html +1 -1
  45. data/docs/doc/Doing/Errors/PluginException.html +1 -1
  46. data/docs/doc/Doing/Errors/UserCancelled.html +1 -1
  47. data/docs/doc/Doing/Errors/WrongCommand.html +1 -1
  48. data/docs/doc/Doing/Errors.html +1 -1
  49. data/docs/doc/Doing/Hooks.html +1 -1
  50. data/docs/doc/Doing/Item.html +125 -1
  51. data/docs/doc/Doing/Items.html +1 -1
  52. data/docs/doc/Doing/LogAdapter.html +1 -1
  53. data/docs/doc/Doing/Note.html +109 -3
  54. data/docs/doc/Doing/Pager.html +1 -1
  55. data/docs/doc/Doing/Plugins.html +1 -1
  56. data/docs/doc/Doing/Prompt.html +1 -1
  57. data/docs/doc/Doing/Section.html +1 -1
  58. data/docs/doc/Doing/TemplateString.html +1 -1
  59. data/docs/doc/Doing/Types.html +1 -1
  60. data/docs/doc/Doing/Util/Backup.html +1 -1
  61. data/docs/doc/Doing/Util.html +1 -1
  62. data/docs/doc/Doing/WWID.html +6 -6
  63. data/docs/doc/Doing.html +2 -2
  64. data/docs/doc/FalseClass.html +1 -1
  65. data/docs/doc/GLI/Commands/Help.html +1 -1
  66. data/docs/doc/GLI/Commands/MarkdownDocumentListener.html +1 -1
  67. data/docs/doc/GLI/Commands.html +1 -1
  68. data/docs/doc/GLI.html +1 -1
  69. data/docs/doc/Hash.html +1 -1
  70. data/docs/doc/Object.html +1 -1
  71. data/docs/doc/PhraseParser/Operator.html +1 -1
  72. data/docs/doc/PhraseParser/PhraseClause.html +1 -1
  73. data/docs/doc/PhraseParser/Query.html +1 -1
  74. data/docs/doc/PhraseParser/QueryParser.html +1 -1
  75. data/docs/doc/PhraseParser/QueryTransformer.html +1 -1
  76. data/docs/doc/PhraseParser/TermClause.html +1 -1
  77. data/docs/doc/PhraseParser.html +1 -1
  78. data/docs/doc/Status.html +1 -1
  79. data/docs/doc/String.html +1 -1
  80. data/docs/doc/Symbol.html +1 -1
  81. data/docs/doc/Time.html +1 -1
  82. data/docs/doc/TrueClass.html +1 -1
  83. data/docs/doc/_index.html +3 -1
  84. data/docs/doc/file.README.html +2 -2
  85. data/docs/doc/index.html +2 -2
  86. data/docs/doc/method_list.html +337 -241
  87. data/docs/doc/top-level-namespace.html +105 -1
  88. data/doing.rdoc +25 -9
  89. data/example_plugin.rb +7 -5
  90. data/lib/completion/_doing.zsh +2 -2
  91. data/lib/completion/doing.bash +2 -2
  92. data/lib/completion/doing.fish +2 -3
  93. data/lib/doing/add_options.rb +117 -0
  94. data/lib/doing/array/array.rb +16 -0
  95. data/lib/doing/completion/bash_completion.rb +12 -51
  96. data/lib/doing/completion/fish_completion.rb +16 -52
  97. data/lib/doing/completion/zsh_completion.rb +12 -56
  98. data/lib/doing/completion.rb +203 -17
  99. data/lib/doing/item.rb +21 -3
  100. data/lib/doing/items.rb +5 -5
  101. data/lib/doing/note.rb +24 -8
  102. data/lib/doing/plugins/export/dayone_export.rb +8 -6
  103. data/lib/doing/plugins/export/html_export.rb +4 -4
  104. data/lib/doing/plugins/export/json_export.rb +19 -20
  105. data/lib/doing/plugins/export/markdown_export.rb +2 -2
  106. data/lib/doing/plugins/export/template_export.rb +4 -4
  107. data/lib/doing/plugins/import/calendar_import.rb +1 -1
  108. data/lib/doing/plugins/import/doing_import.rb +1 -1
  109. data/lib/doing/plugins/import/timing_import.rb +1 -1
  110. data/lib/doing/string/highlight.rb +3 -4
  111. data/lib/doing/string/string.rb +8 -0
  112. data/lib/doing/util.rb +1 -1
  113. data/lib/doing/util_backup.rb +12 -12
  114. data/lib/doing/version.rb +1 -1
  115. data/lib/doing/wwid.rb +76 -77
  116. data/lib/doing.rb +57 -0
  117. data/lib/examples/commands/wiki.rb +27 -19
  118. data/scripts/setting_replace.rb +11 -0
  119. metadata +6 -4
@@ -97,12 +97,116 @@
97
97
 
98
98
 
99
99
 
100
+
101
+ <h2>
102
+ Instance Method Summary
103
+ <small><a href="#" class="summary_toggle">collapse</a></small>
104
+ </h2>
105
+
106
+ <ul class="summary">
107
+
108
+ <li class="public ">
109
+ <span class="summary_signature">
110
+
111
+ <a href="top-level-namespace.html#add_options-instance_method" title="#add_options (instance method)">#<strong>add_options</strong>(type, cmd) &#x21d2; Object </a>
112
+
113
+
114
+
115
+ </span>
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+
124
+
125
+ <span class="summary_desc"><div class='inline'><p>Add presets of flags and switches to a command.</p>
126
+ </div></span>
127
+
128
+ </li>
100
129
 
130
+
131
+ </ul>
132
+
133
+
134
+
135
+
136
+ <div id="instance_method_details" class="method_details_list">
137
+ <h2>Instance Method Details</h2>
138
+
139
+
140
+ <div class="method_details first">
141
+ <h3 class="signature first" id="add_options-instance_method">
142
+
143
+ #<strong>add_options</strong>(type, cmd) &#x21d2; <tt><span class='object_link'><a href="Object.html" title="Object (class)">Object</a></span></tt>
144
+
145
+
146
+
147
+
148
+
149
+ </h3><div class="docstring">
150
+ <div class="discussion">
151
+ <p>Add presets of flags and switches to a command.</p>
152
+
153
+ <p>:add_entry =&gt; --noauto, --note, --ask, --editor, --back</p>
154
+
155
+ <p>:search =&gt; --search, --case, --exact</p>
156
+
157
+ <p>:tag_filter =&gt; --tag, --bool, --not, --val</p>
158
+
159
+ <p>:date_filter =&gt; --before, --after, --from</p>
160
+
161
+
162
+ </div>
163
+ </div>
164
+ <div class="tags">
165
+ <p class="tag_title">Parameters:</p>
166
+ <ul class="param">
167
+
168
+ <li>
169
+
170
+ <span class='name'>type</span>
171
+
172
+
173
+ <span class='type'>(<tt><span class='object_link'><a href="Symbol.html" title="Symbol (class)">Symbol</a></span></tt>)</span>
174
+
175
+
176
+
177
+ &mdash;
178
+ <div class='inline'><p>The type</p>
179
+ </div>
180
+
181
+ </li>
182
+
183
+ <li>
184
+
185
+ <span class='name'>cmd</span>
186
+
187
+
188
+ <span class='type'></span>
189
+
190
+
191
+
192
+ &mdash;
193
+ <div class='inline'><p>The GLI command to which the options will be added</p>
194
+ </div>
195
+
196
+ </li>
197
+
198
+ </ul>
199
+
200
+
201
+ </div>
202
+ </div>
203
+
204
+ </div>
101
205
 
102
206
  </div>
103
207
 
104
208
  <div id="footer">
105
- Generated on Wed Feb 16 07:23:35 2022 by
209
+ Generated on Thu Feb 17 13:05:18 2022 by
106
210
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
107
211
  0.9.27 (ruby-3.0.1).
108
212
  </div>
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.1.30
8
+ v2.1.31pre
9
9
 
10
10
  === Global Options
11
11
  === --config_file arg
@@ -506,26 +506,42 @@ Disable Doing commands
506
506
 
507
507
  [Default Command] add
508
508
  ==== Command: <tt>completion </tt>
509
- Generate shell completion scripts
509
+ Generate shell completion scripts for doing
510
510
 
511
511
  Generates the necessary scripts to add command line completion to various shells,
512
512
  so typing 'doing' and hitting tab will offer completions of subcommands and their options.
513
513
  ===== Options
514
- ===== -f|--file PATH
514
+ ===== -t|--type arg
515
515
 
516
- File to write output to
516
+ Deprecated, specify shell as argument to subcommand
517
517
 
518
- [Default Value] STDOUT
518
+ [Default Value] None
519
+ [Must Match] (?i-mx:^(?:[bzf](?:[ai]?sh)?|all)$)
519
520
 
520
521
 
521
- ===== -t|--type SHELL
522
+ ===== Commands
523
+ ====== Command: <tt>generate [zsh|bash|fish|all]</tt>
524
+ Generate completion scripts, including custom plugins and command options
525
+
526
+ Argument specifies which shell to install for: zsh, bash, fish, all
527
+ ======= Options
528
+ ======= -f|--file PATH
529
+
530
+ Alternative file to write output to
531
+
532
+ [Default Value] None
533
+ Argument specifies which shell to install for: zsh, bash, fish, all
534
+
535
+ ======= --stdout
536
+ Output result to STDOUT only
522
537
 
523
- Shell to generate for (bash, zsh, fish)
524
538
 
525
- [Default Value] zsh
526
- [Must Match] (?i-mx:^(?:[bzf](?:[ai]?sh)?|all)$)
527
539
 
540
+ ====== Command: <tt>install [zsh|bash|fish]</tt>
541
+ Install default completion scripts
528
542
 
543
+ Argument specifies which shell to install for: zsh, bash, fish, or all
544
+ [Default Command] generate
529
545
  ==== Command: <tt>config </tt>
530
546
  Edit the configuration file or output a value from it
531
547
 
data/example_plugin.rb CHANGED
@@ -54,7 +54,7 @@ module Doing
54
54
  ## automatically be added for the user to override
55
55
  ## The config key will be available at:
56
56
  ##
57
- ## wwid.config['export_templates'][PLUGIN_NAME]
57
+ ## Doing.config.settings['export_templates'][PLUGIN_NAME]
58
58
  ##
59
59
  ## config: (optional) A Hash which will be
60
60
  ## added to the main configuration in the plugins section.
@@ -65,7 +65,7 @@ module Doing
65
65
  ##
66
66
  ## The configuration keys will be available at:
67
67
  ##
68
- ## wwid.config['plugins'][PLUGIN_NAME][KEY]
68
+ ## Doing.config.settings['plugins'][PLUGIN_NAME][KEY]
69
69
  ##
70
70
  ## Method to return plugin settings (required)
71
71
  ##
@@ -125,6 +125,8 @@ module Doing
125
125
  def self.render(wwid, items, variables: {})
126
126
  return unless items.good?
127
127
 
128
+ config = Doing.config.settings
129
+
128
130
  # the :options key includes the flags passed to the
129
131
  # command that called the plugin use `puts
130
132
  # variables.inspect` to see properties and methods
@@ -162,8 +164,8 @@ module Doing
162
164
  title = i.title.gsub(/@/, 'hashtag ')
163
165
  tpl = template('say')
164
166
 
165
- if wwid.config['export_templates'].key?('say')
166
- cfg_tpl = wwid.config['export_templates']['say']
167
+ if config['export_templates'].key?('say')
168
+ cfg_tpl = config['export_templates']['say']
167
169
  tpl = cfg_tpl if cfg_tpl.good?
168
170
  end
169
171
  output = tpl.dup
@@ -188,7 +190,7 @@ module Doing
188
190
  Doing.logger.info('Spoke the last entry. Did you hear it?')
189
191
 
190
192
  # This export runs a command for fun, most plugins won't
191
- voice = wwid.config['plugins']['say']['say_voice'] || 'Alex'
193
+ voice = config['plugins']['say']['say_voice'] || 'Alex'
192
194
  `say -v "#{voice}" "#{output}"`
193
195
 
194
196
  # Return the result (don't output to terminal with puts or print)
@@ -18,7 +18,7 @@ function _doing() {
18
18
  'changelog:List recent changes in Doing'
19
19
  'colors:List available color variables for configuration templates and views'
20
20
  'commands:Enable and disable Doing commands'
21
- 'completion:Generate shell completion scripts'
21
+ 'completion:Generate shell completion scripts for doing'
22
22
  'config:Edit the configuration file or output a value from it'
23
23
  'done:Add a completed item with @done(date)'
24
24
  'did:Add a completed item with @done(date)'
@@ -100,7 +100,7 @@ function _doing() {
100
100
  args=( )
101
101
  ;;
102
102
  completion)
103
- args=( {-f,--file=}"[File to write output to]" {-t,--type=}"[Shell to generate for]" )
103
+ args=( {-t,--type=}"[Deprecated]" )
104
104
  ;;
105
105
  config)
106
106
  args=( {-d,--dump}"[DEPRECATED]" {-u,--update}"[DEPRECATED]" )
@@ -71,9 +71,9 @@ _doing_changes() {
71
71
  _doing_completion() {
72
72
 
73
73
  if [[ "$token" == --* ]]; then
74
- COMPREPLY=( $( compgen -W '--file --type' -- $token ) )
74
+ COMPREPLY=( $( compgen -W '--type' -- $token ) )
75
75
  elif [[ "$token" == -* ]]; then
76
- COMPREPLY=( $( compgen -W '-f -t --file --type' -- $token ) )
76
+ COMPREPLY=( $( compgen -W '-t --type' -- $token ) )
77
77
 
78
78
  fi
79
79
  }
@@ -143,7 +143,7 @@ complete -xc doing -n '__fish_doing_needs_command' -a 'cancel' -d End\ last\ X\
143
143
  complete -xc doing -n '__fish_doing_needs_command' -a 'changes changelog' -d List\ recent\ changes\ in\ Doing
144
144
  complete -xc doing -n '__fish_doing_needs_command' -a 'colors' -d List\ available\ color\ variables\ for\ configuration\ templates\ and\ views
145
145
  complete -xc doing -n '__fish_doing_needs_command' -a 'commands' -d Enable\ and\ disable\ Doing\ commands
146
- complete -xc doing -n '__fish_doing_needs_command' -a 'completion' -d Generate\ shell\ completion\ scripts
146
+ complete -xc doing -n '__fish_doing_needs_command' -a 'completion' -d Generate\ shell\ completion\ scripts\ for\ doing
147
147
  complete -xc doing -n '__fish_doing_needs_command' -a 'config' -d Edit\ the\ configuration\ file\ or\ output\ a\ value\ from\ it
148
148
  complete -xc doing -n '__fish_doing_needs_command' -a 'done did' -d Add\ a\ completed\ item\ with\ @done\(date\)
149
149
  complete -xc doing -n '__fish_doing_needs_command' -a 'finish' -d Mark\ last\ X\ entries\ as\ @done
@@ -232,8 +232,7 @@ complete -c doing -l markdown -f -n '__fish_doing_using_command changes change
232
232
  complete -c doing -l render -f -n '__fish_doing_using_command changes changelog' -d Force\ rendered\ output
233
233
  complete -c doing -l search -s s -f -r -n '__fish_doing_using_command changes changelog' -d Show\ changelogs\ matching\ search\ terms
234
234
  complete -c doing -l sort -f -r -n '__fish_doing_using_command changes changelog' -d Sort\ order
235
- complete -c doing -l file -s f -f -r -n '__fish_doing_using_command completion' -d File\ to\ write\ output\ to
236
- complete -c doing -l type -s t -f -r -n '__fish_doing_using_command completion' -d Shell\ to\ generate\ for
235
+ complete -c doing -l type -s t -f -r -n '__fish_doing_using_command completion' -d Deprecated
237
236
  complete -c doing -l dump -s d -f -n '__fish_doing_using_command config' -d DEPRECATED
238
237
  complete -c doing -l update -s u -f -n '__fish_doing_using_command config' -d DEPRECATED
239
238
  complete -c doing -l noauto -s X -f -n '__fish_doing_using_command done did' -d Exclude\ auto\ tags\ and\ default\ tags
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ ## Add presets of flags and switches to a command.
5
+ ##
6
+ ## :add_entry => --noauto, --note, --ask, --editor, --back
7
+ ##
8
+ ## :search => --search, --case, --exact
9
+ ##
10
+ ## :tag_filter => --tag, --bool, --not, --val
11
+ ##
12
+ ## :date_filter => --before, --after, --from
13
+ ##
14
+ ## @param type [Symbol] The type
15
+ ## @param cmd The GLI command to which the options will be added
16
+ ##
17
+ def add_options(type, cmd)
18
+ cmd_name = cmd.name.to_s
19
+ action = case cmd_name
20
+ when /again/
21
+ 'Repeat'
22
+ when /grep/
23
+ 'Search'
24
+ when /mark/
25
+ 'Flag'
26
+ when /(last|tags|view)/
27
+ 'Show'
28
+ else
29
+ cmd_name.capitalize
30
+ end
31
+
32
+ case type
33
+ when :add_entry
34
+ cmd.desc 'Exclude auto tags and default tags'
35
+ cmd.switch %i[X noauto], default_value: false, negatable: false
36
+
37
+ cmd.desc 'Include a note'
38
+ cmd.arg_name 'TEXT'
39
+ cmd.flag %i[n note]
40
+
41
+ cmd.desc 'Prompt for note via multi-line input'
42
+ cmd.switch %i[ask], negatable: false, default_value: false
43
+
44
+ cmd.desc "Edit entry with #{Doing::Util.default_editor}"
45
+ cmd.switch %i[e editor], negatable: false, default_value: false
46
+
47
+ cmd.desc 'Backdate start date for new entry to date string [4pm|20m|2h|yesterday noon]'
48
+ cmd.arg_name 'DATE_STRING'
49
+ cmd.flag %i[b back started], type: DateBeginString
50
+ when :search
51
+ cmd.desc 'Filter entries using a search query, surround with slashes for regex (e.g. "/query.*/"),
52
+ start with single quote for exact match ("\'query")'
53
+ cmd.arg_name 'QUERY'
54
+ cmd.flag [:search]
55
+
56
+ cmd.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
57
+ cmd.arg_name 'TYPE'
58
+ cmd.flag [:case], must_match: REGEX_CASE,
59
+ default_value: Doing.settings.dig('search', 'case').normalize_case,
60
+ type: CaseSymbol
61
+
62
+ cmd.desc 'Force exact search string matching (case sensitive)'
63
+ cmd.switch %i[x exact], default_value: Doing.config.exact_match?, negatable: Doing.config.exact_match?
64
+ when :tag_filter
65
+ cmd.desc 'Filter entries by tag. Combine multiple tags with a comma. Wildcards allowed (*, ?)'
66
+ cmd.arg_name 'TAG'
67
+ cmd.flag [:tag], type: TagArray
68
+
69
+ cmd.desc 'Perform a tag value query ("@done > two hours ago" or "@progress < 50").
70
+ May be used multiple times, combined with --bool'
71
+ cmd.arg_name 'QUERY'
72
+ cmd.flag [:val], multiple: true, must_match: REGEX_VALUE_QUERY
73
+
74
+ cmd.desc "#{action} items that *don't* match search/tag filters"
75
+ cmd.switch [:not], default_value: false, negatable: false
76
+
77
+ cmd.desc 'Boolean used to combine multiple tags. Use PATTERN to parse + and - as booleans'
78
+ cmd.arg_name 'BOOLEAN'
79
+ cmd.flag [:bool], must_match: REGEX_BOOL,
80
+ default_value: :pattern,
81
+ type: BooleanSymbol
82
+ when :date_filter
83
+ if action =~ /Archive/
84
+ cmd.desc 'Archive entries older than date (natural language).'
85
+ else
86
+ cmd.desc "#{action} entries older than date (natural language). If this is only a time (8am, 1:30pm, 15:00), all
87
+ dates will be included, but entries will be filtered by time of day"
88
+ end
89
+ cmd.arg_name 'DATE_STRING'
90
+ cmd.flag [:before], type: DateBeginString
91
+
92
+ if action =~ /Archive/
93
+ cmd.desc 'Archive entries newer than date (natural language).'
94
+ else
95
+ cmd.desc "#{action} entries newer than date (natural language). If this is only a time (8am, 1:30pm, 15:00), all
96
+ dates will be included, but entries will be filtered by time of day"
97
+ end
98
+ cmd.arg_name 'DATE_STRING'
99
+ cmd.flag [:after], type: DateEndString
100
+
101
+ if action =~ /Archive/
102
+ cmd.desc %(
103
+ Date range (natural language) to archive: `doing archive --from "1/1/21 to 12/31/21"`.
104
+ )
105
+ else
106
+ cmd.desc %(
107
+ Date range (natural language) to #{action.downcase}, or a single day to filter on.
108
+ To specify a range, use "to": `doing #{cmd_name} --from "monday 8am to friday 5pm"`.
109
+
110
+ If values are only time(s) (6am to noon) all dates will be included, but entries will be filtered
111
+ by time of day.
112
+ )
113
+ end
114
+ cmd.arg_name 'DATE_OR_RANGE'
115
+ cmd.flag [:from], type: DateRangeString
116
+ end
117
+ end
@@ -2,3 +2,19 @@
2
2
 
3
3
  require_relative 'tags'
4
4
  require_relative 'nested_hash'
5
+
6
+ class ::Array
7
+ ##
8
+ ## Force UTF-8 encoding of strings in array
9
+ ##
10
+ ## @return [Array] Encoded lines
11
+ ##
12
+ def utf8
13
+ c = self.class
14
+ if String.method_defined? :force_encoding
15
+ replace c.new(map(&:utf8))
16
+ else
17
+ self
18
+ end
19
+ end
20
+ end
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Doing
2
4
  module Completion
5
+ # Generate completions for Bash
3
6
  class BashCompletions
4
7
  attr_accessor :commands, :global_options
5
8
 
@@ -11,7 +14,7 @@ module Doing
11
14
  @commands.each_with_index do |cmd, i|
12
15
  @bar.advance(status: cmd[:commands].first)
13
16
 
14
- data = get_help_sections(cmd[:commands].first)
17
+ data = Completion.get_help_sections(cmd[:commands].first)
15
18
 
16
19
  arg = data[:synopsis].join(' ').strip.split(/ /).last
17
20
  case arg
@@ -26,7 +29,7 @@ module Doing
26
29
  end
27
30
 
28
31
  if data[:command_options]
29
- options = parse_options(data[:command_options])
32
+ options = Completion.parse_options(data[:command_options])
30
33
  out << command_function(cmd[:commands].first, options, type)
31
34
 
32
35
  if first
@@ -119,56 +122,13 @@ module Doing
119
122
  [func, logic]
120
123
  end
121
124
 
122
-
123
-
124
- def get_help_sections(command = '')
125
- res = `doing help #{command}`.strip
126
- scanned = res.scan(/(?m-i)^([A-Z ]+)\n([\s\S]*?)(?=\n+[A-Z]+|\Z)/)
127
- sections = {}
128
- scanned.each do |sect|
129
- title = sect[0].downcase.strip.gsub(/ +/, '_').to_sym
130
- content = sect[1].split(/\n/).map(&:strip).delete_if(&:empty?)
131
- sections[title] = content
132
- end
133
- sections
134
- end
135
-
136
- def parse_option(option)
137
- res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>\w+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
138
- return nil unless res
139
- {
140
- short: res['short'],
141
- long: res['long'],
142
- arg: res[:arg],
143
- description: res['desc'].short_desc
144
- }
145
- end
146
-
147
- def parse_options(options)
148
- options.map { |opt| parse_option(opt) }
149
- end
150
-
151
- def parse_command(command)
152
- res = command.match(/^(?<cmd>[^, \t]+)(?<alias>(?:, [^, \t]+)*)?\s+- (?<desc>.*?)$/)
153
- commands = [res['cmd']]
154
- commands.concat(res['alias'].split(/, /).delete_if(&:empty?)) if res['alias']
155
-
156
- {
157
- commands: commands,
158
- description: res['desc'].short_desc
159
- }
160
- end
161
-
162
- def parse_commands(commands)
163
- commands.map { |cmd| parse_command(cmd) }
164
- end
165
-
166
125
  def initialize
167
- data = get_help_sections
168
- @global_options = parse_options(data[:global_options])
169
- @commands = parse_commands(data[:commands])
170
- @bar = TTY::ProgressBar.new("\033[0;0;33mGenerating Bash completions: \033[0;35;40m[:bar] :status\033[0m", total: @commands.count, bar_format: :blade, status: 'Reading subcommands')
171
- @bar.resize(25)
126
+ data = Completion.get_help_sections
127
+ @global_options = Completion.parse_options(data[:global_options])
128
+ @commands = Completion.parse_commands(data[:commands])
129
+ @bar = TTY::ProgressBar.new("\033[0;0;33mGenerating Bash completions: \033[0;35;40m[:bar] :status\033[0m", total: @commands.count + 1, bar_format: :box, hide_cursor: true, status: 'Reading subcommands')
130
+ width = TTY::Screen.columns - 45
131
+ @bar.resize(width)
172
132
  end
173
133
 
174
134
  def generate_completions
@@ -176,6 +136,7 @@ module Doing
176
136
  out = []
177
137
  out << main_function
178
138
  out << 'complete -F _doing doing'
139
+ @bar.advance(status: '✅')
179
140
  @bar.finish
180
141
  out.join("\n")
181
142
  end
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Doing
2
4
  module Completion
5
+ # Generate completions for Fish
3
6
  class FishCompletions
4
7
 
5
8
  attr_accessor :commands, :global_options
@@ -137,53 +140,12 @@ module Doing
137
140
  EOFUNCTIONS
138
141
  end
139
142
 
140
- def get_help_sections(command = '')
141
- res = `doing help #{command}`.strip
142
- scanned = res.scan(/(?m-i)^([A-Z ]+)\n([\s\S]*?)(?=\n+[A-Z]+|\Z)/)
143
- sections = {}
144
- scanned.each do |sect|
145
- title = sect[0].downcase.strip.gsub(/ +/, '_').to_sym
146
- content = sect[1].split(/\n/).map(&:strip).delete_if(&:empty?)
147
- sections[title] = content
148
- end
149
- sections
150
- end
151
-
152
- def parse_option(option)
153
- res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>\w+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
154
- return nil unless res
155
-
156
- {
157
- short: res['short'],
158
- long: res['long'],
159
- arg: res['arg'],
160
- description: res['desc'].short_desc
161
- }
162
- end
163
-
164
- def parse_options(options)
165
- options.map { |opt| parse_option(opt) }
166
- end
167
-
168
- def parse_command(command)
169
- res = command.match(/^(?<cmd>[^, \t]+)(?<alias>(?:, [^, \t]+)*)?\s+- (?<desc>.*?)$/)
170
- commands = [res['cmd']]
171
- commands.concat(res['alias'].split(/, /).delete_if(&:empty?)) if res['alias']
172
-
173
- {
174
- commands: commands,
175
- description: res['desc'].short_desc
176
- }
177
- end
178
-
179
- def parse_commands(commands)
180
- commands.map { |cmd| parse_command(cmd) }
181
- end
182
-
183
143
  def generate_subcommand_completions
184
144
  out = []
185
- @commands.each_with_index do |cmd, i|
186
- out << "complete -xc doing -n '__fish_doing_needs_command' -a '#{cmd[:commands].join(' ')}' -d #{Shellwords.escape(cmd[:description])}"
145
+ @commands.each do |cmd|
146
+ desc = Shellwords.escape(cmd[:description])
147
+ cmds = cmd[:commands].join(' ')
148
+ out << "complete -xc doing -n '__fish_doing_needs_command' -a '#{cmds}' -d #{desc}"
187
149
  end
188
150
 
189
151
  out.join("\n")
@@ -203,14 +165,14 @@ module Doing
203
165
 
204
166
  @commands.each_with_index do |cmd, i|
205
167
  @bar.advance(status: cmd[:commands].first)
206
- data = get_help_sections(cmd[:commands].first)
168
+ data = Completion.get_help_sections(cmd[:commands].first)
207
169
 
208
170
  if data[:synopsis].join(' ').strip.split(/ /).last =~ /(path|file)/i
209
171
  out << "complete -c doing -F -n '__fish_doing_using_command #{cmd[:commands].join(" ")}'"
210
172
  end
211
173
 
212
174
  if data[:command_options]
213
- parse_options(data[:command_options]).each do |option|
175
+ Completion.parse_options(data[:command_options]).each do |option|
214
176
  next if option.nil?
215
177
 
216
178
  arg = option[:arg] ? '-r' : ''
@@ -267,11 +229,12 @@ module Doing
267
229
  end
268
230
 
269
231
  def initialize
270
- data = get_help_sections
271
- @global_options = parse_options(data[:global_options])
272
- @commands = parse_commands(data[:commands])
273
- @bar = TTY::ProgressBar.new("\033[0;0;33mGenerating Fish completions: \033[0;35;40m[:bar] :status\033[0m", total: @commands.count, bar_format: :blade, status: 'processing subcommands')
274
- @bar.resize(25)
232
+ data = Completion.get_help_sections
233
+ @global_options = Completion.parse_options(data[:global_options])
234
+ @commands = Completion.parse_commands(data[:commands])
235
+ @bar = TTY::ProgressBar.new("\033[0;0;33mGenerating Fish completions: \033[0;35;40m[:bar] :status\033[0m", total: @commands.count + 1, bar_format: :block, hide_cursor: true, status: 'processing subcommands')
236
+ width = TTY::Screen.columns - 45
237
+ @bar.resize(width)
275
238
  end
276
239
 
277
240
  def generate_completions
@@ -280,6 +243,7 @@ module Doing
280
243
  out << generate_helpers
281
244
  out << generate_subcommand_completions
282
245
  out << generate_subcommand_option_completions
246
+ @bar.advance(status: '✅')
283
247
  @bar.finish
284
248
  out.join("\n")
285
249
  end