completions: generate fish completions
This commit is contained in:
		
							parent
							
								
									5f5930255e
								
							
						
					
					
						commit
						541a981d37
					
				@ -52,6 +52,19 @@ module Homebrew
 | 
			
		||||
      file:              "__brew_formulae_or_ruby_files",
 | 
			
		||||
    }.freeze
 | 
			
		||||
 | 
			
		||||
    FISH_NAMED_ARGS_COMPLETION_FUNCTION_MAPPING = {
 | 
			
		||||
      formula:           "__fish_brew_suggest_formulae_all",
 | 
			
		||||
      installed_formula: "__fish_brew_suggest_formulae_installed",
 | 
			
		||||
      outdated_formula:  "__fish_brew_suggest_formulae_outdated",
 | 
			
		||||
      cask:              "__fish_brew_suggest_casks_all",
 | 
			
		||||
      installed_cask:    "__fish_brew_suggest_casks_installed",
 | 
			
		||||
      outdated_cask:     "__fish_brew_suggest_casks_outdated",
 | 
			
		||||
      tap:               "__fish_brew_suggest_taps_installed",
 | 
			
		||||
      installed_tap:     "__fish_brew_suggest_taps_installed",
 | 
			
		||||
      command:           "__fish_brew_suggest_commands",
 | 
			
		||||
      diagnostic_check:  "__fish_brew_suggest_diagnostic_checks",
 | 
			
		||||
    }.freeze
 | 
			
		||||
 | 
			
		||||
    sig { void }
 | 
			
		||||
    def link!
 | 
			
		||||
      Settings.write :linkcompletions, true
 | 
			
		||||
@ -111,6 +124,7 @@ module Homebrew
 | 
			
		||||
 | 
			
		||||
      (COMPLETIONS_DIR/"bash/brew").atomic_write generate_bash_completion_file(commands)
 | 
			
		||||
      (COMPLETIONS_DIR/"zsh/_brew").atomic_write generate_zsh_completion_file(commands)
 | 
			
		||||
      (COMPLETIONS_DIR/"fish/brew.fish").atomic_write generate_fish_completion_file(commands)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sig { params(command: String).returns(T::Boolean) }
 | 
			
		||||
@ -120,9 +134,14 @@ module Homebrew
 | 
			
		||||
      command_options(command).any?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sig { params(description: String).returns(String) }
 | 
			
		||||
    def format_description(description)
 | 
			
		||||
      description.gsub("'", "'\\\\''").gsub(/[<>]/, "").tr("\n", " ").chomp(".")
 | 
			
		||||
    sig { params(description: String, fish: T::Boolean).returns(String) }
 | 
			
		||||
    def format_description(description, fish: false)
 | 
			
		||||
      description = if fish
 | 
			
		||||
        description.gsub("'", "\\\\'")
 | 
			
		||||
      else
 | 
			
		||||
        description.gsub("'", "'\\\\''")
 | 
			
		||||
      end
 | 
			
		||||
      description.gsub(/[<>]/, "").tr("\n", " ").chomp(".")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sig { params(command: String).returns(T::Hash[String, String]) }
 | 
			
		||||
