commit 1143e815f0c0e19effa74e0e600dd2d9acac7ed4
parent d200f190114506275d6681eac33e3f8a855dfb1b
Author: Sean Enck <sean@ttypty.com>
Date: Thu, 21 Mar 2024 21:35:10 -0400
initial work on fish completion
Diffstat:
7 files changed, 49 insertions(+), 24 deletions(-)
diff --git a/README.md b/README.md
@@ -34,7 +34,7 @@ Use `lb help verbose` for additional information about options and environment v
`lb` should work on combinations of the following:
- linux/macOS/WSL
-- zsh/bash (for completions)
+- zsh/bash/fish (for completions)
- amd64/arm64
## usage
diff --git a/internal/app/completions.go b/internal/app/completions.go
@@ -119,14 +119,14 @@ func loadProfiles(exe string, canFilter bool) []Profile {
}
// GenerateCompletions handles creating shell completion outputs
-func GenerateCompletions(isBash, isHelp bool, exe string) ([]string, error) {
+func GenerateCompletions(completionType string, isHelp bool, exe string) ([]string, error) {
if isHelp {
var h []string
for _, p := range loadProfiles(exe, false) {
if p.IsDefault {
continue
}
- text := fmt.Sprintf("export %s\n - filtered completions\n - useful when:\n", p.Env())
+ text := fmt.Sprintf("when %s\n - filtered completions\n - useful when:\n", p.Env())
for idx, e := range p.env {
if idx > 0 {
text = fmt.Sprintf("%s and\n", text)
@@ -138,7 +138,7 @@ func GenerateCompletions(isBash, isHelp bool, exe string) ([]string, error) {
h = append(h, strings.TrimSpace(fmt.Sprintf(`
%s is not set
unset %s
-export %s=<unknown>
+when %s=<unknown>
- default completions
`, config.EnvironmentCompletionKey, config.EnvironmentCompletionKey, config.EnvironmentCompletionKey)))
return h, nil
@@ -161,16 +161,10 @@ export %s=<unknown>
CompletionEnv: fmt.Sprintf("$%s", config.EnvironmentCompletionKey),
}
- using, err := readDoc("zsh.sh")
+ using, err := readDoc(fmt.Sprintf("%s.sh", completionType))
if err != nil {
return nil, err
}
- if isBash {
- using, err = readDoc("bash.sh")
- if err != nil {
- return nil, err
- }
- }
shellScript, err := readDoc("shell.sh")
if err != nil {
return nil, err
diff --git a/internal/app/completions_test.go b/internal/app/completions_test.go
@@ -9,12 +9,13 @@ import (
)
func TestCompletions(t *testing.T) {
- testCompletion(t, true)
- testCompletion(t, false)
+ testCompletion(t, "bash")
+ testCompletion(t, "zsh")
+ testCompletion(t, "fish")
}
-func testCompletion(t *testing.T, bash bool) {
- v, err := app.GenerateCompletions(bash, true, "lb")
+func testCompletion(t *testing.T, completionMode string) {
+ v, err := app.GenerateCompletions(completionMode, true, "lb")
if err != nil {
t.Errorf("invalid error: %v", err)
}
@@ -23,7 +24,7 @@ func testCompletion(t *testing.T, bash bool) {
}
defer os.Clearenv()
os.Setenv("LOCKBOX_COMPLETION_FUNCTION", "A")
- o, err := app.GenerateCompletions(bash, true, "lb")
+ o, err := app.GenerateCompletions(completionMode, true, "lb")
if err != nil {
t.Errorf("invalid error: %v", err)
}
@@ -31,7 +32,7 @@ func testCompletion(t *testing.T, bash bool) {
t.Errorf("invalid result")
}
os.Setenv("LOCKBOX_COMPLETION_FUNCTION", "")
- v, err = app.GenerateCompletions(bash, false, "lb")
+ v, err = app.GenerateCompletions(completionMode, false, "lb")
if err != nil {
t.Errorf("invalid error: %v", err)
}
@@ -39,12 +40,12 @@ func testCompletion(t *testing.T, bash bool) {
t.Errorf("invalid result")
}
os.Setenv("LOCKBOX_COMPLETION_FUNCTION", "ZZZ")
- _, err = app.GenerateCompletions(bash, false, "lb")
+ _, err = app.GenerateCompletions(completionMode, false, "lb")
if err == nil || err.Error() != "no profiles loaded, invalid environment setting?" {
t.Errorf("invalid error: %v", err)
}
os.Setenv("LOCKBOX_COMPLETION_FUNCTION", "NOCLIP-READONLY")
- n, err := app.GenerateCompletions(bash, false, "lb")
+ n, err := app.GenerateCompletions(completionMode, false, "lb")
if err != nil {
t.Errorf("invalid error: %v", err)
}
@@ -52,7 +53,7 @@ func testCompletion(t *testing.T, bash bool) {
t.Errorf("invalid result, should filter")
}
os.Setenv("LOCKBOX_COMPLETION_FUNCTION", "DEFAULT")
- d, err := app.GenerateCompletions(bash, false, "lb")
+ d, err := app.GenerateCompletions(completionMode, false, "lb")
if err != nil {
t.Errorf("invalid error: %v", err)
}
diff --git a/internal/app/core.go b/internal/app/core.go
@@ -72,6 +72,8 @@ const (
JSONCommand = "json"
// ZshCommand is the command to generate zsh completions
ZshCommand = "zsh"
+ // FishCommand is the command to generate fish completions
+ FishCommand = "fish"
docDir = "doc"
textFile = ".txt"
)
@@ -206,6 +208,8 @@ func Usage(verbose bool, exe string) ([]string, error) {
results = append(results, command(VersionCommand, "", "display version information"))
results = append(results, command(ZshCommand, "", "generate user environment zsh completion"))
results = append(results, subCommand(ZshCommand, CompletionHelpCommand, "", completionHelpDesc))
+ results = append(results, command(FishCommand, "", "generate user environment fish completion"))
+ results = append(results, subCommand(FishCommand, CompletionHelpCommand, "", completionHelpDesc))
sort.Strings(results)
usage := []string{fmt.Sprintf("%s usage:", exe)}
if verbose {
diff --git a/internal/app/core_test.go b/internal/app/core_test.go
@@ -9,11 +9,11 @@ import (
func TestUsage(t *testing.T) {
u, _ := app.Usage(false, "lb")
- if len(u) != 25 {
+ if len(u) != 27 {
t.Errorf("invalid usage, out of date? %d", len(u))
}
u, _ = app.Usage(true, "lb")
- if len(u) != 108 {
+ if len(u) != 110 {
t.Errorf("invalid verbose usage, out of date? %d", len(u))
}
for _, usage := range u {
diff --git a/internal/app/info.go b/internal/app/info.go
@@ -61,7 +61,7 @@ func info(command string, args []string) ([]string, error) {
return nil, errors.New("invalid env command")
}
return config.Environ(), nil
- case BashCommand, ZshCommand:
+ case BashCommand, ZshCommand, FishCommand:
if len(args) > 1 {
return nil, fmt.Errorf("invalid %s command", command)
}
@@ -77,7 +77,7 @@ func info(command string, args []string) ([]string, error) {
if err != nil {
return nil, err
}
- return GenerateCompletions(command == BashCommand, isHelp, exe)
+ return GenerateCompletions(command, isHelp, exe)
}
return nil, nil
}
diff --git a/internal/app/info_test.go b/internal/app/info_test.go
@@ -123,3 +123,29 @@ func TestZshInfo(t *testing.T) {
t.Errorf("invalid error: %v", err)
}
}
+
+func TestFishInfo(t *testing.T) {
+ os.Clearenv()
+ var buf bytes.Buffer
+ ok, err := app.Info(&buf, "fish", []string{})
+ if !ok || err != nil {
+ t.Errorf("invalid error: %v", err)
+ }
+ if buf.String() == "" {
+ t.Error("nothing written")
+ }
+ buf = bytes.Buffer{}
+ ok, err = app.Info(&buf, "fish", []string{"help"})
+ if !ok || err != nil {
+ t.Errorf("invalid error: %v", err)
+ }
+ if buf.String() == "" {
+ t.Error("nothing written")
+ }
+ if _, err = app.Info(&buf, "fish", []string{"defaults"}); err.Error() != "invalid fish subcommand" {
+ t.Errorf("invalid error: %v", err)
+ }
+ if _, err = app.Info(&buf, "fish", []string{"test", "default"}); err.Error() != "invalid fish command" {
+ t.Errorf("invalid error: %v", err)
+ }
+}