Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions autocomplete/fish_autocomplete
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# This is a shell completion script auto-generated by https://github.com/urfave/cli for fish.

function __%[1]_perform_completion
# Extract all args except the last one
set -l args (commandline -opc)
# Extract the last arg (partial input)
set -l lastArg (commandline -ct)

set -l results ($args[1] $args[2..-1] $lastArg --generate-shell-completion 2> /dev/null)

# Remove trailing empty lines
for line in $results[-1..1]
if test (string trim -- $line) = ""
set results $results[1..-2]
else
break
end
end

for line in $results
if not string match -q -- "%[1]*" $line
set -l parts (string split -m 1 ":" -- "$line")
if test (count $parts) -eq 2
printf "%s\t%s\n" "$parts[1]" "$parts[2]"
else
printf "%s\n" "$line"
end
end
end
end

# Clear existing completions for %[1]
complete -c %[1] -e
# Register completion function
complete -c %[1] -f -a '(__%[1]_perform_completion)'
3 changes: 2 additions & 1 deletion completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ var (
return fmt.Sprintf(string(b), appName), err
},
"fish": func(c *Command, appName string) (string, error) {
return c.Root().ToFishCompletion()
b, err := autoCompleteFS.ReadFile("autocomplete/fish_autocomplete")
return fmt.Sprintf(string(b), appName), err
},
"pwsh": func(c *Command, appName string) (string, error) {
b, err := autoCompleteFS.ReadFile("autocomplete/powershell_autocomplete.ps1")
Expand Down
37 changes: 37 additions & 0 deletions examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,43 @@ func ExampleCommand_Run_shellComplete_zsh() {
// help:Shows a list of commands or help for one command
}

func ExampleCommand_Run_shellComplete_fish() {
cmd := &cli.Command{
Name: "greet",
EnableShellCompletion: true,
Commands: []*cli.Command{
{
Name: "describeit",
Aliases: []string{"d"},
Usage: "use it to see a description",
Description: "This is how we describe describeit the function",
Action: func(context.Context, *cli.Command) error {
fmt.Printf("i like to describe things")
return nil
},
}, {
Name: "next",
Usage: "next example",
Description: "more stuff to see when generating bash completion",
Action: func(context.Context, *cli.Command) error {
fmt.Printf("the next example")
return nil
},
},
},
}

// Simulate a fish environment and command line arguments
os.Args = []string{"greet", "--generate-shell-completion"}
os.Setenv("SHELL", "/usr/bin/fish")

_ = cmd.Run(context.Background(), os.Args)
// Output:
// describeit:use it to see a description
// next:next example
// help:Shows a list of commands or help for one command
}

func ExampleCommand_Run_sliceValues() {
cmd := &cli.Command{
Name: "multi_values",
Expand Down
6 changes: 4 additions & 2 deletions help.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,12 @@ func DefaultRootCommandComplete(ctx context.Context, cmd *Command) {
var DefaultAppComplete = DefaultRootCommandComplete

func printCommandSuggestions(commands []*Command, writer io.Writer) {
shell := os.Getenv("SHELL")
for _, command := range commands {
if command.Hidden {
continue
}
if strings.HasSuffix(os.Getenv("SHELL"), "zsh") && len(command.Usage) > 0 {
if (strings.HasSuffix(shell, "zsh") || strings.HasSuffix(shell, "fish")) && len(command.Usage) > 0 {
_, _ = fmt.Fprintf(writer, "%s:%s\n", command.Name, command.Usage)
} else {
_, _ = fmt.Fprintf(writer, "%s\n", command.Name)
Expand Down Expand Up @@ -240,7 +241,8 @@ func printFlagSuggestions(lastArg string, flags []Flag, writer io.Writer) {
// match if last argument matches this flag and it is not repeated
if strings.HasPrefix(name, cur) && cur != name /* && !cliArgContains(name, os.Args)*/ {
flagCompletion := fmt.Sprintf("%s%s", strings.Repeat("-", count), name)
if usage != "" && strings.HasSuffix(os.Getenv("SHELL"), "zsh") {
shell := os.Getenv("SHELL")
if usage != "" && (strings.HasSuffix(shell, "zsh") || strings.HasSuffix(shell, "fish")) {
flagCompletion = fmt.Sprintf("%s:%s", flagCompletion, usage)
}
fmt.Fprintln(writer, flagCompletion)
Expand Down