Module: Simple::CLI::Runner::Autocompletion

Included in:
Simple::CLI::Runner
Defined in:
lib/simple/cli/runner/autocompletion.rb

Constant Summary collapse

CommandHelp =
Simple::CLI::Runner::CommandHelp
DEFAULT_OPTIONS =
%w(--verbose -v --quiet -q)
AUTOCOMPLETE_SHELL_CODE =

The shell function function is executed in the current shell environment. When it is executed,

  • $1 is the name of the command whose arguments are being completed,

  • $2 is the word being completed, and

  • $3 is the word preceding the word being completed

When it finishes, the possible completions are retrieved from the value of the COMPREPLY array variable.

see www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html

<<~BASH
  _{{BINARY}}()
  {
    local cmd=$1
    local cur=$2

    if [[ $COMP_CWORD == 1 ]]; then
      COMPREPLY=( $("$cmd" autocomplete "$cur" ))
    else
      local subcommand=${COMP_WORDS[1]}
      COMPREPLY=( $("$cmd" autocomplete "$subcommand" "$cur" ))
    fi

    return 0
  }
  complete -F _{{BINARY}} {{BINARY}}
BASH

Instance Method Summary collapse

Instance Method Details

#autocomplete(subcommand = nil, cur = nil) ⇒ Object



4
5
6
# File 'lib/simple/cli/runner/autocompletion.rb', line 4

def autocomplete(subcommand = nil, cur = nil)
  puts completions(subcommand, cur).join("\n")
end

#autocomplete_bashObject



59
60
61
# File 'lib/simple/cli/runner/autocompletion.rb', line 59

def autocomplete_bash
  puts AUTOCOMPLETE_SHELL_CODE.gsub(/{{BINARY}}/, binary_name)
end

#autocomplete_helpObject



49
50
51
52
53
54
55
56
57
# File 'lib/simple/cli/runner/autocompletion.rb', line 49

def autocomplete_help
  STDERR.puts <<~DOC
    #{binary_name} supports autocompletion. To enable autocompletion please run

        eval "$(#{$0} autocomplete:bash)"
  DOC

  exit 1
end

#autocomplete_subcommand_options(subcommand, cur) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/simple/cli/runner/autocompletion.rb', line 35

def autocomplete_subcommand_options(subcommand, cur)
  if subcommand == "help"
    completions = commands.map(&:to_s).map { |s| s.tr("_", ":") } + ["autocomplete"]
    filter_completions completions, prefix: cur
  elsif cur && cur[0, 1] == "-"
    completions = CommandHelp.option_names(@app, string_to_command(subcommand))
    completions += DEFAULT_OPTIONS

    filter_completions completions, prefix: cur
  else
    Dir.glob "#{cur}*"
  end
end

#autocomplete_subcommands(cur) ⇒ Object



22
23
24
25
26
27
28
29
30
31
# File 'lib/simple/cli/runner/autocompletion.rb', line 22

def autocomplete_subcommands(cur)
  commands = self.commands.map { |cmd| cmd.to_s.tr("_", ":") }
  commands << "help"
  completions = filter_completions commands, prefix: cur
  if completions == [cur]
    autocomplete_subcommand_options(cur, nil)
  else
    completions
  end
end

#completions(subcommand = nil, cur = nil) ⇒ Object



8
9
10
11
12
13
14
# File 'lib/simple/cli/runner/autocompletion.rb', line 8

def completions(subcommand = nil, cur = nil)
  if !cur
    autocomplete_subcommands(subcommand)
  else
    autocomplete_subcommand_options(subcommand, cur)
  end
end

#filter_completions(completions, prefix:) ⇒ Object



16
17
18
19
20
# File 'lib/simple/cli/runner/autocompletion.rb', line 16

def filter_completions(completions, prefix:)
  completions.select do |completion|
    !prefix || completion.start_with?(prefix)
  end
end