From c17e3e2259da370f26b9e91c45c3901fcc89fb8e Mon Sep 17 00:00:00 2001 From: Arvid Bjurklint Date: Fri, 9 Aug 2024 22:41:56 +0200 Subject: [PATCH] Sort matches by consecutive matches with the prompt --- main.go | 35 +++++++++++++++++++------ main_test.go | 73 +++++++++++++++++++++++++++++++++------------------- 2 files changed, 73 insertions(+), 35 deletions(-) diff --git a/main.go b/main.go index 0111eed..62bc829 100644 --- a/main.go +++ b/main.go @@ -28,6 +28,11 @@ func fatal(msg string, args ...any) { os.Exit(1) } +type Match struct { + Key string + ConsecutiveMatches int +} + func main() { log.SetFlags(0) // Disable the timestamp vault := VaultClient{ @@ -146,12 +151,19 @@ func main() { width, height := screen.Size() if nextPrompt != prompt { prompt = nextPrompt - filteredKeys = []string{} + matches := []Match{} for _, k := range keys { - if matchesPrompt(prompt, k) { - filteredKeys = append(filteredKeys, k) + if match, consecutive := matchesPrompt(prompt, k); match { + matches = append(matches, Match{Key: k, ConsecutiveMatches: consecutive}) } } + slices.SortFunc(matches, func(a, b Match) int { + return b.ConsecutiveMatches - a.ConsecutiveMatches + }) + filteredKeys = []string{} + for _, m := range matches { + filteredKeys = append(filteredKeys, m.Key) + } } screen.Clear() drawKeys(screen, width, height, filteredKeys, selectedIndex) @@ -321,7 +333,6 @@ func drawKeys(s tcell.Screen, width, height int, keys []string, selectedIndex in maxHeight := height - 2 offset := max(0, selectedIndex-maxHeight+1) keys = keys[offset:min(maxHeight+offset, len(keys))] - slices.Sort(keys) y := height - 3 for _, line := range keys { line = line[:min(width/2-2, len(line))] @@ -430,18 +441,26 @@ func drawLoadingScreen(s tcell.Screen, height int) { drawLine(s, 2, height-2, tcell.StyleDefault.Foreground(tcell.ColorYellow), "Loading...") } -func matchesPrompt(prompt, s string) bool { +func matchesPrompt(prompt, s string) (bool, int) { if len(prompt) == 0 { - return true + return true, 0 } index := 0 + consecutive := 0 + previousMatched := false for _, c := range []byte(s) { if c == prompt[index] { + if previousMatched { + consecutive++ + } + previousMatched = true if index == len(prompt)-1 { - return true + return true, consecutive } index++ + } else { + previousMatched = false } } - return false + return false, 0 } diff --git a/main_test.go b/main_test.go index b3417fd..b35a306 100644 --- a/main_test.go +++ b/main_test.go @@ -87,49 +87,68 @@ func TestGetSecret(t *testing.T) { func TestMatchesPrompt(t *testing.T) { tests := map[string]struct { - prompt string - key string - expected bool + prompt string + key string + match bool + consecutive int }{ "match": { - prompt: "set", - key: "secret", - expected: true, + prompt: "set", + key: "secret", + match: true, + consecutive: 1, }, "match2": { - prompt: "seet", - key: "secret", - expected: true, + prompt: "seet", + key: "secret", + match: true, + consecutive: 2, }, "exact-match": { - prompt: "secret", - key: "secret", - expected: true, + prompt: "secret", + key: "secret", + match: true, + consecutive: 5, + }, + "short-match": { + prompt: "user", + key: "/user", + match: true, + consecutive: 3, + }, + "long-match": { + prompt: "user", + key: "/if/you/can/read/the/full/path/of/this/key/you/are/the/person/in/the/red/flag/monitor/meme", + match: true, + consecutive: 0, }, "no-match": { - prompt: "asdf", - key: "secret", - expected: false, + prompt: "asdf", + key: "secret", + match: false, + consecutive: 0, }, "no-match1": { - prompt: "a", - key: "secret", - expected: false, + prompt: "a", + key: "secret", + match: false, + consecutive: 0, }, "no-match2": { - prompt: "seeet", - key: "secret", - expected: false, + prompt: "seeet", + key: "secret", + match: false, + consecutive: 0, }, } for name, test := range tests { t.Run(name, func(t *testing.T) { - if matchesPrompt(test.prompt, test.key) != test.expected { - if test.expected { - t.Fatalf("Expected %s to match %s", test.prompt, test.key) - } else { - t.Fatalf("Expected %s to not match %s", test.prompt, test.key) - } + match, consecutive := matchesPrompt(test.prompt, test.key) + if match != test.match { + t.Fatalf("Expected %s to match %s", test.prompt, test.key) + } + if consecutive != test.consecutive { + t.Fatalf("Expected %d consecutive character matches for prompt %s and key %s, got %d", test.consecutive, test.prompt, test.key, consecutive) } }) }