@@ -15,8 +15,13 @@ import (
1515// Refresh recomputes and redisplays the entire readline interface, except
1616// the first lines of the primary prompt when the latter is a multiline one.
1717func (e * Engine ) Refresh () {
18+ // Buffer the whole frame and flush once, so the terminal never shows a
19+ // partial repaint and we issue a single write instead of dozens.
20+ term .BeginBuffer ()
21+ defer term .EndBuffer ()
22+
1823 // 1. Preparation & Coordinates
19- fmt . Print (term .HideCursor )
24+ term . WriteString (term .HideCursor )
2025 // Go back to the first column, and if the primary prompt
2126 // was not printed yet, back up to the line's beginning row.
2227 term .MoveCursorBackwards (term .GetWidth ())
@@ -63,10 +68,11 @@ func (e *Engine) Refresh() {
6368 // CUD + clear + CUU to clean up artifacts from previous renders.
6469 termHeight := term .GetLength ()
6570 atBottom := (e .startRows + e .lineRows ) >= termHeight
71+
6672 if ! atBottom {
6773 term .MoveCursorDown (1 )
6874 term .MoveCursorBackwards (term .GetWidth ())
69- fmt . Print (term .ClearScreenBelow )
75+ term . WriteString (term .ClearScreenBelow )
7076 term .MoveCursorUp (1 )
7177 term .MoveCursorForwards (e .lineCol )
7278 }
@@ -83,7 +89,7 @@ func (e *Engine) Refresh() {
8389 term .MoveCursorBackwards (term .GetWidth ())
8490 term .MoveCursorForwards (e .cursorCol )
8591
86- fmt . Print (term .ShowCursor )
92+ term . WriteString (term .ShowCursor )
8793}
8894
8995// repaintPromptUpperLines reprints the upper lines of a multi-line prompt at
@@ -131,7 +137,7 @@ func (e *Engine) renderHelpers() {
131137 return
132138 }
133139
134- fmt . Print (term .NewlineReturn )
140+ term . WriteString (term .NewlineReturn )
135141
136142 // 3. Display Hints
137143 ui .DisplayHint (e .hint )
@@ -190,13 +196,13 @@ func (e *Engine) ensureIndicatorSpace() {
190196
191197 e .startCols += indicatorWidth
192198 // Print the indicator on the first line.
193- fmt . Print (indicator )
199+ term . WriteString (indicator )
194200 } else if e .line .Lines () > 0 && e .startCols < indicatorWidth {
195201 // If the prompt is shorter than the indicator, pad with spaces
196202 // to ensure the input text starts aligned with subsequent lines
197203 // and isn't overwritten by the indicator.
198204 padding := indicatorWidth - e .startCols
199- fmt .Printf ("%*s" , padding , "" )
205+ term .Printf ("%*s" , padding , "" )
200206
201207 e .startCols = indicatorWidth
202208 }
@@ -237,7 +243,7 @@ func (e *Engine) ensureInputSpace() {
237243 term .MoveCursorDown (e .lineRows )
238244
239245 for range deficit {
240- fmt . Print (term .NewlineReturn )
246+ term . WriteString (term .NewlineReturn )
241247 }
242248
243249 e .startRows -= deficit
@@ -301,15 +307,15 @@ func (e *Engine) renderMultilineIndicators() {
301307 pipe := ui .DefaultMultilineColumn
302308
303309 for i := 1 ; i <= e .line .Lines (); i ++ {
304- fmt . Print ("\n " )
310+ term . WriteString ("\n " )
305311
306312 switch {
307313 case numbered :
308- fmt .Printf (color .FgBlackBright + "%d" + color .Reset + " " , i + 1 )
314+ term .Printf (color .FgBlackBright + "%d" + color .Reset + " " , i + 1 )
309315 case i == e .line .Lines ():
310316 e .prompt .SecondaryPrint ()
311317 default :
312- fmt . Print (pipe )
318+ term . WriteString (pipe )
313319 }
314320
315321 printedLines ++
0 commit comments