commit 73356a540fba4fce6062e4944747cac67a8ec0e6
parent e9247b213d948a41586e1a6063fe0030caec312c
Author: Sean Enck <sean@ttypty.com>
Date: Sun, 6 Oct 2024 18:02:52 -0400
fish rewritten
Diffstat:
7 files changed, 57 insertions(+), 7 deletions(-)
diff --git a/internal/app/completions.go b/internal/app/completions.go
@@ -31,6 +31,11 @@ type (
HelpAdvancedCommand string
Options []CompletionOption
TOTPSubCommands []CompletionOption
+ Conditionals struct {
+ ReadOnly string
+ NoClip string
+ NoTOTP string
+ }
}
// CompletionOption are conditional wrapped logic for options that may be disabled
CompletionOption struct {
@@ -87,8 +92,10 @@ func GenerateCompletions(completionType, exe string) ([]string, error) {
DoList: fmt.Sprintf("%s %s", exe, ListCommand),
DoTOTPList: fmt.Sprintf("%s %s %s", exe, TOTPCommand, TOTPListCommand),
}
+ c.Conditionals.ReadOnly = newConditional(config.EnvReadOnly.Key(), config.YesValue)
+ c.Conditionals.NoClip = newConditional(config.EnvNoClip.Key(), config.YesValue)
+ c.Conditionals.NoTOTP = newConditional(config.EnvNoTOTP.Key(), config.YesValue)
- // TOTPSubCommands: []string{TOTPMinimalCommand, TOTPOnceCommand, TOTPShowCommand, TOTPClipCommand, TOTPInsertCommand},
cmds := newGenOptions(
EnvCommand,
HelpCommand,
diff --git a/internal/app/completions_test.go b/internal/app/completions_test.go
@@ -10,6 +10,7 @@ import (
func TestCompletions(t *testing.T) {
for k, v := range map[string]string{
"zsh": "typeset -A opt_args",
+ "fish": "set -f commands",
"bash": "local cur opts",
} {
testCompletion(t, k, v)
diff --git a/internal/app/core.go b/internal/app/core.go
@@ -71,8 +71,10 @@ const (
JSONCommand = "json"
// CompletionsZshCommand is the command to generate zsh completions
CompletionsZshCommand = "zsh"
- docDir = "doc"
- textFile = ".txt"
+ // CompletionsFishCommand is the command to generate fish completions
+ CompletionsFishCommand = "fish"
+ docDir = "doc"
+ textFile = ".txt"
// PasswordGenerateCommand is the command to do password generation
PasswordGenerateCommand = "pwgen"
)
@@ -80,7 +82,7 @@ const (
var (
//go:embed doc/*
docs embed.FS
- completionTypes = []string{CompletionsBashCommand, CompletionsZshCommand}
+ completionTypes = []string{CompletionsBashCommand, CompletionsFishCommand, CompletionsZshCommand}
)
type (
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) != 26 {
t.Errorf("invalid usage, out of date? %d", len(u))
}
u, _ = app.Usage(true, "lb")
- if len(u) != 114 {
+ if len(u) != 115 {
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
@@ -77,7 +77,7 @@ func info(command string, args []string) ([]string, error) {
return nil, errors.New("invalid completions subcommand")
}
switch shell {
- case CompletionsZshCommand, CompletionsBashCommand:
+ case CompletionsZshCommand, CompletionsBashCommand, CompletionsFishCommand:
break
default:
return nil, fmt.Errorf("unknown completion type: %s", shell)
diff --git a/internal/app/info_test.go b/internal/app/info_test.go
@@ -74,6 +74,7 @@ func TestCompletionInfo(t *testing.T) {
defer os.Clearenv()
for k, v := range map[string]string{
"zsh": "typeset -A opt_args",
+ "fish": "set -f commands",
"bash": "local cur opts",
} {
for _, b := range []bool{true, false} {
diff --git a/internal/app/shell/fish.sh b/internal/app/shell/fish.sh
@@ -0,0 +1,39 @@
+complete -c {{ $.Executable }} -f
+
+
+function {{ $.Executable }}-completion
+ set -f commands ""
+{{- range $idx, $value := $.Options }}
+ {{- if gt $idx 0 }}
+ set -f commands " $commands"
+ {{ end }}
+ if {{ $value.Conditional }}
+ set -f commands "{{ $value.Key }}$commands"
+ end
+{{- end }}
+ complete -c {{ $.Executable }} -n "not __fish_seen_subcommand_from $commands" -a "$commands"
+ complete -c {{ $.Executable }} -n "__fish_seen_subcommand_from {{ $.HelpCommand }}; and test (count (commandline -opc)) -lt 3" -a "{{ $.HelpAdvancedCommand }}"
+ if {{ $.Conditionals.ReadOnly }}
+ complete -c {{ $.Executable }} -n "__fish_seen_subcommand_from {{ $.InsertCommand }} {{ $.MultiLineCommand }} {{ $.RemoveCommand }}; and test (count (commandline -opc)) -lt 3" -a "({{ $.DoList }})"
+ complete -c {{ $.Executable }} -n "__fish_seen_subcommand_from {{ $.MoveCommand }}; and test (count (commandline -opc)) -lt 4" -a "({{ $.DoList }})"
+ end
+ if {{ $.Conditionals.NoTOTP }}
+ set -f totps ""
+{{- range $idx, $value := $.TOTPSubCommands }}
+ {{- if gt $idx 0 }}
+ set -f totps " $totps"
+ {{ end }}
+ if {{ $value.Conditional }}
+ set -f totps "{{ $value.Key }}$totps"
+ end
+{{- end }}
+ complete -c {{ $.Executable }} -n "__fish_seen_subcommand_from {{ $.TOTPCommand }}; and not __fish_seen_subcommand_from $totps" -a "$totps"
+ complete -c {{ $.Executable }} -n "__fish_seen_subcommand_from {{ $.TOTPCommand }}; and __fish_seen_subcommand_from $totps; and test (count (commandline -opc)) -lt 4" -a "({{ $.DoTOTPList }})"
+ end
+ if {{ $.Conditionals.NoClip }}
+ complete -c {{ $.Executable }} -n "__fish_seen_subcommand_from {{ $.ClipCommand }}; and test (count (commandline -opc)) -lt 3" -a "({{ $.DoList}})"
+ end
+ complete -c {{ $.Executable }} -n "__fish_seen_subcommand_from {{ $.ShowCommand }} {{ $.JSONCommand }}; and test (count (commandline -opc)) -lt 3" -a "({{ $.DoList}})"
+end
+
+{{ $.Executable }}-completion