bashly 1.4.0 → 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 (47) 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 +2 -2
  5. data/lib/bashly/completions/completely.yaml +0 -4
  6. data/lib/bashly/config_validator.rb +16 -3
  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 +8 -4
  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 +12 -1
  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/completion.gtx +1 -0
  35. data/lib/bashly/views/flag/completion_filter.gtx +7 -0
  36. data/lib/bashly/views/flag/completion_filter_arg.gtx +10 -0
  37. data/lib/bashly/views/flag/completion_filter_block.gtx +8 -0
  38. data/lib/bashly/views/flag/completion_filter_no_arg.gtx +2 -0
  39. data/lib/bashly/views/flag/completion_value_candidates.gtx +31 -0
  40. data/lib/bashly.rb +2 -5
  41. metadata +22 -23
  42. data/lib/bashly/completion_builder.rb +0 -231
  43. data/lib/bashly/concerns/completions.rb +0 -48
  44. data/lib/bashly/libraries/completions/completions_function.rb +0 -37
  45. data/lib/bashly/libraries/completions/completions_script.rb +0 -28
  46. data/lib/bashly/libraries/completions/completions_yaml.rb +0 -26
  47. /data/lib/bashly/views/wrapper/{bash3_bouncer.gtx → bash_version_bouncer.gtx} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eca947512ada2ac873e3b6d399d75b441c97eb1ac4c56f5e1e8c1017fc9389ac
4
- data.tar.gz: f340d79b2f493871f3601c3be689eaf846a4f865eabb34cb3beeaab529ddf2eb
3
+ metadata.gz: 6e96439b1894f3097d9c8ea8d49b42254075a41bf02b233aa7d57674030e2d7f
4
+ data.tar.gz: 14963288238d456e105ce739fdc076d0bb950f497a234851725ba3f887a4a982
5
5
  SHA512:
6
- metadata.gz: 1fba0f5a53ebd3f4a209a1a4a12b7e132d20b06aba4d9dac4afa199b240f0099e39be1905a4d5db95d37255cebdf62d4c7058131b3b2ee1c2ba54a09d4054de5
7
- data.tar.gz: 688fb3b6a40e18a2d63a1bde4ddbeaa999d13c8f8b1b5487af3cfe4a1487d0fc0154422869138beed62b04cc1bc321902046ec1f805aa2226f3085b5d619e20d
6
+ metadata.gz: 474e72b43adcba1b0860f123be0584dbf8d7d7d14797f44018603f6f805e6a792b92282201d7930383e40ff48d771094e339e0c279c12940558a17d07dc09f06
7
+ data.tar.gz: 343351f0dbcb3d182ef2050e99a22f2ff39a1839ba11b208712c3cb85178f44678628f05ac1d2b2a4370e2dc77055f66972d16e94f5a4122dff409b937d9e956
@@ -1,55 +1,17 @@
1
- require 'completely'
2
-
3
1
  module Bashly
4
2
  module Commands
5
3
  class Completions < Base
6
- summary 'Install bash completions for bashly itself'
7
- help 'Display the bash completions script or install it directly to your bash completions directory'
4
+ summary 'Display bash completions for bashly itself'
8
5
 
9
- usage 'bashly completions [--install|--uninstall]'
6
+ usage 'bashly completions'
10
7
  usage 'bashly completions (-h|--help)'
11
8
 
12
- option '-i --install', 'Install the completions script to your bash completions directory'
13
- option '-u --uninstall', 'Uninstall the completions script from your bash completions directory'
14
-
15
9
  def run
16
- if args['--install']
17
- install_completions
18
- elsif args['--uninstall']
19
- uninstall_completions
20
- else
21
- puts script
22
- end
23
- end
24
-
25
- def installer
26
- @installer ||= Completely::Installer.new program: 'bashly', script_path: script_path
10
+ puts script
27
11
  end
28
12
 
29
13
  private
30
14
 
31
- def install_completions
32
- success = installer.install force: true
33
- raise Error, "Failed running command:\nnb`#{installer.install_command_string}`" unless success
34
-
35
- say 'Completions installed'
36
- say "Source: m`#{installer.script_path}`"
37
- say "Target: m`#{installer.target_path}`"
38
- say 'Restart your session for the changes to take effect'
39
- end
40
-
41
- def uninstall_completions
42
- success = installer.uninstall
43
- raise Error, "Failed running command:\nnb`#{installer.uninstall_command_string}`" unless success
44
-
45
- say 'Completions uninstalled'
46
- say 'Restart your session for the changes to take effect'
47
- end
48
-
49
- def script_path
50
- @script_path ||= asset('completions/bashly-completions.bash')
51
- end
52
-
53
15
  def script
