Skip to content

Commit a0fa644

Browse files
committed
refactor(display): extract Refresh logic into helper methods
- Extracted terminal probing and scrolling logic into ensureInputSpace(). - Extracted multiline indicator setup logic into ensureIndicatorSpace(). - Simplified the main Refresh() method for better readability and maintainability.
1 parent cbf1ab2 commit a0fa644

1 file changed

Lines changed: 75 additions & 63 deletions

File tree

internal/display/refresh.go

Lines changed: 75 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
200212
func (e *Engine) displayLineRefactored() {
201213
var line string
202214
// Apply user-defined highlighter to the input line.

0 commit comments

Comments
 (0)