Skip to content

Commit

Permalink
Fish does not accept - or : in vars
Browse files Browse the repository at this point in the history
Fixes #1121.
This is for programs that may contain a : or - in their name.

Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>
  • Loading branch information
marckhouzam committed May 22, 2020
1 parent 94a87a7 commit 60f26e0
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 41 deletions.
33 changes: 0 additions & 33 deletions custom_completions_test.go
Expand Up @@ -307,39 +307,6 @@ func TestCompleteCmdInBashScript(t *testing.T) {
check(t, output, ShellCompNoDescRequestCmd)
}

func TestCompleteNoDesCmdInFishScript(t *testing.T) {
rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun}
child := &Command{
Use: "child",
ValidArgsFunction: validArgsFunc,
Run: emptyRun,
}
rootCmd.AddCommand(child)

buf := new(bytes.Buffer)
rootCmd.GenFishCompletion(buf, false)
output := buf.String()

check(t, output, ShellCompNoDescRequestCmd)
}

func TestCompleteCmdInFishScript(t *testing.T) {
rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun}
child := &Command{
Use: "child",
ValidArgsFunction: validArgsFunc,
Run: emptyRun,
}
rootCmd.AddCommand(child)

buf := new(bytes.Buffer)
rootCmd.GenFishCompletion(buf, true)
output := buf.String()

check(t, output, ShellCompRequestCmd)
checkOmit(t, output, ShellCompNoDescRequestCmd)
}

func TestFlagCompletionInGo(t *testing.T) {
rootCmd := &Command{
Use: "root",
Expand Down
22 changes: 14 additions & 8 deletions fish_completions.go
Expand Up @@ -5,9 +5,15 @@ import (
"fmt"
"io"
"os"
"strings"
)

func genFishComp(buf *bytes.Buffer, name string, includeDesc bool) {
// Variables should not contain a '-' or ':' character
nameForVar := name
nameForVar = strings.Replace(nameForVar, "-", "_", -1)
nameForVar = strings.Replace(nameForVar, ":", "_", -1)

compCmd := ShellCompRequestCmd
if !includeDesc {
compCmd = ShellCompNoDescRequestCmd
Expand Down Expand Up @@ -37,7 +43,7 @@ function __%[1]s_perform_completion
end
__%[1]s_debug "emptyArg: $emptyArg"
set requestComp "$args[1] %[2]s $args[2..-1] $emptyArg"
set requestComp "$args[1] %[3]s $args[2..-1] $emptyArg"
__%[1]s_debug "Calling $requestComp"
set results (eval $requestComp 2> /dev/null)
Expand Down Expand Up @@ -96,16 +102,16 @@ function __%[1]s_prepare_completions
set directive 0
end
set compErr (math (math --scale 0 $directive / %[3]d) %% 2)
set compErr (math (math --scale 0 $directive / %[4]d) %% 2)
if test $compErr -eq 1
__%[1]s_debug "Received error directive: aborting."
# Might as well do file completion, in case it helps
set --global __%[1]s_comp_do_file_comp 1
return 0
end
set nospace (math (math --scale 0 $directive / %[4]d) %% 2)
set nofiles (math (math --scale 0 $directive / %[5]d) %% 2)
set nospace (math (math --scale 0 $directive / %[5]d) %% 2)
set nofiles (math (math --scale 0 $directive / %[6]d) %% 2)
__%[1]s_debug "nospace: $nospace, nofiles: $nofiles"
Expand Down Expand Up @@ -135,21 +141,21 @@ end
# Remove any pre-existing completions for the program since we will be handling all of them
# TODO this cleanup is not sufficient. Fish completions are only loaded once the user triggers
# them, so the below deletion will not work as it is run too early. What else can we do?
complete -c %[1]s -e
complete -c %[2]s -e
# The order in which the below two lines are defined is very important so that __%[1]s_prepare_completions
# is called first. It is __%[1]s_prepare_completions that sets up the __%[1]s_comp_do_file_comp variable.
#
# This completion will be run second as complete commands are added FILO.
# It triggers file completion choices when __%[1]s_comp_do_file_comp is set.
complete -c %[1]s -n 'set --query __%[1]s_comp_do_file_comp'
complete -c %[2]s -n 'set --query __%[1]s_comp_do_file_comp'
# This completion will be run first as complete commands are added FILO.
# The call to __%[1]s_prepare_completions will setup both __%[1]s_comp_results abd __%[1]s_comp_do_file_comp.
# It provides the program's completion choices.
complete -c %[1]s -n '__%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results'
complete -c %[2]s -n '__%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results'
`, name, compCmd, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp))
`, nameForVar, name, compCmd, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp))
}

// GenFishCompletion generates fish completion file and writes to the passed writer.
Expand Down
69 changes: 69 additions & 0 deletions fish_completions_test.go
@@ -0,0 +1,69 @@
package cobra

import (
"bytes"
"testing"
)

func TestCompleteNoDesCmdInFishScript(t *testing.T) {
rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun}
child := &Command{
Use: "child",
ValidArgsFunction: validArgsFunc,
Run: emptyRun,
}
rootCmd.AddCommand(child)

buf := new(bytes.Buffer)
rootCmd.GenFishCompletion(buf, false)
output := buf.String()

check(t, output, ShellCompNoDescRequestCmd)
}

func TestCompleteCmdInFishScript(t *testing.T) {
rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun}
child := &Command{
Use: "child",
ValidArgsFunction: validArgsFunc,
Run: emptyRun,
}
rootCmd.AddCommand(child)

buf := new(bytes.Buffer)
rootCmd.GenFishCompletion(buf, true)
output := buf.String()

check(t, output, ShellCompRequestCmd)
checkOmit(t, output, ShellCompNoDescRequestCmd)
}

func TestProgWithDash(t *testing.T) {
rootCmd := &Command{Use: "root-dash", Args: NoArgs, Run: emptyRun}
buf := new(bytes.Buffer)
rootCmd.GenFishCompletion(buf, false)
output := buf.String()

// Functions name should have replace the '-'
check(t, output, "__root_dash_perform_completion")
checkOmit(t, output, "__root-dash_perform_completion")

// The command name should not have replaced the '-'
check(t, output, "-c root-dash")
checkOmit(t, output, "-c root_dash")
}

func TestProgWithColon(t *testing.T) {
rootCmd := &Command{Use: "root:colon", Args: NoArgs, Run: emptyRun}
buf := new(bytes.Buffer)
rootCmd.GenFishCompletion(buf, false)
output := buf.String()

// Functions name should have replace the ':'
check(t, output, "__root_colon_perform_completion")
checkOmit(t, output, "__root:colon_perform_completion")

// The command name should not have replaced the ':'
check(t, output, "-c root:colon")
checkOmit(t, output, "-c root_colon")
}

0 comments on commit 60f26e0

Please sign in to comment.