bashly 1.4.0.rc2 → 2.0.0.rc1

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bashly/commands/completions.rb +3 -41
  3. data/lib/bashly/completions/README.md +3 -7
  4. data/lib/bashly/completions/bashly-completions.bash +178 -382
  5. data/lib/bashly/completions/completely.yaml +2 -4
  6. data/lib/bashly/config_validator.rb +55 -5
  7. data/lib/bashly/docs/arg.yml +12 -6
  8. data/lib/bashly/docs/command.yml +0 -12
  9. data/lib/bashly/docs/flag.yml +29 -5
  10. data/lib/bashly/libraries/libraries.yml +0 -15
  11. data/lib/bashly/libraries/settings/settings.yml +9 -1
  12. data/lib/bashly/script/argument.rb +12 -0
  13. data/lib/bashly/script/command.rb +1 -2
  14. data/lib/bashly/script/flag.rb +48 -11
  15. data/lib/bashly/script/introspection/commands.rb +5 -0
  16. data/lib/bashly/script/wrapper.rb +1 -1
  17. data/lib/bashly/settings.rb +28 -3
  18. data/lib/bashly/version.rb +1 -1
  19. data/lib/bashly/views/argument/completion.gtx +31 -0
  20. data/lib/bashly/views/argument/completion_filter.gtx +1 -0
  21. data/lib/bashly/views/command/completion_argument_candidates.gtx +11 -0
  22. data/lib/bashly/views/command/completion_argument_filter.gtx +25 -0
  23. data/lib/bashly/views/command/completion_command_candidates.gtx +3 -0
  24. data/lib/bashly/views/command/completion_flag_candidates.gtx +21 -0
  25. data/lib/bashly/views/command/completion_function.gtx +24 -0
  26. data/lib/bashly/views/command/completion_script.gtx +21 -0
  27. data/lib/bashly/views/command/completion_script_bash.gtx +63 -0
  28. data/lib/bashly/views/command/completion_script_zsh.gtx +52 -0
  29. data/lib/bashly/views/command/completion_word_filter.gtx +44 -0
  30. data/lib/bashly/views/command/completions.gtx +81 -0
  31. data/lib/bashly/views/command/inspect_args.gtx +3 -3
  32. data/lib/bashly/views/command/master_script.gtx +1 -0
  33. data/lib/bashly/views/command/start.gtx +9 -0
  34. data/lib/bashly/views/flag/argfile_case.gtx +8 -1
  35. data/lib/bashly/views/flag/case.gtx +9 -1
  36. data/lib/bashly/views/flag/completion.gtx +1 -0
  37. data/lib/bashly/views/flag/completion_filter.gtx +7 -0
  38. data/lib/bashly/views/flag/completion_filter_arg.gtx +10 -0
  39. data/lib/bashly/views/flag/completion_filter_block.gtx +8 -0
  40. data/lib/bashly/views/flag/completion_filter_no_arg.gtx +2 -0
  41. data/lib/bashly/views/flag/completion_value_candidates.gtx +31 -0
  42. data/lib/bashly.rb +2 -5
  43. metadata +22 -37
  44. data/lib/bashly/completion_builder.rb +0 -231
  45. data/lib/bashly/concerns/completions.rb +0 -48
  46. data/lib/bashly/libraries/completions/completions_function.rb +0 -37
  47. data/lib/bashly/libraries/completions/completions_script.rb +0 -28
  48. data/lib/bashly/libraries/completions/completions_yaml.rb +0 -26
  49. /data/lib/bashly/views/wrapper/{bash3_bouncer.gtx → bash_version_bouncer.gtx} +0 -0
@@ -60,9 +60,6 @@ tokens:
60
60
  path:
61
61
  library:
62
62
  - colors
63
- - completions
64
- - completions_script
65
- - completions_yaml
66
63
  - config
67
64
  - help
68
65
  - hooks
@@ -91,7 +88,6 @@ tokens:
91
88
  - command.args
92
89
  - command.catch_all
93
90
  - command.commands
94
- - command.completions
95
91
  - command.default
96
92
  - command.dependencies
97
93
  - command.environment_variables
