@@ -156,12 +156,14 @@ fn (tv &TextView) on_click(layout &Layout, mut e Event, mut w Window) {
156156 )
157157 // Set cursor position and reset text selection
158158 cursor_pos := tv.mouse_cursor_pos (layout.shape, e, mut w)
159+ cursor_column := get_cursor_column (layout.shape.text_lines, cursor_pos)
159160 input_state := w.view_state.input_state[layout.shape.id_focus]
160161 w.view_state.input_state[layout.shape.id_focus] = InputState{
161162 ...input_state
162- cursor_pos: cursor_pos
163- select_beg: 0
164- select_end: 0
163+ cursor_pos: cursor_pos
164+ select_beg: 0
165+ select_end: 0
166+ cursor_column: cursor_column
165167 }
166168 e.is_handled = true
167169 }
@@ -297,13 +299,14 @@ fn (tv &TextView) mouse_cursor_pos(shape &Shape, e &Event, mut w Window) int {
297299// on_key_down handles keyboard input for navigation and text selection.
298300// It supports standard navigation keys (arrows, home, end) and modifiers
299301// (Alt, Ctrl, Shift) for word/line jumping and selection extension.
300- fn (tv &TextView) on_key_down (layout & Layout, mut e Event, mut w Window) {
301- if w .is_focus (layout.shape.id_focus) {
302+ fn (tv &TextView) on_key_down (layout & Layout, mut e Event, mut window Window) {
303+ if window .is_focus (layout.shape.id_focus) {
302304 if tv.placeholder_active {
303305 return
304306 }
305- mut current_input_state := w .view_state.input_state[layout.shape.id_focus]
307+ mut current_input_state := window .view_state.input_state[layout.shape.id_focus]
306308 mut new_cursor_pos := current_input_state.cursor_pos
309+ mut new_cursor_column := current_input_state.cursor_column
307310 text_lines := layout.shape.text_lines
308311
309312 // Handle navigation with modifiers
@@ -327,8 +330,8 @@ fn (tv &TextView) on_key_down(layout &Layout, mut e Event, mut w Window) {
327330 match e.key_code {
328331 .left { new_cursor_pos = cursor_left (new_cursor_pos) }
329332 .right { new_cursor_pos = cursor_right (text_lines, new_cursor_pos) }
330- .up { new_cursor_pos = cursor_up (text_lines, new_cursor_pos) }
331- .down { new_cursor_pos = cursor_down (text_lines, new_cursor_pos) }
333+ .up { new_cursor_pos = cursor_up (text_lines, new_cursor_pos, new_cursor_column ) }
334+ .down { new_cursor_pos = cursor_down (text_lines, new_cursor_pos, new_cursor_column ) }
332335 .home { new_cursor_pos = cursor_home () }
333336 .end { new_cursor_pos = cursor_end (text_lines) }
334337 else { return }
@@ -337,10 +340,14 @@ fn (tv &TextView) on_key_down(layout &Layout, mut e Event, mut w Window) {
337340 return
338341 }
339342
343+ if e.key_code != .up && e.key_code != .down {
344+ new_cursor_column = get_cursor_column (text_lines, new_cursor_pos)
345+ }
346+
340347 // input_cursor_on_sticky allows the cursor to stay on during cursor movements.
341348 // See `blinky_cursor_animation()`
342349 if new_cursor_pos != current_input_state.cursor_pos {
343- w .view_state.cursor_on_sticky = true
350+ window .view_state.cursor_on_sticky = true
344351 }
345352
346353 // ================================
@@ -390,15 +397,16 @@ fn (tv &TextView) on_key_down(layout &Layout, mut e Event, mut w Window) {
390397 }
391398
392399 // Update input state with new cursor position and selection
393- w .view_state.input_state[layout.shape.id_focus] = InputState{
400+ window .view_state.input_state[layout.shape.id_focus] = InputState{
394401 ...current_input_state
395- cursor_pos: new_cursor_pos
396- select_beg: new_select_beg
397- select_end: new_select_end
402+ cursor_pos: new_cursor_pos
403+ select_beg: new_select_beg
404+ select_end: new_select_end
405+ cursor_column: new_cursor_column
398406 }
399407
400408 // Ensure the new cursor position is visible
401- scroll_cursor_into_view (new_cursor_pos, layout, e, mut w )
409+ scroll_cursor_into_view (new_cursor_pos, layout, e, mut window )
402410 e.is_handled = true
403411 }
404412}
@@ -501,7 +509,7 @@ pub fn (tv &TextView) select_all(shape &Shape, mut w Window) {
501509 cursor_pos: len
502510 select_beg: 0
503511 select_end: u32 (len)
504- cursor_offset: 0
512+ cursor_column: len
505513 }
506514}
507515
@@ -515,6 +523,6 @@ pub fn (tv &TextView) unselect_all(mut w Window) {
515523 cursor_pos: 0
516524 select_beg: 0
517525 select_end: 0
518- cursor_offset : 0
526+ cursor_column : 0
519527 }
520528}
0 commit comments