@ -248,5 +267,52 @@ module Homebrew
 | 
			
		||||
 | 
			
		||||
      ERB.new((TEMPLATE_DIR/"zsh.erb").read, trim_mode: ">").result(variables.instance_eval { binding })
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sig { params(command: String).returns(T.nilable(String)) }
 | 
			
		||||
    def generate_fish_subcommand_completion(command)
 | 
			
		||||
      return unless command_gets_completions? command
 | 
			
		||||
 | 
			
		||||
      command_description = format_description Commands.command_description(command, short: true), fish: true
 | 
			
		||||
      lines = ["__fish_brew_complete_cmd '#{command}' '#{command_description}'"]
 | 
			
		||||
 | 
			
		||||
      options = command_options(command).sort.map do |opt, desc|
 | 
			
		||||
        arg_line = "__fish_brew_complete_arg '#{command}' -l #{opt.sub(/^-+/, "")}"
 | 
			
		||||
        arg_line += " -d '#{format_description desc, fish: true}'" if desc.present?
 | 
			
		||||
        arg_line
 | 
			
		||||
      end.compact
 | 
			
		||||
 | 
			
		||||
      subcommands = []
 | 
			
		||||
      named_args = []
 | 
			
		||||
      if types = Commands.named_args_type(command)
 | 
			
		||||
        named_args_strings, named_args_types = types.partition { |type| type.is_a? String }
 | 
			
		||||
 | 
			
		||||
        named_args_types.each do |type|
 | 
			
		||||
          next unless FISH_NAMED_ARGS_COMPLETION_FUNCTION_MAPPING.key? type
 | 
			
		||||
 | 
			
		||||
          named_arg_function = FISH_NAMED_ARGS_COMPLETION_FUNCTION_MAPPING[type]
 | 
			
		||||
          named_args << "__fish_brew_complete_arg '#{command}' -a '(#{named_arg_function})'"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        named_args_strings.each do |subcommand|
 | 
			
		||||
          subcommands << "__fish_brew_complete_sub_cmd '#{command}' '#{subcommand}'"
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      lines += subcommands + options + named_args
 | 
			
		||||
      <<~COMPLETION
 | 
			
		||||
        #{lines.join("\n").chomp}
 | 
			
		||||
      COMPLETION
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sig { params(commands: T::Array[String]).returns(String) }
 | 
			
		||||
    def generate_fish_completion_file(commands)
 | 
			
		||||
      variables = OpenStruct.new
 | 
			
		||||
 | 
			
		||||
      variables[:completion_functions] = commands.map do |command|
 | 
			
		||||
        generate_fish_subcommand_completion command
 | 
			
		||||
      end.compact
 | 
			
		||||
 | 
			
		||||
      ERB.new((TEMPLATE_DIR/"fish.erb").read, trim_mode: ">").result(variables.instance_eval { binding })
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										268
									
								
								Library/Homebrew/completions/fish.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										268
									
								
								Library/Homebrew/completions/fish.erb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,268 @@
 | 
			
		||||
<%
 | 
			
		||||
# To make changes to the completions:
 | 
			
		||||
#
 | 
			
		||||
# - For changes to a command under `COMMANDS` or `DEVELOPER COMMANDS` sections):
 | 
			
		||||
#   - Find the source file in `Library/Homebrew/[dev-]cmd/<command>.{rb,sh}`.
 | 
			
		||||
#   - For `.rb` files, edit the `<command>_args` method.
 | 
			
		||||
#   - For `.sh` files, edit the top comment, being sure to use the line prefix
 | 
			
		||||
#     `#:` for the comments to be recognized as documentation. If in doubt,
 | 
			
		||||
#     compare with already documented commands.
 | 
			
		||||
# - For other changes: Edit this file.
 | 
			
		||||
#
 | 
			
		||||
# When done, regenerate the completions by running `brew man`.
 | 
			
		||||
%>
 | 
			
		||||
# Fish shell completions for Homebrew
 | 
			
		||||
 | 
			
		||||
# A note about aliases:
 | 
			
		||||
#
 | 
			
		||||
# * When defining completions for the (sub)commands themselves, only the full names are used, as they
 | 
			
		||||
#   are more descriptive and worth completing. Aliases are usually shorter than the full names, and
 | 
			
		||||
#   exist exactly to save time for users who already know what they want and are going to type the
 | 
			
		||||
#   command anyway (i.e. without completion).
 | 
			
		||||
# * Nevertheless, it's important to support aliases in the completions for their arguments/options.
 | 
			
		||||
 | 
			
		||||
##########################
 | 
			
		||||
## COMMAND LINE PARSING ##
 | 
			
		||||
##########################
 | 
			
		||||
 | 
			
		||||
function __fish_brew_args -d "Returns a list of all arguments given to brew"
 | 
			
		||||
 | 
			
		||||
    set -l tokens (commandline -opc)
 | 
			
		||||
    set -e tokens[1] # remove 'brew'
 | 
			
		||||
    for t in $tokens
 | 
			
		||||
        echo $t
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function __fish_brew_opts -d "Only arguments starting with a dash (options)"
 | 
			
		||||
    string match --all -- '-*' (__fish_brew_args)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
# This can be used either to get the first argument or to match it against a given list of commands
 | 
			
		||||
#
 | 
			
		||||
