@@ -272,6 +272,12 @@ type Model struct {
272
272
// Cursor row.
273
273
row int
274
274
275
+ // The bubble offset relative to the parent bubble.
276
+ offsetX , offsetY int
277
+
278
+ // The last recorded real cursor position.
279
+ realCol , realRow int
280
+
275
281
// Last character offset, used to maintain state when the cursor is moved
276
282
// vertically such that we can maintain the same navigating position.
277
283
lastCharOffset int
@@ -358,6 +364,11 @@ func DefaultDarkStyles() Styles {
358
364
return DefaultStyles (true )
359
365
}
360
366
367
+ // SetOffset sets the offset of the textarea relative to the parent bubble.
368
+ func (m * Model ) SetOffset (x , y int ) {
369
+ m .offsetX , m .offsetY = x , y
370
+ }
371
+
361
372
// SetValue sets the value of the text input.
362
373
func (m * Model ) SetValue (s string ) {
363
374
m .Reset ()
@@ -1101,11 +1112,23 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
1101
1112
1102
1113
newRow , newCol := m .cursorLineNumber (), m .col
1103
1114
m .Cursor , cmd = m .Cursor .Update (msg )
1104
- if (newRow != oldRow || newCol != oldCol ) && m .Cursor .Mode () == cursor .CursorBlink {
1115
+ if cmd != nil {
1116
+ cmds = append (cmds , cmd )
1117
+ }
1118
+
1119
+ if m .Cursor .Mode () == cursor .CursorBlink && (newRow != oldRow || newCol != oldCol ) {
1105
1120
m .Cursor .Blink = false
1106
- cmd = m .Cursor .BlinkCmd ()
1121
+ cmds = append (cmds , m .Cursor .BlinkCmd ())
1122
+ }
1123
+
1124
+ // Ensure the real cursor is at the correct position.
1125
+ row := m .cursorLineNumber ()
1126
+ lineInfo := m .LineInfo ()
1127
+ realCol , realRow := m .offsetX + lineInfo .ColumnOffset , m .offsetY + row - m .viewport .YOffset
1128
+ if realCol != m .realCol || realRow != m .realRow {
1129
+ m .realCol , m .realRow = realCol , realRow
1130
+ cmds = append (cmds , tea .SetCursorPosition (realCol , realRow ))
1107
1131
}
1108
- cmds = append (cmds , cmd )
1109
1132
1110
1133
m .repositionView ()
1111
1134
@@ -1183,7 +1206,9 @@ func (m Model) View() string {
1183
1206
wrappedLine = []rune (strings .TrimSuffix (string (wrappedLine ), " " ))
1184
1207
padding -= m .width - strwidth
1185
1208
}
1186
- if m .row == l && lineInfo .RowOffset == wl {
1209
+
1210
+ // We don't need to render the cursor if it's hidden.
1211
+ if m .Cursor .Mode () != cursor .CursorHide && m .row == l && lineInfo .RowOffset == wl {
1187
1212
s .WriteString (style .Render (string (wrappedLine [:lineInfo .ColumnOffset ])))
1188
1213
if m .col >= len (line ) && lineInfo .CharOffset >= m .width {
1189
1214
m .Cursor .SetChar (" " )
0 commit comments