@@ -118,6 +114,7 @@ tokens:
118
114
  - environment_variable.required
119
115
  - environment_variable.validate
120
116
  - flag
117
+ - flag.alias
121
118
  - flag.allowed
122
119
  - flag.arg
123
120
  - flag.completions
@@ -126,6 +123,7 @@ tokens:
126
123
  - flag.help
127
124
  - flag.long
128
125
  - flag.needs
126
+ - flag.negatable
129
127
  - flag.private
130
128
  - flag.repeatable
131
129
  - flag.required
@@ -88,6 +88,20 @@ module Bashly
88
88
  assert [true, false, nil, 'always'].include?(value), "#{key} must be a boolean, or the string 'always'"
89
89
  end
90
90
 
91
+ def assert_completions(key, value)
92
+ return unless value
93
+
94
+ assert_hash key, value, keys: %i[static dynamic options]
95
+ assert_array "#{key}.static", value['static'], of: :string
96
+ assert_array "#{key}.dynamic", value['dynamic'], of: :string
97
+ assert_array "#{key}.options", value['options'], of: :string
98
+
99
+ Array(value['options']).each do |option|
100
+ assert %w[files directories no-space].include?(option),
101
+ "#{key}.options contains an unknown option: #{option}"
102
+ end
103
+ end
104
+
91
105
  def assert_arg(key, value)
92
106
  assert_hash key, value, keys: Script::Argument.option_keys
93
107
  refute value['allowed'] && value['completions'], "#{key} cannot have both nub`allowed` and nub`completions`"
@@ -101,7 +115,7 @@ module Bashly
101
115
  assert_boolean "#{key}.unique", value['unique']
102
116
 
103
117
  assert_array "#{key}.allowed", value['allowed'], of: :string
104
- assert_array "#{key}.completions", value['completions'], of: :string
118
+ assert_completions "#{key}.completions", value['completions']
105
119
 
106
120
  refute value['name'].match(/^-/), "#{key}.name must not start with '-'"
107
121
 
@@ -126,23 +140,36 @@ module Bashly
126
140
  assert_optional_string "#{key}.short", value['short']
127
141
  assert_optional_string "#{key}.help", value['help']
128
142
  assert_optional_string "#{key}.arg", value['arg']
143
+ assert_string_or_array "#{key}.alias", value['alias']
129
144
  assert_string_or_array "#{key}.default", value['default']
130
145
  assert_string_or_array "#{key}.validate", value['validate']
131
146
 
147
+ assert_boolean "#{key}.negatable", value['negatable']
132
148
  assert_boolean "#{key}.private", value['private']
133
149
  assert_boolean "#{key}.repeatable", value['repeatable']
134
150
  assert_boolean "#{key}.unique", value['unique']
135
151
  assert_boolean "#{key}.required", value['required']
136
152
  assert_array "#{key}.allowed", value['allowed'], of: :string
137
153
  assert_array "#{key}.conflicts", value['conflicts'], of: :string
138
- assert_array "#{key}.completions", value['completions'], of: :string
154
+ assert_completions "#{key}.completions", value['completions']
139
155
 
140
156
  assert value['long'].match(/^--[a-zA-Z0-9_-]+$/), "#{key}.long must be in the form of '--name'" if value['long']
141
157
  assert value['short'].match(/^-[a-zA-Z0-9]$/), "#{key}.short must be in the form of '-n'" if value['short']
158
+ Array(value['alias']).each_with_index do |flag_alias, index|
159
+ alias_key = value['alias'].is_a?(Array) ? "#{key}.alias[#{index}]" : "#{key}.alias"
160
+ assert_flag_alias alias_key, flag_alias
161
+ end
142
162
  refute value['arg'].match(/^-/), "#{key}.arg must not start with '-'" if value['arg']
143
163
 
144
164
  refute value['required'] && value['default'], "#{key} cannot have both nub`required` and nub`default`"
145
165
 
