From 3133168f94edbe54fb09b8ed74821af86f80bed4 Mon Sep 17 00:00:00 2001 From: moloch-- <875022+moloch--@users.noreply.github.com> Date: Sun, 4 Jan 2026 10:37:23 -0800 Subject: [PATCH 1/2] Attempt to address flickering text --- internal/completion/display.go | 2 -- internal/display/engine.go | 9 ++++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/internal/completion/display.go b/internal/completion/display.go index e345b9e..a54f063 100644 --- a/internal/completion/display.go +++ b/internal/completion/display.go @@ -15,8 +15,6 @@ import ( func Display(eng *Engine, maxRows int) { eng.usedY = 0 - defer fmt.Print(term.ClearScreenBelow) - // The completion engine might be inactive but still having // a non-empty list of completions. This is on purpose, as // sometimes it's better to keep completions printed for a diff --git a/internal/display/engine.go b/internal/display/engine.go index d88cd10..649d4f1 100644 --- a/internal/display/engine.go +++ b/internal/display/engine.go @@ -300,16 +300,23 @@ func (e *Engine) displayHelpers() { // Recompute completions and hints if autocompletion is on. e.completer.Autocomplete() + prevHintRows := e.hintRows + prevCompRows := e.compRows + // Display hint and completions. ui.DisplayHint(e.hint) e.hintRows = ui.CoordinatesHint(e.hint) completion.Display(e.completer, e.AvailableHelperLines()) e.compRows = completion.Coordinates(e.completer) + if e.hintRows+e.compRows < prevHintRows+prevCompRows { + fmt.Print(term.ClearScreenBelow) + } + // Go back to the first line below the input line. term.MoveCursorBackwards(term.GetWidth()) term.MoveCursorUp(e.compRows) - term.MoveCursorUp(ui.CoordinatesHint(e.hint)) + term.MoveCursorUp(e.hintRows) } // AvailableHelperLines returns the number of lines available below the hint section. From d3ac1d6c561d6be6f09246d7ac647940524a6f7e Mon Sep 17 00:00:00 2001 From: moloch-- <875022+moloch--@users.noreply.github.com> Date: Sun, 4 Jan 2026 10:54:23 -0800 Subject: [PATCH 2/2] Attempt to fix flickering text --- internal/completion/engine.go | 10 ++++++++ internal/display/engine.go | 46 +++++++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/internal/completion/engine.go b/internal/completion/engine.go index be271e3..3aa011f 100644 --- a/internal/completion/engine.go +++ b/internal/completion/engine.go @@ -288,6 +288,16 @@ func (e *Engine) Matches() int { return comps } +// DisplaySkipped reports whether completion display is suppressed. +func (e *Engine) DisplaySkipped() bool { + return e.skipDisplay +} + +// ResetUsedRows clears the cached displayed row count. +func (e *Engine) ResetUsedRows() { + e.usedY = 0 +} + // Line returns the relevant input line at the time this function is called: // if a candidate is currently selected, the line returned is the one containing // the candidate. If no candidate is selected, the normal input line is returned. diff --git a/internal/display/engine.go b/internal/display/engine.go index 649d4f1..db667c9 100644 --- a/internal/display/engine.go +++ b/internal/display/engine.go @@ -92,9 +92,13 @@ func (e *Engine) Refresh() { // Display hints and completions, go back // to the start of the line, then to cursor. - e.displayHelpers() - e.cursorHintToLineStart() - e.lineStartToCursorPos() + helpersMoved := e.displayHelpers() + if helpersMoved { + e.cursorHintToLineStart() + e.lineStartToCursorPos() + } else { + e.lineEndToCursorPos() + } fmt.Print(term.ShowCursor) } @@ -294,20 +298,33 @@ func (e *Engine) displayMultilinePrompts() { // displayHelpers renders the hint and completion sections. // It assumes that the cursor is on the last line of input, // and goes back to this same line after displaying this. -func (e *Engine) displayHelpers() { - fmt.Print(term.NewlineReturn) - +func (e *Engine) displayHelpers() bool { // Recompute completions and hints if autocompletion is on. e.completer.Autocomplete() + hintRows := ui.CoordinatesHint(e.hint) + compMatches := e.completer.Matches() + compSkip := e.completer.DisplaySkipped() + + if e.hintRows == 0 && e.compRows == 0 && hintRows == 0 && (compMatches == 0 || compSkip) { + return false + } + + fmt.Print(term.NewlineReturn) + prevHintRows := e.hintRows prevCompRows := e.compRows // Display hint and completions. ui.DisplayHint(e.hint) e.hintRows = ui.CoordinatesHint(e.hint) - completion.Display(e.completer, e.AvailableHelperLines()) - e.compRows = completion.Coordinates(e.completer) + if compMatches > 0 && !compSkip { + completion.Display(e.completer, e.AvailableHelperLines()) + e.compRows = completion.Coordinates(e.completer) + } else { + e.completer.ResetUsedRows() + e.compRows = 0 + } if e.hintRows+e.compRows < prevHintRows+prevCompRows { fmt.Print(term.ClearScreenBelow) @@ -317,6 +334,19 @@ func (e *Engine) displayHelpers() { term.MoveCursorBackwards(term.GetWidth()) term.MoveCursorUp(e.compRows) term.MoveCursorUp(e.hintRows) + + return true +} + +// lineEndToCursorPos moves the cursor from the end of the input line +// to the current cursor position. +func (e *Engine) lineEndToCursorPos() { + if e.lineRows > e.cursorRow { + term.MoveCursorUp(e.lineRows - e.cursorRow) + } + + term.MoveCursorBackwards(term.GetWidth()) + term.MoveCursorForwards(e.cursorCol) } // AvailableHelperLines returns the number of lines available below the hint section.