@@ -29,39 +29,9 @@ func (e *Engine) Refresh() {
2929 // Compute Coordinates: StartPos, LineHeight, CursorPos (row/col).
3030 e .computeCoordinates (true )
3131
32- // Determine the width of the multiline indicator.
33- // We need to ensure that the indentation of the input line is at least
34- // as wide as the indicator, otherwise the indicator will overwrite the text
35- // on subsequent lines.
36- var indicatorWidth int
37- if e .opts .GetBool ("multiline-column-numbered" ) {
38- indicatorWidth = len (strconv .Itoa (1 )) + 1
39- } else {
40- indicatorWidth = 2
41- }
42-
43- // Adjust indentation if the primary prompt is empty,
44- // because we will print a column indicator on the first line.
45- if e .prompt .LastUsed () == 0 && e .line .Lines () > 0 {
46- var indicator string
47- if e .opts .GetBool ("multiline-column-numbered" ) {
48- indicator = fmt .Sprintf (color .FgBlackBright + "%d" + color .Reset + " " , 1 )
49- } else {
50- indicator = ui .DefaultMultilineColumn
51- }
52-
53- e .startCols += indicatorWidth
54- // Print the indicator on the first line.
55- fmt .Print (indicator )
56- } else if e .line .Lines () > 0 && e .startCols < indicatorWidth {
57- // If the prompt is shorter than the indicator, pad with spaces
58- // to ensure the input text starts aligned with subsequent lines
59- // and isn't overwritten by the indicator.
60- padding := indicatorWidth - e .startCols
61- fmt .Print (fmt .Sprintf ("%*s" , padding , "" ))
62-
63- e .startCols = indicatorWidth
64- }
32+ // Ensure that the indicator is printed if the prompt is empty,
33+ // and that we have enough space to print the line.
34+ e .ensureIndicatorSpace ()
6535
6636 // Recompute coordinates with the new indentation/cursor position.
6737 if e .line .Lines () > 0 {
@@ -72,36 +42,7 @@ func (e *Engine) Refresh() {
7242 // Ensure that we have enough space to print the line.
7343 // We probe the terminal to verify that we are not at the bottom of the screen.
7444 // If we are, we scroll the screen to make space for the line.
75- if e .lineRows > 1 {
76- // 1. Probe the terminal height.
77- // We move the cursor down to the last line of the input line,
78- // and check if the cursor is at the expected position.
79- term .MoveCursorDown (e .lineRows - 1 )
80- _ , actualRow := e .keys .GetCursorPos ()
81- term .MoveCursorUp (e .lineRows - 1 )
82-
83- // 2. Calculate the overshoot.
84- expectedRow := e .startRows + e .lineRows - 1
85- overshoot := expectedRow - actualRow
86-
87- // 3. Scroll the screen if needed.
88- if overshoot > 0 {
89- // Move to the bottom of the terminal.
90- term .MoveCursorDown (actualRow - e .startRows )
91-
92- // Scroll the screen by printing newlines.
93- for i := 0 ; i < overshoot ; i ++ {
94- fmt .Print ("\n " )
95- }
96-
97- // Update the start row to reflect the scrolling.
98- e .startRows -= overshoot
99-
100- // Move the cursor back up to the new start position.
101- term .MoveCursorUp (e .lineRows - 1 )
102- term .MoveCursorForwards (e .startCols )
103- }
104- }
45+ e .ensureInputSpace ()
10546
10647 // 3. Input Area Rendering
10748 e .renderInputArea ()
@@ -197,6 +138,77 @@ func (e *Engine) renderRightPrompt() {
197138 term .MoveCursorForwards (e .lineCol )
198139}
199140
141+ func (e * Engine ) ensureIndicatorSpace () {
142+ // Determine the width of the multiline indicator.
143+ // We need to ensure that the indentation of the input line is at least
144+ // as wide as the indicator, otherwise the indicator will overwrite the text
145+ // on subsequent lines.
146+ var indicatorWidth int
147+ if e .opts .GetBool ("multiline-column-numbered" ) {
148+ indicatorWidth = len (strconv .Itoa (1 )) + 1
149+ } else {
150+ indicatorWidth = 2
151+ }
152+
153+ // Adjust indentation if the primary prompt is empty,
154+ // because we will print a column indicator on the first line.
155+ if e .prompt .LastUsed () == 0 && e .line .Lines () > 0 {
156+ var indicator string
157+ if e .opts .GetBool ("multiline-column-numbered" ) {
158+ indicator = fmt .Sprintf (color .FgBlackBright + "%d" + color .Reset + " " , 1 )
159+ } else {
160+ indicator = ui .DefaultMultilineColumn
161+ }
162+
163+ e .startCols += indicatorWidth
164+ // Print the indicator on the first line.
165+ fmt .Print (indicator )
166+ } else if e .line .Lines () > 0 && e .startCols < indicatorWidth {
167+ // If the prompt is shorter than the indicator, pad with spaces
168+ // to ensure the input text starts aligned with subsequent lines
169+ // and isn't overwritten by the indicator.
170+ padding := indicatorWidth - e .startCols
171+ fmt .Print (fmt .Sprintf ("%*s" , padding , "" ))
172+
173+ e .startCols = indicatorWidth
174+ }
175+ }
176+
177+ func (e * Engine ) ensureInputSpace () {
178+ if e .lineRows <= 1 {
179+ return
180+ }
181+
182+ // 1. Probe the terminal height.
183+ // We move the cursor down to the last line of the input line,
184+ // and check if the cursor is at the expected position.
185+ term .MoveCursorDown (e .lineRows - 1 )
186+ _ , actualRow := e .keys .GetCursorPos ()
187+ term .MoveCursorUp (e .lineRows - 1 )
188+
189+ // 2. Calculate the overshoot.
190+ expectedRow := e .startRows + e .lineRows - 1
191+ overshoot := expectedRow - actualRow
192+
193+ // 3. Scroll the screen if needed.
194+ if overshoot > 0 {
195+ // Move to the bottom of the terminal.
196+ term .MoveCursorDown (actualRow - e .startRows )
197+
198+ // Scroll the screen by printing newlines.
199+ for range overshoot {
200+ fmt .Print ("\n " )
201+ }
202+
203+ // Update the start row to reflect the scrolling.
204+ e .startRows -= overshoot
205+
206+ // Move the cursor back up to the new start position.
207+ term .MoveCursorUp (e .lineRows - 1 )
208+ term .MoveCursorForwards (e .startCols )
209+ }
210+ }
211+
200212func (e * Engine ) displayLineRefactored () {
201213 var line string
202214 // Apply user-defined highlighter to the input line.
0 commit comments