166
+ if value['negatable']
167
+ assert value['long'], "#{key}.negatable requires nub`long`"
168
+ refute value['arg'], "#{key}.negatable does not make sense with nub`arg`"
169
+ refute value['repeatable'], "#{key}.negatable does not make sense with nub`repeatable`"
170
+ refute value['required'], "#{key}.negatable does not make sense with nub`required`"
171
+ end
172
+
146
173
  if value['default']
147
174
  assert value['arg'], "#{key}.default does not make sense without nub`arg`"
148
175
  end
@@ -165,6 +192,13 @@ module Bashly
165
192
  end
166
193
  end
167
194
 
195
+ def assert_flag_alias(key, value)
196
+ assert(
197
+ value.match(/^--[a-zA-Z0-9_-]+$/) || value.match(/^-[a-zA-Z0-9]$/),
198
+ "#{key} must be in the form of '--name' or '-n'"
199
+ )
200
+ end
201
+
168
202
  def assert_env_var(key, value)
169
203
  assert_hash key, value, keys: Script::EnvironmentVariable.option_keys
170
204
  assert_string "#{key}.name", value['name']
@@ -216,14 +250,12 @@ module Bashly
216
250
  assert_array "#{key}.args", value['args'], of: :arg
217
251
  assert_array "#{key}.flags", value['flags'], of: :flag
218
252
  assert_array "#{key}.commands", value['commands'], of: :command
219
- assert_array "#{key}.completions", value['completions'], of: :string
220
253
  assert_array "#{key}.filters", value['filters'], of: :string
221
254
  assert_array "#{key}.environment_variables", value['environment_variables'], of: :env_var
222
255
  assert_array "#{key}.variables", value['variables'], of: :var
223
256
 
224
257
  assert_uniq "#{key}.commands", value['commands'], %w[name alias]
225
- assert_uniq "#{key}.flags", value['flags'], 'long'
226
- assert_uniq "#{key}.flags", value['flags'], 'short'
258
+ assert_uniq_flags key, value['flags']
227
259
  assert_uniq "#{key}.args", value['args'], 'name'
228
260
 
229
261
  if value['function']
@@ -265,5 +297,23 @@ module Bashly
265
297
  refute value['extensible'], "#{key}.extensible makes no sense"
266
298
  end
267
299
  end
300
+
301
+ def assert_uniq_flags(key, flags)
302
+ return unless flags
303
+
304
+ list = flags.flat_map do |flag|
305
+ [flag['long'], flag['short'], *Array(flag['alias']), negated_flag_name(flag)].compact
306
+ end
307
+
308
+ nonuniqs = list.nonuniq
309
+ assert nonuniqs.empty?,
310
+ "#{key}.flags contains non-unique elements (#{nonuniqs.join ', '}) in long or short or alias"
311
+ end
312
+
313
+ def negated_flag_name(flag)
314
+ return unless flag['negatable'] == true && flag['long']
315
+
316
+ "--no-#{flag['long'].delete_prefix '--'}"
317
+ end
268
318
  end
269
319
  end
@@ -34,15 +34,21 @@ arg.allowed:
34
34
  default: development
35
35
 
36
36
  arg.completions:
37
- help: Specify a list of additional completion suggestions when used in conjunction with `bashly add completions`.
37
+ help: |-
38
+ Configure additional runtime completions.
39
+ `static` contains literal candidates. `dynamic` contains Bash commands that
40
+ print one candidate per line. `options` accepts `files`, `directories`, and
41
+ `no-space`.
38
42
  url: https://bashly.dev/configuration/argument/#completions
39
43
  example: |-
40
44
  args:
41
- - name: path
42
- help: File or directory to process
45
+ - name: branch
46
+ help: Branch to process
43
47
  completions:
44
- - <file>
45
- - <directory>
48
+ static: [main, develop]
49
+ dynamic:
50
+ - git branch --format='%(refname:short)'
51
+ options: [no-space]
46
52
 
47
53
  arg.default:
48
54
  help: Specify the value to apply when not provided by the user.
@@ -102,4 +108,4 @@ arg.validate:
102
108
  example: |-
103
109
  args:
104
110
  - name: path
105
- validate: file_exists
111
+ validate: file_exists
@@ -74,18 +74,6 @@ command.commands:
74
74
  alias: a