# Usage examples (for `completion -n '...'`):
 | 
			
		||||
# * `__fish_brew_command` returns the command (first arg of brew) or exits with 1
 | 
			
		||||
# * `not __fish_brew_command` returns true when brew doesn't have a command yet
 | 
			
		||||
# * `__fish_brew_command list ls` returns true when brew command is _either_ `list` _or_ `ls`
 | 
			
		||||
#
 | 
			
		||||
function __fish_brew_command -d "Helps matching the first argument of brew"
 | 
			
		||||
    set args (__fish_brew_args)
 | 
			
		||||
    set -q args[1]; or return 1
 | 
			
		||||
 | 
			
		||||
    if count $argv
 | 
			
		||||
        contains -- $args[1] $argv
 | 
			
		||||
    else
 | 
			
		||||
        echo $args[1]
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function __fish_brew_subcommand -a cmd -d "Helps matching the second argument of brew"
 | 
			
		||||
    set args (__fish_brew_args)
 | 
			
		||||
 | 
			
		||||
    __fish_brew_command $cmd
 | 
			
		||||
    and set -q args[2]
 | 
			
		||||
    and set -l sub $args[2]
 | 
			
		||||
    or return 1
 | 
			
		||||
 | 
			
		||||
    set -e argv[1]
 | 
			
		||||
    if count $argv
 | 
			
		||||
        contains -- $sub $argv
 | 
			
		||||
    else
 | 
			
		||||
        echo $sub
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
# This can be used to match any given option against the given list of arguments:
 | 
			
		||||
# * to add condition on interdependent options
 | 
			
		||||
# * to ddd condition on mutually exclusive options
 | 
			
		||||
#
 | 
			
		||||
# Usage examples (for `completion -n '...'`):
 | 
			
		||||
# * `__fish_brew_opt -s --long` returns true if _either_ `-s` _or_ `--long` is present
 | 
			
		||||
# * `not __fish_brew_opt --foo --bar` will work only if _neither_ `--foo` _nor_ `--bar` are present
 | 
			
		||||
#
 | 
			
		||||
function __fish_brew_opt -d "Helps matching brew options against the given list"
 | 
			
		||||
 | 
			
		||||
    not count $argv
 | 
			
		||||
    or contains -- $argv[1] (__fish_brew_opts)
 | 
			
		||||
    or begin
 | 
			
		||||
        set -q argv[2]
 | 
			
		||||
        and __fish_brew_opt $argv[2..-1]
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
######################
 | 
			
		||||
## SUGGESTION LISTS ##
 | 
			
		||||
######################
 | 
			
		||||
# These functions return lists of suggestions for arguments completion
 | 
			
		||||
 | 
			
		||||
