commit ea14b905e4032103db269874e3c273b7faf006e9
parent 992ecae8bc27d63460c90eb7640f30253ec7bd69
Author: Sean Enck <sean@ttypty.com>
Date: Sun, 3 Sep 2023 15:50:34 -0400
support completions that can be filtered to function as well
Diffstat:
3 files changed, 68 insertions(+), 14 deletions(-)
diff --git a/internal/app/completions.go b/internal/app/completions.go
@@ -3,6 +3,7 @@ package app
import (
"bytes"
+ "errors"
"fmt"
"strings"
"text/template"
@@ -82,8 +83,10 @@ func (p Profile) TOTPSubCommands() []string {
return totp
}
-func loadProfiles(exe string) []Profile {
+func loadProfiles(exe string, canFilter bool) []Profile {
profiles := config.LoadCompletionProfiles()
+ filter := config.EnvCompletion.Get()
+ hasFilter := filter != "" && canFilter
var res []Profile
for _, p := range profiles {
name := p.Name
@@ -97,6 +100,19 @@ func loadProfiles(exe string) []Profile {
n.ReadOnly = !p.Write
n.IsDefault = p.Default
n.env = p.Env
+ if hasFilter {
+ skipped := false
+ if p.Default {
+ skipped = filter != "DEFAULT"
+ } else {
+ if filter != n.Display() {
+ skipped = true
+ }
+ }
+ if skipped {
+ continue
+ }
+ }
res = append(res, n)
}
return res
@@ -106,7 +122,7 @@ func loadProfiles(exe string) []Profile {
func GenerateCompletions(isBash, isHelp bool, exe string) ([]string, error) {
if isHelp {
var h []string
- for _, p := range loadProfiles(exe) {
+ for _, p := range loadProfiles(exe, false) {
if p.IsDefault {
continue
}
@@ -159,11 +175,18 @@ export %s=<unknown>
if err != nil {
return nil, err
}
- c.Profiles = loadProfiles(exe)
- for _, p := range c.Profiles {
- if p.IsDefault {
- c.DefaultProfile = p
- break
+ c.Profiles = loadProfiles(exe, true)
+ switch len(c.Profiles) {
+ case 0:
+ return nil, errors.New("no profiles loaded, invalid environment setting?")
+ case 1:
+ c.DefaultProfile = c.Profiles[0]
+ default:
+ for _, p := range c.Profiles {
+ if p.IsDefault {
+ c.DefaultProfile = p
+ break
+ }
}
}
shell, err := templateScript(shellScript, c)
diff --git a/internal/app/completions_test.go b/internal/app/completions_test.go
@@ -1,29 +1,56 @@
package app_test
import (
+ "fmt"
+ "os"
"testing"
"github.com/enckse/lockbox/internal/app"
)
-func TestBashCompletion(t *testing.T) {
- v, err := app.GenerateCompletions(true, false, "lb")
+func TestCompletions(t *testing.T) {
+ testCompletion(t, true)
+ testCompletion(t, false)
+}
+
+func testCompletion(t *testing.T, bash bool) {
+ v, err := app.GenerateCompletions(bash, true, "lb")
if err != nil {
t.Errorf("invalid error: %v", err)
}
- if len(v) != 1 {
+ if len(v) < 2 {
t.Errorf("invalid result")
}
-}
-
-func TestZshCompletion(t *testing.T) {
- v, err := app.GenerateCompletions(false, false, "lb")
+ defer os.Clearenv()
+ os.Setenv("LOCKBOX_COMPLETION_FUNCTION", "A")
+ o, err := app.GenerateCompletions(bash, true, "lb")
+ if err != nil {
+ t.Errorf("invalid error: %v", err)
+ }
+ if len(o) < 2 || len(o) != len(v) {
+ t.Errorf("invalid result")
+ }
+ os.Setenv("LOCKBOX_COMPLETION_FUNCTION", "")
+ v, err = app.GenerateCompletions(bash, false, "lb")
if err != nil {
t.Errorf("invalid error: %v", err)
}
if len(v) != 1 {
t.Errorf("invalid result")
}
+ os.Setenv("LOCKBOX_COMPLETION_FUNCTION", "ZZZ")
+ _, err = app.GenerateCompletions(bash, 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")
+ if err != nil {
+ t.Errorf("invalid error: %v", err)
+ }
+ if fmt.Sprintf("%v", n) == fmt.Sprintf("%v", v) {
+ t.Errorf("invalid result, should filter")
+ }
}
func TestProfileDisplay(t *testing.T) {
diff --git a/internal/app/doc/shell b/internal/app/doc/shell
@@ -1,4 +1,7 @@
_{{ $.Executable }}() {
+{{- if eq (len $.Profiles) 1 }}
+ {{ $.DefaultProfile.Name }}
+{{- else}}
case "{{ $.CompletionEnv }}" in
{{- range $idx, $profile := $.Profiles }}
{{- if not $profile.IsDefault }}
@@ -11,4 +14,5 @@ _{{ $.Executable }}() {
{{ $.DefaultProfile.Name }}
;;
esac
+{{- end}}
}