75
75
  help: Register a local repository
76
76
 
77
- command.completions:
78
- help: Specify a list of additional completion suggestions when used in conjunction with `bashly add completions`.
79
- url: https://bashly.dev/configuration/command/#completions
80
- example: |-
81
- commands:
82
- - name: view
83
- help: View a directory, system user or a git branch
84
- completions:
85
- - <directory>
86
- - <user>
87
- - $(git branch 2> /dev/null)
88
-
89
77
  command.default:
90
78
  help: Specify that this sub-command will be executed implicitly.
91
79
  url: https://bashly.dev/configuration/command/#default
@@ -13,6 +13,17 @@ flag:
13
13
  help: Repository user name
14
14
  required: true
15
15
 
16
+ flag.alias:
17
+ help: Specify one or more aliases for this flag. Each alias must include the `--` or `-` prefix.
18
+ url: https://bashly.dev/configuration/flag/#alias
19
+ example: |-
20
+ flags:
21
+ - long: --container
22
+ short: -c
23
+ alias: [--pod, -p]
24
+ arg: name
25
+ help: Container name
26
+
16
27
  flag.allowed:
17
28
  help: Specify a list of allowed values. Can be used in conjunction with `default` and `required`, and must be accompanied by `arg`.
18
29
  url: https://bashly.dev/configuration/flag/#allowed
@@ -47,14 +58,18 @@ flag.arg:
47
58
  help: Specify the user name
48
59
 
49
60
  flag.completions:
50
- help: Specify a list of additional completion suggestions when used in conjunction with `bashly add completions`. Must be accompanied by `arg`.
61
+ help: |-
62
+ Configure additional runtime completions. Must be accompanied by `arg`.
63
+ `static` contains literal candidates. `dynamic` contains Bash commands that
64
+ print one candidate per line. `options` accepts `files`, `directories`, and
65
+ `no-space`.
51
66
  url: https://bashly.dev/configuration/flag/#completions
52
67
  example: |-
53
68
  flags:
54
- - long: --user
55
- arg: username
69
+ - long: --config
70
+ arg: file
56
71
  completions:
57
- - <user>
72
+ options: [files]
58
73
 
59
74
  # Anything in the 'allowed' option is automatically added as a completion.
60
75
  - long: --protocol
@@ -136,6 +151,15 @@ flag.needs:
136
151
  help: Where to add the alias
137
152
  needs: [--add]
138
153
 
154
+ flag.negatable:
155
+ help: Allow a boolean long flag to also be disabled with its `--no-` form.
156
+ url: https://bashly.dev/configuration/flag/#negatable
157
+ example: |-
158
+ flags:
159
+ - long: --color
160
+ help: Enable color output
161
+ negatable: true
162
+
139
163
  flag.private:
140
164
  help: Specify that this flag should not be displayed in the help text.
141
165
  url: https://bashly.dev/configuration/flag/#private
@@ -205,4 +229,4 @@ flag.validate:
205
229
  - long: --config
206
230
  arg: path
207
231
  help: Load configuration from a file
208
- validate: file_exists
232
+ validate: file_exists
@@ -12,21 +12,6 @@ colors:
12
12
 
13
13
  m`$ bashly add hooks`
14
14
 
15
- completions:
16
- help: Generate a bash completions function.
17
- usage: '[PATH]'
18
- handler: Bashly::Libraries::CompletionsFunction
19
-
20
- completions_script:
21
- help: Generate a standalone bash completions script.
22
- usage: '[PATH]'
23
- handler: Bashly::Libraries::CompletionsScript
24
-
25
- completions_yaml:
26
- help: Generate a completions YAML configuration for Completely.
27
- usage: '[PATH]'
28
- handler: Bashly::Libraries::CompletionsYAML
29
-
30
15
  config:
31
16
  help: Add functions for handling INI configuration files to the lib directory.
32
17
  files:
@@ -157,13 +157,21 @@ env: development
157
157
  # - always # render this feature in any environment
158
158
  # - never # do not render this feature
159
159
  enable_header_comment: always
160
- enable_bash3_bouncer: always
160
+ enable_bash_version_bouncer: always
161
161
  enable_view_markers: development