function __fish_brew_ruby_parse_json -a file parser -d 'Parses given JSON file with Ruby'
 | 
			
		||||
    # parser is any chain of methods to call on the parsed JSON
 | 
			
		||||
    ruby -e "require('json'); JSON.parse(File.read('$file'))$parser"
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function __fish_brew_suggest_formulae_all -d 'Lists all available formulae with their descriptions'
 | 
			
		||||
    # store the brew cache path in a var (because calling (brew --cache) is slow)
 | 
			
		||||
    set -q __brew_cache_path
 | 
			
		||||
    or set -gx __brew_cache_path (brew --cache)
 | 
			
		||||
 | 
			
		||||
    if test -f "$__brew_cache_path/descriptions.json"
 | 
			
		||||
        __fish_brew_ruby_parse_json "$__brew_cache_path/descriptions.json" \
 | 
			
		||||
            '.each{ |k, v| puts([k, v].reject(&:nil?).join("\t")) }'
 | 
			
		||||
    else
 | 
			
		||||
        brew formulae
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function __fish_brew_suggest_formulae_installed
 | 
			
		||||
    brew list --formula
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function __fish_brew_suggest_formulae_outdated -d "List of outdated formulae with the information about potential upgrade"
 | 
			
		||||
    brew outdated --verbose \
 | 
			
		||||
        # replace first space with tab to make the following a description in the completions list:
 | 
			
		||||
        | string replace -r '\s' '\t'
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function __fish_brew_suggest_formula_options -a formula -d "List installation options for a given formula"
 | 
			
		||||
    function list_pairs
 | 
			
		||||
        set -q argv[2]; or return 0
 | 
			
		||||
        echo $argv[1]\t$argv[2]
 | 
			
		||||
        set -e argv[1..2]
 | 
			
		||||
        list_pairs $argv
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # brew options lists options name and its description on different lines
 | 
			
		||||
    list_pairs (brew options $formula | string trim)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function __fish_brew_suggest_casks_all -d "Lists locally available casks"
 | 
			
		||||
    brew casks
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function __fish_brew_suggest_casks_installed -d "Lists installed casks"
 | 
			
		||||
    brew list --cask -1
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function __fish_brew_suggest_casks_outdated -d "Lists outdated casks with the information about potential upgrade"
 | 
			
		||||
    brew cask outdated --verbose \
 | 
			
		||||
        # replace first space with tab to make the following a description in the completions list:
 | 
			
		||||
        | string replace -r '\s' '\t'
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function __fish_brew_suggest_taps_installed -d "List all available taps"
 | 
			
		||||
    brew tap
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function __fish_brew_suggest_commands -d "Lists all commands names, including aliases"
 | 
			
		||||
    if test -f (brew --cache)/all_commands_list.txt
 | 
			
		||||
        cat (brew --cache)/all_commands_list.txt | \grep -v instal\$
 | 
			
		||||
    else
 | 
			
		||||
        cat (brew --repo)/completions/internal_commands_list.txt | \grep -v instal\$
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function __fish_brew_suggest_diagnostic_check -d "List available diagnostic checks"
 | 
			
		||||
    brew doctor --list-checks
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
# TODO: any better way to list available services?
 | 
			
		||||
function __fish_brew_suggest_services -d "Lists available services"
 | 
			
		||||
    set -l list (brew services list)
 | 
			
		||||
    set -e list[1] # Header
 | 
			
		||||
    for line in $list
 | 
			
		||||
        echo (string split ' ' $line)[1]
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##########################
 | 
			
		||||
## COMPLETION SHORTCUTS ##
 | 
			
		||||
##########################
 | 
			
		||||
 | 
			
		||||
function __fish_brew_complete_cmd -a cmd -d "A shortcut for defining brew commands completions"
 | 
			
		||||
    set -e argv[1]
 | 
			
		||||
    complete -f -c brew -n 'not __fish_brew_command' -a $cmd -d $argv
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function __fish_brew_complete_arg -a cond -d "A shortcut for defining arguments completion for brew commands"
 | 
			
		||||
    set -e argv[1]
 | 
			
		||||
    # NOTE: $cond can be just a name of a command (or several) or additionally any other condition
 | 
			
		||||
    complete -f -c brew -n "__fish_brew_command $cond" $argv
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function __fish_brew_complete_sub_cmd -a cmd sub -d "A shortcut for defining brew subcommands completions"
 | 
			
		||||
    set -e argv[1..2]
 | 
			
		||||
    if count $argv > /dev/null
 | 
			
		||||
        __fish_brew_complete_arg "$cmd; and [ (count (__fish_brew_args)) = 1 ]" -a $sub -d $argv
 | 
			
		||||
    else
 | 
			
		||||
        __fish_brew_complete_arg "$cmd; and [ (count (__fish_brew_args)) = 1 ]" -a $sub
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function __fish_brew_complete_sub_arg -a cmd sub -d "A shortcut for defining brew subcommand arguments completions"
 | 
			
		||||
    set -e argv[1..2]
 | 
			
		||||
    # NOTE: $sub can be just a name of a subcommand (or several) or additionally any other condition
 | 
			
		||||
    complete -f -c brew -n "__fish_brew_subcommand $cmd $sub" $argv
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##############
 | 
			
		||||
## COMMANDS ##
 | 
			
		||||
##############
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<%= completion_functions.join("\n\n") %>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
################################
 | 
			
		||||
## OFFICIAL EXTERNAL COMMANDS ##
 | 
			
		||||
################################
 | 
			
		||||
# TODO: These commands are installed/tapped separately, so they should be completed only when present
 | 
			
		||||
 | 
			
		||||
##############
 | 
			
		||||
### BUNDLE ###
 | 
			
		||||
 | 
			
		||||
