Class: GDKBox::Completion
- Inherits:
-
Object
- Object
- GDKBox::Completion
- Defined in:
- lib/gdkbox/completion.rb
Overview
Generates shell completion scripts for the gdkbox CLI.
The list of subcommands and their flags is introspected from the Thor CLI
so it stays in sync automatically. Box names and skill names are completed
dynamically at completion time by shelling back out to gdkbox ls and
gdkbox skills.
Constant Summary collapse
- SHELLS =
%w[bash zsh].freeze
- BOX_COMMANDS =
Subcommands whose first positional argument is an existing box.
%w[status dispatch ssh code install-agent set-key set-git set-remote hydrate claim release start stop rm add-skill].freeze
- MARKER =
Marker identifying the rc-file block
installmanages. "# gdkbox:completion"
Instance Method Summary collapse
-
#initialize(cli_class = CLI, config: Config.new, home: Dir.home) ⇒ Completion
constructor
A new instance of Completion.
-
#install(shell) ⇒ Object
Make completion permanent for the given shell: write the script to a file under the gdkbox home (regenerated on every install, so re-running after an upgrade picks up new subcommands) and wire the shell's rc file to source it — once, marker-tagged, like the set-host hosts entry.
- #rc_path(shell) ⇒ Object
-
#script(shell) ⇒ Object
The completion script for the given shell.
Constructor Details
#initialize(cli_class = CLI, config: Config.new, home: Dir.home) ⇒ Completion
Returns a new instance of Completion.
20 21 22 23 24 |
# File 'lib/gdkbox/completion.rb', line 20 def initialize(cli_class = CLI, config: Config.new, home: Dir.home) @cli = cli_class @config = config @home = home end |
Instance Method Details
#install(shell) ⇒ Object
Make completion permanent for the given shell: write the script to a
file under the gdkbox home (regenerated on every install, so re-running
after an upgrade picks up new subcommands) and wire the shell's rc file
to source it — once, marker-tagged, like the set-host hosts entry.
Sourcing a static file keeps shell startup fast: no Ruby process runs,
unlike the eval "$(gdkbox completion ...)" approach.
Returns [script_path, rc_path, rc_changed].
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/gdkbox/completion.rb', line 51 def install(shell) content = script(shell) # validates the shell first @config.ensure_dirs! script_path = File.join(@config.home, "completion.#{shell}") File.write(script_path, content) rc = rc_path(shell) line = "[ -f #{script_path.inspect} ] && source #{script_path.inspect}" existing = File.exist?(rc) ? File.read(rc) : "" return [script_path, rc, false] if existing.include?(MARKER) File.open(rc, "a") do |f| f.write("\n") unless existing.empty? || existing.end_with?("\n") f.write("\n#{MARKER}\n#{line}\n") end [script_path, rc, true] end |
#rc_path(shell) ⇒ Object
69 70 71 |
# File 'lib/gdkbox/completion.rb', line 69 def rc_path(shell) File.join(@home, shell == "bash" ? ".bashrc" : ".zshrc") end |
#script(shell) ⇒ Object
The completion script for the given shell.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/gdkbox/completion.rb', line 27 def script(shell) unless SHELLS.include?(shell) raise Error, "Unsupported shell '#{shell}'. Supported: #{SHELLS.join(', ')}." end body = function + "\ncomplete -F _gdkbox gdkbox\n" return body if shell == "bash" # zsh runs bash-style completion functions via bashcompinit, which needs # the completion system loaded — initialize it if the user's zshrc has # not already done so (the guard keeps a second compinit from running). <<~ZSH + body whence compdef >/dev/null || { autoload -U compinit && compinit } autoload -U +X bashcompinit && bashcompinit ZSH end |