162
162
  enable_inspect_args: development
163
163
  enable_deps_array: always
164
164
  enable_env_var_names_array: always
165
165
  enable_sourcing: development
166
166
 
167
+ # Generate native runtime completions. Supported values:
168
+ # - ~ or false # disable completions (default)
169
+ # - minimal # generate the runtime completion engine without shell adapters
170
+ # - bash or zsh # generate the runtime engine and one shell adapter
171
+ # - bash,zsh # generate the runtime engine and selected shell adapters
172
+ # - full # generate the runtime engine and all available shell adapters
173
+ completions: ~
174
+
167
175
 
168
176
  #-------------------------------------------------------------------------------
169
177
  # DEVELOPER OPTIONS
@@ -23,6 +23,18 @@ module Bashly
23
23
  end
24
24
  end
25
25
 
26
+ def completion_static
27
+ completions&.fetch('static', []) || []
28
+ end
29
+
30
+ def completion_dynamic
31
+ completions&.fetch('dynamic', []) || []
32
+ end
33
+
34
+ def completion_options
35
+ completions&.fetch('options', []) || []
36
+ end
37
+
26
38
  def label
27
39
  repeatable ? "#{name.upcase}..." : name.upcase
28
40
  end
@@ -1,7 +1,6 @@
1
1
  module Bashly
2
2
  module Script
3
3
  class Command < Base
4
- include Completions::Command
5
4
  include Introspection::Arguments
6
5
  include Introspection::Commands
7
6
  include Introspection::Dependencies
@@ -14,7 +13,7 @@ module Bashly
14
13
  class << self
15
14
  def option_keys