54
16
  @script ||= asset_content('completions/bashly-completions.bash')
55
17
  end
@@ -15,10 +15,6 @@ Note that for production use, only the `bashly-completions.bash` is used.
15
15
 
16
16
  ## For users
17
17
 
18
- Install completions in one of two ways:
19
-
20
- 1. Run `bashly completions --install`. This will make a best effort to copy
21
- the completions script to your completions directory.
22
- 2. If the above fails, run `bashly completions > out.bash`, then copy the file
23
- manually to your completions directory (or simply get the
24
- `bashly-completions.bash` from this directory).
18
+ Run `bashly completions > out.bash`, then copy the file manually to your
19
+ completions directory (or simply get the `bashly-completions.bash` from this
20
+ directory).
@@ -297,11 +297,11 @@ _bashly_completions() {
297
297
 
298
298
  case "$node_id:$positional_index" in
299
299
  5:0)
300
- while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "colors completions completions_script completions_yaml config help hooks ini lib render_markdown render_markdown_github render_mandoc settings stacktrace strings validations yaml" -- "$cur")
300
+ while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "colors config help hooks ini lib render_markdown render_markdown_github render_mandoc settings stacktrace strings validations yaml" -- "$cur")
301
301
  return
302
302
  ;;
303
303
  6:0)
304
- while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "arg arg.allowed arg.completions arg.default arg.help arg.name arg.repeatable arg.required arg.validate command command.alias command.args command.catch_all command.commands command.completions command.default command.dependencies command.environment_variables command.examples command.expose command.extensible command.filename command.filters command.flags command.footer command.function command.group command.help command.help_header_override command.name command.private command.variables command.version environment_variable environment_variable.default environment_variable.help environment_variable.name environment_variable.private environment_variable.required environment_variable.validate flag flag.alias flag.allowed flag.arg flag.completions flag.conflicts flag.default flag.help flag.long flag.needs flag.negatable flag.private flag.repeatable flag.required flag.short flag.unique flag.validate variable variable.name variable.value" -- "$cur")
304
+ while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "arg arg.allowed arg.completions arg.default arg.help arg.name arg.repeatable arg.required arg.validate command command.alias command.args command.catch_all command.commands command.default command.dependencies command.environment_variables command.examples command.expose command.extensible command.filename command.filters command.flags command.footer command.function command.group command.help command.help_header_override command.name command.private command.variables command.version environment_variable environment_variable.default environment_variable.help environment_variable.name environment_variable.private environment_variable.required environment_variable.validate flag flag.alias flag.allowed flag.arg flag.completions flag.conflicts flag.default flag.help flag.long flag.needs flag.negatable flag.private flag.repeatable flag.required flag.short flag.unique flag.validate variable variable.name variable.value" -- "$cur")
305
305
  return
306
306
  ;;
307
307
  8: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
@@ -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
 
@@ -137,7 +151,7 @@ module Bashly
137
151
  assert_boolean "#{key}.required", value['required']
138
152
  assert_array "#{key}.allowed", value['allowed'], of: :string
139
153
  assert_array "#{key}.conflicts", value['conflicts'], of: :string
140
- assert_array "#{key}.completions", value['completions'], of: :string
154
+ assert_completions "#{key}.completions", value['completions']
141
155
 
142
156
  assert value['long'].match(/^--[a-zA-Z0-9_-]+$/), "#{key}.long must be in the form of '--name'" if value['long']
143
157
  assert value['short'].match(/^-[a-zA-Z0-9]$/), "#{key}.short must be in the form of '-n'" if value['short']
@@ -236,7 +250,6 @@ module Bashly
236
250
  assert_array "#{key}.args", value['args'], of: :arg
237
251
  assert_array "#{key}.flags", value['flags'], of: :flag
238
252
  assert_array "#{key}.commands", value['commands'], of: :command
239
- assert_array "#{key}.completions", value['completions'], of: :string
240
253
  assert_array "#{key}.filters", value['filters'], of: :string
241
254
  assert_array "#{key}.environment_variables", value['environment_variables'], of: :env_var
242
255
  assert_array "#{key}.variables", value['variables'], of: :var
@@ -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
@@ -58,14 +58,18 @@ flag.arg:
58
58
  help: Specify the user name
59
59
 
60
60
  flag.completions:
