module Clamp::Completion

Shell completion script generation.

Constants

GENERATORS

Public Instance Methods

argparse_specs_for(option) click to toggle source

Return fish argparse optspecs for an option.

# File lib/clamp/completion.rb, line 86
def argparse_specs_for(option)
  switches = expanded_switches(option)
  suffix = option.flag? ? "" : "="
  short = switches.find { |s| s.match?(/^-[^-]$/) }
  longs = switches.select { |s| s.start_with?("--") }
  if short && longs.length == 1
    ["#{short.delete_prefix('-')}/#{longs.first.delete_prefix('--')}#{suffix}"]
  else
    longs.map { |l| "#{l.delete_prefix('--')}#{suffix}" }
  end
end
collect_subcommand_names(command_class) click to toggle source

Collect all subcommand names across the command tree.

# File lib/clamp/completion.rb, line 99
def collect_subcommand_names(command_class)
  names = []
  walk_command_tree(command_class) do |cmd, _path, has_children|
    cmd.recognised_subcommands.each { |sub| names.concat(sub.names) } if has_children
  end
  names.uniq
end
encode_name(name) click to toggle source

Encode a name for use as a shell function identifier. Special characters are replaced with _XX hex codes.

# File lib/clamp/completion.rb, line 38
def encode_name(name)
  name.gsub(/[^a-zA-Z0-9_]/) { |c| format("_%02x", c.ord) }
end
expanded_switches(option) click to toggle source

Return switches with –[no-]foo expanded to –foo and –no-foo.

# File lib/clamp/completion.rb, line 50
def expanded_switches(option)
  option.switches.flat_map do |switch|
    if switch =~ /^--\[no-\](.*)/
      ["--#{Regexp.last_match(1)}", "--no-#{Regexp.last_match(1)}"]
    else
      switch
    end
  end
end
generate(command_class, shell, executable_name) click to toggle source
# File lib/clamp/completion.rb, line 42
def generate(command_class, shell, executable_name)
  generator_class = GENERATORS.fetch(shell) do
    raise ArgumentError, "unsupported shell: #{shell.inspect}"
  end
  generator_class.new(command_class, executable_name).generate
end
required_parameter_count(command_class) click to toggle source

Count required, non-multivalued parameters for a command.

# File lib/clamp/completion.rb, line 81
def required_parameter_count(command_class)
  command_class.parameters.count { |p| p.required? && !p.multivalued? }
end
visible_options(command_class) click to toggle source

Options visible in completion (excludes hidden).

# File lib/clamp/completion.rb, line 61
def visible_options(command_class)
  command_class.recognised_options.reject(&:hidden?)
end
walk_command_tree(command_class, path = [], visited = Set.new) { |command_class, path, has_children| ... } click to toggle source

Walk the command tree depth-first, yielding (command_class, path, has_children). Path is an array of Subcommand::Definition objects. Always yields, even for revisited classes (with has_children=false).

# File lib/clamp/completion.rb, line 68
def walk_command_tree(command_class, path = [], visited = Set.new, &block)
  fresh = !visited.include?(command_class)
  visited |= [command_class]
  has_children = command_class.has_subcommands? && fresh
  yield command_class, path, has_children
  return unless has_children

  command_class.recognised_subcommands.each do |sub|
    walk_command_tree(sub.subcommand_class, path + [sub], visited, &block)
  end
end