__fish_brew_complete_cmd 'bundle' "Install or upgrade all dependencies in a Brewfile"
 | 
			
		||||
__fish_brew_complete_arg 'bundle; and [ (count (__fish_brew_args)) = 1 ]' -s v -l verbose -d "Print more details"
 | 
			
		||||
 | 
			
		||||
# --file/--global option is available for bundle command and all its subcommands except exec
 | 
			
		||||
__fish_brew_complete_arg 'bundle;
 | 
			
		||||
        and not __fish_brew_subcommand bundle exec;
 | 
			
		||||
        and not __fish_brew_opt --file --global
 | 
			
		||||
    ' -l file -r -d "Specify Brewfile"
 | 
			
		||||
__fish_brew_complete_arg 'bundle;
 | 
			
		||||
        and not __fish_brew_subcommand bundle exec;
 | 
			
		||||
        and not __fish_brew_opt --file --global
 | 
			
		||||
    ' -l global  -d "Use \$HOME/.Brewfile"
 | 
			
		||||
 | 
			
		||||
__fish_brew_complete_sub_cmd 'bundle' 'dump'    "Write all installed casks/formulae/taps into a Brewfile"
 | 
			
		||||
__fish_brew_complete_sub_cmd 'bundle' 'cleanup' "Uninstall all dependencies not listed in a Brewfile"
 | 
			
		||||
__fish_brew_complete_sub_cmd 'bundle' 'check'   "Check if all dependencies are installed in a Brewfile"
 | 
			
		||||
__fish_brew_complete_sub_cmd 'bundle' 'exec'    "Run an external command in an isolated build environment"
 | 
			
		||||
 | 
			
		||||
# --force is available only for the dump/cleanup subcommands
 | 
			
		||||
__fish_brew_complete_sub_arg 'bundle' 'dump cleanup' -l force -d "Uninstall dependencies or overwrite an existing Brewfile"
 | 
			
		||||
 | 
			
		||||
# --no-upgrade is available for bundle command and its check subcommand
 | 
			
		||||
__fish_brew_complete_arg 'bundle; and [ (count (__fish_brew_args)) = 1 ];
 | 
			
		||||
        or __fish_brew_subcommand bundle check
 | 
			
		||||
    ' -l no-upgrade -d "Don't run brew upgrade for outdated dependencies"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
################
 | 
			
		||||
### SERVICES ###
 | 
			
		||||
 | 
			
		||||
__fish_brew_complete_cmd 'services' "Integrates Homebrew formulae with macOS's launchctl manager"
 | 
			
		||||
__fish_brew_complete_arg 'services; and [ (count (__fish_brew_args)) = 1 ]' -s v -l verbose -d "Print more details"
 | 
			
		||||
 | 
			
		||||
__fish_brew_complete_sub_cmd 'services' 'list'    "List all running services for the current user"
 | 
			
		||||
__fish_brew_complete_sub_cmd 'services' 'run'     "Run service without starting at login/boot"
 | 
			
		||||
__fish_brew_complete_sub_cmd 'services' 'start'   "Start service immediately and register it to launch at login/boot"
 | 
			
		||||
__fish_brew_complete_sub_cmd 'services' 'stop'    "Stop service immediately and unregister it from launching at login/boot"
 | 
			
		||||
__fish_brew_complete_sub_cmd 'services' 'restart' "Stop and start service immediately and register it to launch at login/boot"
 | 
			
		||||
__fish_brew_complete_sub_cmd 'services' 'cleanup' "Remove all unused services"
 | 
			
		||||
 | 
			
		||||
__fish_brew_complete_sub_arg 'services' 'run start stop restart' -l all -d "Run all available services"
 | 
			
		||||
__fish_brew_complete_sub_arg 'services' 'run start stop restart' -a '(__fish_brew_suggest_services)'
 | 
			
		||||
@ -158,6 +158,10 @@ describe Homebrew::Completions do
 | 
			
		||||
        expect(described_class.format_description("Homebrew's")).to eq "Homebrew'\\''s"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "escapes single quotes for fish" do
 | 
			
		||||
        expect(described_class.format_description("Homebrew's", fish: true)).to eq "Homebrew\\'s"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "removes angle brackets" do
 | 
			
		||||
        expect(described_class.format_description("<formula>")).to eq "formula"
 | 
			
		||||
      end
 | 
			
		||||