61
- 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`.
62
66
  url: https://bashly.dev/configuration/flag/#completions
63
67
  example: |-
64
68
  flags:
65
- - long: --user
66
- arg: username
69
+ - long: --config
70
+ arg: file
67
71
  completions:
68
- - <user>
72
+ options: [files]
69
73
 
70
74
  # Anything in the 'allowed' option is automatically added as a completion.
71
75
  - long: --protocol
@@ -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,7 +3,6 @@ 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
 
@@ -44,6 +43,18 @@ module Bashly
44
43
  end
45
44
  end
46
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
+
47
58
  def name
48
59
  long || short
49
60
  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'
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
+ >
@@ -0,0 +1,21 @@
1
+ = view_marker
2
+
3
+ completion_shells = Settings.completion_shells
4
+
5
+ > send_completions() {
6
+ > local completion_shell="${1:-{{ completion_shells.first }}}"
7
+ >
8
+ > case "$completion_shell" in
9
+ completion_shells.each do |shell|
10
+ > {{ shell }}) send_completions_{{ shell }} ;;
11
+ end
12
+ > *)
13
+ > printf 'unsupported shell: %s\n' "$completion_shell" >&2
14
+ > return 1
15
+ > ;;
16
+ > esac
17
+ > }
18
+ >
19
+ completion_shells.each do |shell|
20
+ = render :"completion_script_#{shell}"
21
+ end
@@ -0,0 +1,63 @@
1
+ = view_marker
2
+
3
+ > send_completions_bash() {
4
+ > echo $'_{{ name.to_underscore }}_completions() {'
5
+ > echo $' local completion_command="${COMP_WORDS[0]}"'
6
+ > echo $' local completion_current="${COMP_WORDS[COMP_CWORD]:-}"'
7
+ > echo $' local completion_word_count=$((COMP_CWORD - 1))'
8
+ > echo $' local -a completion_words=()'
9
+ > echo $' local -a completion_response=()'
10
+ > echo $' local -a completion_options=()'
11
+ > echo $' local -A completion_seen=()'
12
+ > echo $''
13
+ > echo $' if [[ $completion_word_count -gt 0 ]]; then'
14
+ > echo $' completion_words=("${COMP_WORDS[@]:1:completion_word_count}")'
15
+ > echo $' fi'
16
+ > echo $''
17
+ > echo $' COMPREPLY=()'
18
+ > echo $' while IFS= read -r completion_line; do'
19
+ > echo $' completion_response+=("$completion_line")'
20
+ > echo $' done < <("$completion_command" __complete "${completion_words[@]}" "$completion_current")'
21
+ > echo $''
22
+ > echo $' local completion_directive="${completion_response[-1]:-}"'
23
+ > echo $' if [[ $completion_directive == :options=* ]]; then'
24
+ > echo $' unset "completion_response[-1]"'
25
+ > echo $' IFS=, read -r -a completion_options <<< "${completion_directive#:options=}"'
26
+ > echo $' fi'
27
+ > echo $''
28
+ > echo $' COMPREPLY=("${completion_response[@]}")'
29
+ > echo $' local completion_candidate'
30
+ > echo $' for completion_candidate in "${COMPREPLY[@]}"; do'
31
+ > echo $' completion_seen["$completion_candidate"]=1'
32
+ > echo $' done'
33
+ > echo $''
34
+ > echo $' local completion_option'
35
+ > echo $' local completion_files=false'
36
+ > echo $' local completion_directories=false'
37
+ > echo $' for completion_option in "${completion_options[@]}"; do'
38
+ > echo $' case "$completion_option" in'
39
+ > echo $' files) completion_files=true ;;'
40
+ > echo $' directories) completion_directories=true ;;'
41
+ > echo $' no-space) compopt -o nospace ;;'
42
+ > echo $' esac'
43
+ > echo $' done'
44
+ > echo $''
45
+ > echo $' if [[ $completion_files == true ]]; then'
46
+ > echo $' while IFS= read -r completion_candidate; do'
47
+ > echo $' if [[ -z "${completion_seen[$completion_candidate]:-}" ]]; then'
48
+ > echo $' COMPREPLY+=("$completion_candidate")'
49
+ > echo $' completion_seen["$completion_candidate"]=1'
50
+ > echo $' fi'
51
+ > echo $' done < <(compgen -f -- "$completion_current")'
52
+ > echo $' elif [[ $completion_directories == true ]]; then'
53
+ > echo $' while IFS= read -r completion_candidate; do'
54
+ > echo $' if [[ -z "${completion_seen[$completion_candidate]:-}" ]]; then'
55
+ > echo $' COMPREPLY+=("$completion_candidate")'
56
+ > echo $' completion_seen["$completion_candidate"]=1'
57
+ > echo $' fi'
58
+ > echo $' done < <(compgen -d -- "$completion_current")'
59
+ > echo $' fi'
60
+ > echo $'}'
61
+ > echo $''
62
+ > echo $'complete -F _{{ name.to_underscore }}_completions {{ name }}'
63
+ > }