Module: SmilyCli::Completion

Defined in:
lib/smily_cli/completion.rb

Overview

Generates shell completion scripts. The scripts are static (they embed the known resource and command names at generation time) which keeps completion instant — no subshell to the CLI on every .

Constant Summary collapse

SHELLS =
%w[bash zsh fish].freeze
RESOURCE_ACTIONS =

Subcommands shared by every resource.

%w[list get create update delete].freeze

Class Method Summary collapse

Class Method Details

.bashObject



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/smily_cli/completion.rb', line 32

def bash
  <<~BASH
    # smily bash completion. Install with:
    #   smily completion bash > /usr/local/etc/bash_completion.d/smily
    _smily() {
      local cur prev words cword
      _init_completion 2>/dev/null || { cur="${COMP_WORDS[COMP_CWORD]}"; prev="${COMP_WORDS[COMP_CWORD-1]}"; }
      local top="#{top_level.join(' ')}"
      local actions="#{RESOURCE_ACTIONS.join(' ')}"
      if [ "$COMP_CWORD" -eq 1 ]; then
        COMPREPLY=( $(compgen -W "$top" -- "$cur") )
      elif [ "$COMP_CWORD" -eq 2 ]; then
        COMPREPLY=( $(compgen -W "$actions" -- "$cur") )
      fi
      return 0
    }
    complete -F _smily smily
  BASH
end

.fishObject



71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/smily_cli/completion.rb', line 71

def fish
  lines = []
  lines << "# smily fish completion. Install with:"
  lines << "#   smily completion fish > ~/.config/fish/completions/smily.fish"
  lines << "complete -c smily -f"
  top_level.each do |cmd|
    lines << "complete -c smily -n '__fish_use_subcommand' -a '#{cmd}'"
  end
  RESOURCE_ACTIONS.each do |action|
    lines << "complete -c smily -n '__fish_seen_subcommand_from #{Registry.commands.join(' ')}' -a '#{action}'"
  end
  "#{lines.join("\n")}\n"
end

.script(shell) ⇒ String

Returns the completion script.

Parameters:

  • shell (String)

    one of SHELLS

Returns:

  • (String)

    the completion script

Raises:



17
18
19
20
21
22
23
24
25
# File 'lib/smily_cli/completion.rb', line 17

def script(shell)
  case shell.to_s
  when "bash" then bash
  when "zsh"  then zsh
  when "fish" then fish
  else
    raise UsageError, "Unsupported shell #{shell.inspect}. Supported: #{SHELLS.join(', ')}."
  end
end

.top_levelArray<String>

Returns every top-level command word.

Returns:

  • (Array<String>)

    every top-level command word



28
29
30
# File 'lib/smily_cli/completion.rb', line 28

def top_level
  (Registry.commands + %w[api auth config resources whoami completion version help]).uniq.sort
end

.zshObject



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/smily_cli/completion.rb', line 52

def zsh
  <<~ZSH
    #compdef smily
    # smily zsh completion. Install by placing on your $fpath as _smily, e.g.:
    #   smily completion zsh > "${fpath[1]}/_smily"
    _smily() {
      local -a top actions
      top=(#{top_level.map { |c| "'#{c}'" }.join(' ')})
      actions=(#{RESOURCE_ACTIONS.map { |c| "'#{c}'" }.join(' ')})
      if (( CURRENT == 2 )); then
        compadd -- $top
      elif (( CURRENT == 3 )); then
        compadd -- $actions
      fi
    }
    compdef _smily smily
  ZSH
end