@@ -189,10 +189,10 @@ contains |
| 189 | if (allocated(editor%tabs(editor%active_tab_index)%panes)) then | 189 | if (allocated(editor%tabs(editor%active_tab_index)%panes)) then |
| 190 | call render_cursor_for_panes(editor) | 190 | call render_cursor_for_panes(editor) |
| 191 | else | 191 | else |
| 192 | - call render_cursor(editor) | 192 | + call render_cursor(editor, buffer) |
| 193 | end if | 193 | end if |
| 194 | else | 194 | else |
| 195 | - call render_cursor(editor) | 195 | + call render_cursor(editor, buffer) |
| 196 | end if | 196 | end if |
| 197 | end subroutine render_screen | 197 | end subroutine render_screen |
| 198 | | 198 | |
@@ -442,12 +442,15 @@ contains |
| 442 | call terminal_write(char(27) // '[0m') ! Reset attributes | 442 | call terminal_write(char(27) // '[0m') ! Reset attributes |
| 443 | end subroutine render_status_bar | 443 | end subroutine render_status_bar |
| 444 | | 444 | |
| 445 | - subroutine render_cursor(editor) | 445 | + subroutine render_cursor(editor, buffer) |
| 446 | type(editor_state_t), intent(in) :: editor | 446 | type(editor_state_t), intent(in) :: editor |
| | 447 | + type(buffer_t), intent(in) :: buffer |
| 447 | type(cursor_t) :: cursor | 448 | type(cursor_t) :: cursor |
| 448 | integer :: screen_row, screen_col | 449 | integer :: screen_row, screen_col |
| 449 | integer :: i | 450 | integer :: i |
| 450 | integer :: col_offset, row_offset, min_row | 451 | integer :: col_offset, row_offset, min_row |
| | 452 | + character(len=:), allocatable :: line |
| | 453 | + character :: cursor_char |
| 451 | | 454 | |
| 452 | ! Calculate column offset for line numbers | 455 | ! Calculate column offset for line numbers |
| 453 | if (show_line_numbers) then | 456 | if (show_line_numbers) then |
@@ -479,9 +482,17 @@ contains |
| 479 | ! Ensure cursor is within screen bounds and not in tab bar | 482 | ! Ensure cursor is within screen bounds and not in tab bar |
| 480 | if (screen_row >= min_row .and. screen_row < editor%screen_rows .and. & | 483 | if (screen_row >= min_row .and. screen_row < editor%screen_rows .and. & |
| 481 | screen_col >= 1 .and. screen_col <= editor%screen_cols) then | 484 | screen_col >= 1 .and. screen_col <= editor%screen_cols) then |
| 482 | - ! Inactive cursor - draw with reverse video block | 485 | + ! Get the character at this cursor position |
| | 486 | + line = buffer_get_line(buffer, cursor%line) |
| | 487 | + if (cursor%column <= len(line)) then |
| | 488 | + cursor_char = line(cursor%column:cursor%column) |
| | 489 | + else |
| | 490 | + cursor_char = ' ' ! End of line |
| | 491 | + end if |
| | 492 | + |
| | 493 | + ! Inactive cursor - draw character with reverse video |
| 483 | call terminal_move_cursor(screen_row, screen_col) | 494 | call terminal_move_cursor(screen_row, screen_col) |
| 484 | - call terminal_write(char(27) // '[7m ') ! Inverse video space | 495 | + call terminal_write(char(27) // '[7m' // cursor_char) ! Inverse video |
| 485 | call terminal_write(char(27) // '[0m') ! Reset | 496 | call terminal_write(char(27) // '[0m') ! Reset |
| 486 | end if | 497 | end if |
| 487 | end if | 498 | end if |
@@ -1069,11 +1080,13 @@ contains |
| 1069 | type(editor_state_t), intent(in) :: editor | 1080 | type(editor_state_t), intent(in) :: editor |
| 1070 | type(pane_t) :: pane | 1081 | type(pane_t) :: pane |
| 1071 | type(cursor_t) :: cursor | 1082 | type(cursor_t) :: cursor |
| 1072 | - integer :: tab_idx, pane_idx | 1083 | + integer :: tab_idx, pane_idx, i |
| 1073 | integer :: pane_col, pane_row, pane_width, pane_height | 1084 | integer :: pane_col, pane_row, pane_width, pane_height |
| 1074 | integer :: screen_row, screen_col | 1085 | integer :: screen_row, screen_col |
| 1075 | integer :: screen_width, screen_height | 1086 | integer :: screen_width, screen_height |
| 1076 | integer :: col_offset | 1087 | integer :: col_offset |
| | 1088 | + character(len=:), allocatable :: line |
| | 1089 | + character :: cursor_char |
| 1077 | | 1090 | |
| 1078 | tab_idx = editor%active_tab_index | 1091 | tab_idx = editor%active_tab_index |
| 1079 | if (tab_idx < 1 .or. tab_idx > size(editor%tabs)) return | 1092 | if (tab_idx < 1 .or. tab_idx > size(editor%tabs)) return |
@@ -1086,8 +1099,6 @@ contains |
| 1086 | if (.not. allocated(pane%cursors)) return | 1099 | if (.not. allocated(pane%cursors)) return |
| 1087 | if (pane%active_cursor < 1 .or. pane%active_cursor > size(pane%cursors)) return | 1100 | if (pane%active_cursor < 1 .or. pane%active_cursor > size(pane%cursors)) return |
| 1088 | | 1101 | |
| 1089 | - cursor = pane%cursors(pane%active_cursor) | | |
| 1090 | - | | |
| 1091 | ! Calculate column offset for line numbers | 1102 | ! Calculate column offset for line numbers |
| 1092 | if (show_line_numbers) then | 1103 | if (show_line_numbers) then |
| 1093 | col_offset = LINE_NUMBER_WIDTH + 1 ! +1 for separator space | 1104 | col_offset = LINE_NUMBER_WIDTH + 1 ! +1 for separator space |
@@ -1107,6 +1118,39 @@ contains |
| 1107 | pane_row = 2 + int(pane%y_start * real(screen_height)) | 1118 | pane_row = 2 + int(pane%y_start * real(screen_height)) |
| 1108 | pane_height = int((pane%y_end - pane%y_start) * real(screen_height)) | 1119 | pane_height = int((pane%y_end - pane%y_start) * real(screen_height)) |
| 1109 | | 1120 | |
| | 1121 | + ! For multiple cursors, render all inactive ones first |
| | 1122 | + if (size(pane%cursors) > 1) then |
| | 1123 | + do i = 1, size(pane%cursors) |
| | 1124 | + if (i /= pane%active_cursor) then |
| | 1125 | + cursor = pane%cursors(i) |
| | 1126 | + |
| | 1127 | + ! Calculate cursor position within the pane |
| | 1128 | + screen_row = pane_row + (cursor%line - pane%viewport_line) |
| | 1129 | + screen_col = pane_col + col_offset + (cursor%column - pane%viewport_column) |
| | 1130 | + |
| | 1131 | + ! Ensure cursor is within pane boundaries |
| | 1132 | + if (screen_row >= pane_row .and. screen_row < pane_row + pane_height .and. & |
| | 1133 | + screen_col >= pane_col + col_offset .and. screen_col < pane_col + pane_width) then |
| | 1134 | + ! Get the character at this cursor position |
| | 1135 | + line = buffer_get_line(editor%tabs(tab_idx)%buffer, cursor%line) |
| | 1136 | + if (cursor%column <= len(line)) then |
| | 1137 | + cursor_char = line(cursor%column:cursor%column) |
| | 1138 | + else |
| | 1139 | + cursor_char = ' ' ! End of line |
| | 1140 | + end if |
| | 1141 | + |
| | 1142 | + ! Inactive cursor - draw character with reverse video |
| | 1143 | + call terminal_move_cursor(screen_row, screen_col) |
| | 1144 | + call terminal_write(char(27) // '[7m' // cursor_char) ! Inverse video |
| | 1145 | + call terminal_write(char(27) // '[0m') ! Reset |
| | 1146 | + end if |
| | 1147 | + end if |
| | 1148 | + end do |
| | 1149 | + end if |
| | 1150 | + |
| | 1151 | + ! Now render the active cursor |
| | 1152 | + cursor = pane%cursors(pane%active_cursor) |
| | 1153 | + |
| 1110 | ! Calculate cursor position within the pane, accounting for line numbers | 1154 | ! Calculate cursor position within the pane, accounting for line numbers |
| 1111 | screen_row = pane_row + (cursor%line - pane%viewport_line) | 1155 | screen_row = pane_row + (cursor%line - pane%viewport_line) |
| 1112 | screen_col = pane_col + col_offset + (cursor%column - pane%viewport_column) | 1156 | screen_col = pane_col + col_offset + (cursor%column - pane%viewport_column) |