@ -361,5 +365,55 @@ describe Homebrew::Completions do
 | 
			
		||||
        expect(file).to match(/^_brew "\$@"$/)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe ".generate_fish_subcommand_completion" do
 | 
			
		||||
      it "returns nil if completions aren't needed" do
 | 
			
		||||
        expect(described_class.generate_fish_subcommand_completion("help")).to be_nil
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "returns appropriate completion for a ruby command" do
 | 
			
		||||
        completion = described_class.generate_fish_subcommand_completion("missing")
 | 
			
		||||
        expect(completion).to eq <<~COMPLETION
 | 
			
		||||
          __fish_brew_complete_cmd 'missing' 'Check the given formula kegs for missing dependencies'
 | 
			
		||||
          __fish_brew_complete_arg 'missing' -l debug -d 'Display any debugging information'
 | 
			
		||||
          __fish_brew_complete_arg 'missing' -l help -d 'Show this message'
 | 
			
		||||
          __fish_brew_complete_arg 'missing' -l hide -d 'Act as if none of the specified hidden are installed. hidden should be a comma-separated list of formulae'
 | 
			
		||||
          __fish_brew_complete_arg 'missing' -l quiet -d 'Make some output more quiet'
 | 
			
		||||
          __fish_brew_complete_arg 'missing' -l verbose -d 'Make some output more verbose'
 | 
			
		||||
          __fish_brew_complete_arg 'missing' -a '(__fish_brew_suggest_formulae_all)'
 | 
			
		||||
        COMPLETION
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "returns appropriate completion for a shell command" do
 | 
			
		||||
        completion = described_class.generate_fish_subcommand_completion("update")
 | 
			
		||||
        expect(completion).to eq <<~COMPLETION
 | 
			
		||||
          __fish_brew_complete_cmd 'update' 'Fetch the newest version of Homebrew and all formulae from GitHub using `git`(1) and perform any necessary migrations'
 | 
			
		||||
          __fish_brew_complete_arg 'update' -l debug -d 'Display a trace of all shell commands as they are executed'
 | 
			
		||||
          __fish_brew_complete_arg 'update' -l force -d 'Always do a slower, full update check (even if unnecessary)'
 | 
			
		||||
          __fish_brew_complete_arg 'update' -l help -d 'Show this message'
 | 
			
		||||
          __fish_brew_complete_arg 'update' -l merge -d 'Use `git merge` to apply updates (rather than `git rebase`)'
 | 
			
		||||
          __fish_brew_complete_arg 'update' -l preinstall -d 'Run on auto-updates (e.g. before `brew install`). Skips some slower steps'
 | 
			
		||||
          __fish_brew_complete_arg 'update' -l verbose -d 'Print the directories checked and `git` operations performed'
 | 
			
		||||
        COMPLETION
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "returns appropriate completion for a command with multiple named arg types" do
 | 
			
		||||
        completion = described_class.generate_fish_subcommand_completion("upgrade")
 | 
			
		||||
        expect(completion).to match(
 | 
			
		||||
          /__fish_brew_complete_arg 'upgrade' -a '\(__fish_brew_suggest_formulae_outdated\)'/,
 | 
			
		||||
        )
 | 
			
		||||
        expect(completion).to match(/__fish_brew_complete_arg 'upgrade' -a '\(__fish_brew_suggest_casks_outdated\)'/)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe ".generate_fish_completion_file" do
 | 
			
		||||
      it "returns the correct completion file" do
 | 
			
		||||
        file = described_class.generate_fish_completion_file(%w[install missing update])
 | 
			
		||||
        expect(file).to match(/^function __fish_brew_complete_cmd/)
 | 
			
		||||
        expect(file).to match(/^__fish_brew_complete_cmd 'install' 'Install a formula or cask'$/)
 | 
			
		||||
        expect(file).to match(/^__fish_brew_complete_cmd 'missing' 'Check the given formula kegs for .*'$/)
 | 
			
		||||
        expect(file).to match(/^__fish_brew_complete_cmd 'update' 'Fetch the newest version of Homebrew .*'$/)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user