@@ -189,10 +189,10 @@ contains |
| 189 | 189 | if (allocated(editor%tabs(editor%active_tab_index)%panes)) then |
| 190 | 190 | call render_cursor_for_panes(editor) |
| 191 | 191 | else |
| 192 | | - call render_cursor(editor) |
| 192 | + call render_cursor(editor, buffer) |
| 193 | 193 | end if |
| 194 | 194 | else |
| 195 | | - call render_cursor(editor) |
| 195 | + call render_cursor(editor, buffer) |
| 196 | 196 | end if |
| 197 | 197 | end subroutine render_screen |
| 198 | 198 | |
@@ -442,12 +442,15 @@ contains |
| 442 | 442 | call terminal_write(char(27) // '[0m') ! Reset attributes |
| 443 | 443 | end subroutine render_status_bar |
| 444 | 444 | |
| 445 | | - subroutine render_cursor(editor) |
| 445 | + subroutine render_cursor(editor, buffer) |
| 446 | 446 | type(editor_state_t), intent(in) :: editor |
| 447 | + type(buffer_t), intent(in) :: buffer |
| 447 | 448 | type(cursor_t) :: cursor |
| 448 | 449 | integer :: screen_row, screen_col |
| 449 | 450 | integer :: i |
| 450 | 451 | integer :: col_offset, row_offset, min_row |
| 452 | + character(len=:), allocatable :: line |
| 453 | + character :: cursor_char |
| 451 | 454 | |
| 452 | 455 | ! Calculate column offset for line numbers |
| 453 | 456 | if (show_line_numbers) then |
@@ -479,9 +482,17 @@ contains |
| 479 | 482 | ! Ensure cursor is within screen bounds and not in tab bar |
| 480 | 483 | if (screen_row >= min_row .and. screen_row < editor%screen_rows .and. & |
| 481 | 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 | 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 | 496 | call terminal_write(char(27) // '[0m') ! Reset |
| 486 | 497 | end if |
| 487 | 498 | end if |
@@ -1069,11 +1080,13 @@ contains |
| 1069 | 1080 | type(editor_state_t), intent(in) :: editor |
| 1070 | 1081 | type(pane_t) :: pane |
| 1071 | 1082 | type(cursor_t) :: cursor |
| 1072 | | - integer :: tab_idx, pane_idx |
| 1083 | + integer :: tab_idx, pane_idx, i |
| 1073 | 1084 | integer :: pane_col, pane_row, pane_width, pane_height |
| 1074 | 1085 | integer :: screen_row, screen_col |
| 1075 | 1086 | integer :: screen_width, screen_height |
| 1076 | 1087 | integer :: col_offset |
| 1088 | + character(len=:), allocatable :: line |
| 1089 | + character :: cursor_char |
| 1077 | 1090 | |
| 1078 | 1091 | tab_idx = editor%active_tab_index |
| 1079 | 1092 | if (tab_idx < 1 .or. tab_idx > size(editor%tabs)) return |
@@ -1086,8 +1099,6 @@ contains |
| 1086 | 1099 | if (.not. allocated(pane%cursors)) return |
| 1087 | 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 | 1102 | ! Calculate column offset for line numbers |
| 1092 | 1103 | if (show_line_numbers) then |
| 1093 | 1104 | col_offset = LINE_NUMBER_WIDTH + 1 ! +1 for separator space |
@@ -1107,6 +1118,39 @@ contains |
| 1107 | 1118 | pane_row = 2 + int(pane%y_start * real(screen_height)) |
| 1108 | 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 | 1154 | ! Calculate cursor position within the pane, accounting for line numbers |
| 1111 | 1155 | screen_row = pane_row + (cursor%line - pane%viewport_line) |
| 1112 | 1156 | screen_col = pane_col + col_offset + (cursor%column - pane%viewport_column) |