From 7af4d5657238e5b4fc250752fc8f6c44b192f9e6 Mon Sep 17 00:00:00 2001 From: verse91 Date: Wed, 29 Apr 2026 19:45:37 +0700 Subject: [PATCH] chore: improve UX --- integration/overlay.go | 40 +++++++++++++++++++++++++++++++++------- root/wrapper.go | 12 ++++++------ 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/integration/overlay.go b/integration/overlay.go index f12334b..70fb617 100644 --- a/integration/overlay.go +++ b/integration/overlay.go @@ -19,6 +19,7 @@ type Overlay struct { Visible bool Items []core.Suggestion Cursor int + StartIdx int LastGhostLen int } @@ -40,8 +41,9 @@ var ( func NewOverlay() *Overlay { return &Overlay{ - Visible: false, - Cursor: 0, + Visible: false, + Cursor: 0, + StartIdx: 0, } } @@ -52,6 +54,7 @@ func (o *Overlay) UpdateItems(items []core.Suggestion) { o.Items = items o.Visible = len(o.Items) > 0 o.Cursor = 0 // reset to top result on update + o.StartIdx = 0 } // fixedWidth pads or truncates a string to exact rune width @@ -88,8 +91,8 @@ func (o *Overlay) RenderGhostText(buffer string, userNavigated bool) string { if padLen < 0 { padLen = 0 } - - // add extra padding to erase any stray characters left by fast backspaces + + // add extra padding to erase any stray characters left by fast backspaces // before the debounce timer fired. 10 spaces is safe and won't hit right prompts padLen += 10 @@ -125,10 +128,33 @@ func (o *Overlay) Render() string { windowSize = len(o.Items) } - start := 0 - if o.Cursor >= windowSize { - start = o.Cursor - windowSize + 1 + // when you use up arrow key, the selection bar will stick with the second item + // it stays still at second position until you reach the limit of the list + // but not apply the same with down arrow key + scrolloffUp := 1 + scrolloffDown := 0 + if windowSize <= 3 { + scrolloffUp = 0 } + + if o.Cursor < o.StartIdx+scrolloffUp { + o.StartIdx = o.Cursor - scrolloffUp + } + if o.Cursor >= o.StartIdx+windowSize-scrolloffDown { + o.StartIdx = o.Cursor - windowSize + scrolloffDown + 1 + } + + if o.StartIdx < 0 { + o.StartIdx = 0 + } + if o.StartIdx > len(o.Items)-windowSize { + o.StartIdx = len(o.Items) - windowSize + } + if o.StartIdx < 0 { + o.StartIdx = 0 + } + + start := o.StartIdx end := start + windowSize totalLines := windowSize + 2 // top border + items + bottom border diff --git a/root/wrapper.go b/root/wrapper.go index 23c17e5..10ac72a 100644 --- a/root/wrapper.go +++ b/root/wrapper.go @@ -380,28 +380,28 @@ func runWrapper() { results := mergeResults("", "history") if len(results) > 0 { - limit := 10 + limit := 100 if len(results) < limit { limit = len(results) } - var top10 []core.Suggestion + var historyList []core.Suggestion if inputSlice[i+2] == 'A' { // Up arrow: Reverse the list so newest is at the bottom for j := limit - 1; j >= 0; j-- { - top10 = append(top10, results[j]) + historyList = append(historyList, results[j]) } } else { // Down arrow: Normal order, newest is at the top for j := 0; j < limit; j++ { - top10 = append(top10, results[j]) + historyList = append(historyList, results[j]) } } - overlay.UpdateItems(top10) + overlay.UpdateItems(historyList) if inputSlice[i+2] == 'A' { - overlay.Cursor = len(top10) - 1 // Up arrow: Start at the bottom + overlay.Cursor = len(historyList) - 1 // Up arrow: Start at the bottom } else { overlay.Cursor = 0 // Down arrow: Start at the top }