16
15
  @option_keys ||= %i[
17
- alias argfile args catch_all commands completions
16
+ alias argfile args catch_all commands
18
17
  default dependencies environment_variables examples
19
18
  extensible expose filename filters flags
20
19
  footer function group help help_header_override name
@@ -3,27 +3,34 @@ require 'shellwords'
3
3
  module Bashly
4
4
  module Script
5
5
  class Flag < Base
6
- include Completions::Flag
7
6
  include Introspection::Visibility
8
7
  include Introspection::Validate
9
8
 
10
9
  class << self
11
10
  def option_keys
12
11
  @option_keys ||= %i[
13
- allowed arg completions conflicts default help long needs
14
- private repeatable required short unique validate
12
+ alias allowed arg completions conflicts default help long needs
13
+ negatable private repeatable required short unique validate
15
14
  ]
16
15
  end
17
16
  end
18
17
 
18
+ def alt
19
+ return [] unless options['alias']
20
+
21
+ options['alias'].is_a?(String) ? [options['alias']] : options['alias']
22
+ end
23
+
19
24
  def aliases
20
- if long && short
21
- [long, short]
22
- elsif long
23
- [long]
24
- else
25
- [short]
26
- end
25
+ [long, negated_long, short].compact + alt
26
+ end
27
+
28
+ def positive_aliases
29
+ primary_aliases + alt
30
+ end
31
+
32
+ def negated_long
33
+ "--no-#{long_without_prefix}" if negatable && long
27
34
  end
28
35
 
29
36
  def default_string
@@ -36,17 +43,47 @@ module Bashly
36
43
  end
37
44
  end
38
45
 
46
+ def completion_static
47
+ completions&.fetch('static', []) || []
48
+ end
49
+
50
+ def completion_dynamic
51
+ completions&.fetch('dynamic', []) || []
52
+ end
53
+
54
+ def completion_options
55
+ completions&.fetch('options', []) || []
56
+ end
57
+
39
58
  def name
40
59
  long || short
41
60
  end
42
61
 
43
62
  def usage_string(extended: false)
44
- result = [aliases.join(', ')]
63
+ result = [usage_aliases.join(', ')]
45
64
  result << arg.upcase if arg
46
65
  result << strings[:required] if required && extended
47
66
  result << strings[:repeatable] if repeatable && extended
48
67
  result.join ' '
49
68
  end
69
+
70
+ private
71
+
72
+ def primary_aliases
73
+ [long, short].compact
74
+ end
75
+
76
+ def usage_aliases
77
+ [usage_long, short].compact + alt
78
+ end
79
+
80
+ def usage_long
81
+ negatable && long ? "--[no-]#{long_without_prefix}" : long
82
+ end
83
+
84
+ def long_without_prefix
85
+ long.delete_prefix '--'
86
+ end
50
87
  end
51
88
  end
52
89
  end
@@ -41,6 +41,11 @@ module Bashly
41
41
  commands.map(&:name)
42
42
  end
43
43
 
44
+ # Returns command names and aliases that can be offered as completions
45
+ def completion_aliases
46
+ public_commands.flat_map(&:aliases).reject { |name| name.end_with? '*' }
47
+ end
48
+
44
49
  # Returns an array of the Commands
45
50
  def commands
46
51
  return [] unless options['commands']
@@ -46,7 +46,7 @@ module Bashly
46
46
 
47
47
  def default_header
48
48
  result = render 'header'
49
- result += render('bash3_bouncer') unless function_name || !Settings.enabled?(:bash3_bouncer)
49
+ result += render('bash_version_bouncer') unless function_name || !Settings.enabled?(:bash_version_bouncer)
50
50
  result
51
51
  end
52
52
 
@@ -1,5 +1,7 @@
1
1
  module Bashly
2
2
  class Settings
3
+ COMPLETION_SHELLS = %w[bash zsh].freeze
4
+
3
5
  class << self
4
6
  include AssetHelper
5
7
 
@@ -7,9 +9,10 @@ module Bashly
7
9
  :argfile_var,
8
10
  :commands_dir,
9
11
  :compact_short_flags,
12
+ :completions,
10
13
  :conjoined_flag_args,
11
14
  :config_path,
12
- :enable_bash3_bouncer,
15
+ :enable_bash_version_bouncer,
13
16
  :enable_deps_array,
14
17
  :enable_env_var_names_array,
15
18
  :enable_header_comment,
@@ -50,6 +53,28 @@ module Bashly
50
53
  @compact_short_flags ||= get :compact_short_flags
51
54
  end
52
55
 
56
+ def completions
57
+ @completions ||= get :completions
58
+ end
59
+
60
+ def completions?
61
+ completions == 'minimal' || completion_shells.any?
62
+ end
63
+
64
+ def completion_shells
65
+ value = completions
66
+ return [] if value.nil? || value == false || value == 'minimal'
67
+ return COMPLETION_SHELLS if value == 'full'
68
+
69
+ shells = value.split(',', -1).map(&:strip) if value.is_a? String
70
+ valid = shells&.any? && shells.all? { |shell| COMPLETION_SHELLS.include? shell }
71
+ unique = shells&.uniq == shells
72
+ return shells if valid && unique
73
+
74
+ raise ConfigurationError,
75
+ "completions must be false, minimal, full, or a comma-separated list of: #{COMPLETION_SHELLS.join ', '}"
76
+ end
77
+
53
78
  def conjoined_flag_args
54
79
  @conjoined_flag_args ||= get :conjoined_flag_args
55
80
  end
@@ -64,8 +89,8 @@ module Bashly
64
89
  (send(:"enable_#{feature}") == 'development' && !production?)
65
90
  end
66
91
 
67
- def enable_bash3_bouncer
68
- @enable_bash3_bouncer ||= get :enable_bash3_bouncer
92
+ def enable_bash_version_bouncer
93
+ @enable_bash_version_bouncer ||= get :enable_bash_version_bouncer
69
94
  end
70
95
 
71
96
  def enable_deps_array
@@ -1,3 +1,3 @@
1
1
  module Bashly
2
- VERSION = '1.4.0.rc2'
2
+ VERSION = '2.0.0.rc1'
3
3
  end
@@ -0,0 +1,31 @@
1
+ if allowed
2
+ > local -a completion_values=(
3
+ allowed.each do |value|
4
+ > "{{ value }}"
5
+ end
6
+ > )
7
+ if unique
8
+ > local completion_value
9
+ > for completion_value in "${completion_values[@]}"; do
10
+ > if [[ -z "${completion_used_arguments["{{ name }}:$completion_value"]:-}" ]]; then
11
+ > completion_candidates "$completion_current" "$completion_value"
12
+ > fi
13
+ > done
14
+ else
15
+ > completion_candidates "$completion_current" "${completion_values[@]}"
16
+ end
17
+ end
18
+
19
+ if completion_static.any?
20
+ > completion_candidates "$completion_current" {{ completion_static.map { |value| Shellwords.shellescape value }.join ' ' }}
21
+ end
22
+
23
+ completion_dynamic.each do |command|
24
+ > if completion_output="$({ {{ command }}; } 2>/dev/null)"; then
25
+ > completion_dynamic_candidates "$completion_current" "$completion_output"
26
+ > fi
27
+ end
28
+
29
+ if completion_options.any?
30
+ > completion_add_options {{ completion_options.join ' ' }}
31
+ end
@@ -0,0 +1 @@
1
+ > completion_used_arguments["{{ name }}:$1"]=1
@@ -0,0 +1,11 @@
1
+ if args.any?
2
+ > if [[ $completion_current != -* ]]; then
3
+ > case "$completion_arg_index" in
4
+ args.each_with_index do |arg, index|
5
+ > {{ index }})
6
+ = arg.render(:completion).indent 6
7
+ > ;;
8
+ end
9
+ > esac
10
+ > fi
11
+ end
@@ -0,0 +1,25 @@
1
+ if args.any?(&:unique)
2
+ > case "$completion_arg_index" in
3
+ args.each_with_index do |arg, index|
4
+ next unless arg.unique
5
+
6
+ > {{ index }})
7
+ = arg.render(:completion_filter).indent 4
8
+ > ;;
9
+ end
10
+ > esac
11
+ end
12
+
13
+ if args.last.repeatable
14
+ last_arg_index = args.length - 1
15
+ > if [[ $completion_arg_index -lt {{ last_arg_index }} ]]; then
16
+ > completion_arg_index=$((completion_arg_index + 1))
17
+ > fi
18
+ > shift
19
+ else
20
+ > if [[ $completion_arg_index -ge {{ args.length }} ]]; then
21
+ > return
22
+ > fi
23
+ > completion_arg_index=$((completion_arg_index + 1))
24
+ > shift
25
+ end
@@ -0,0 +1,3 @@
1
+ if completion_aliases.any?
2
+ > completion_candidates "$completion_current" {{ completion_aliases.join ' ' }}
3
+ end
@@ -0,0 +1,21 @@
1
+ if fixed_flags? || public_flags.any?
2
+ > if [[ $completion_current == -* ]]; then
3
+ if fixed_flags?
4
+ if short_flag_exist? '-h'
5
+ > completion_flag_candidates --help "$completion_current" --help
6
+ else
7
+ > completion_flag_candidates --help "$completion_current" --help -h
8
+ end
9
+ if root_command?
10
+ if short_flag_exist? '-v'
11
+ > completion_flag_candidates --version "$completion_current" --version
12
+ else
13
+ > completion_flag_candidates --version "$completion_current" --version -v
14
+ end
15
+ end
16
+ end
17
+ public_flags.each do |flag|
18
+ = flag.render(:completion).indent 2
19
+ end
20
+ > fi
21
+ end
@@ -0,0 +1,24 @@
1
+ = view_marker
2
+
3
+ > {{ function_name }}_completion() {
4
+ > local completion_current="$1"
5
+ if args.any?
6
+ > local completion_arg_index=0
7
+ end
8
+ if args.any?(&:unique)
9
+ > local -A completion_used_arguments=()
10
+ end
11
+ if flags.any?(&:unique)
12
+ > local -A completion_used_flag_values=()
13
+ end
14
+ > shift
15
+ >
16
+ = render(:completion_word_filter).indent 2
17
+ = render(:completion_command_candidates).indent 2
18
+ if default_command
19
+ > {{ default_command.function_name }}_completion "$completion_current"
20
+ end
21
+ = render(:completion_flag_candidates).indent 2
22
+ = render(:completion_argument_candidates).indent 2
23
+ > }
24
+ >