fix multiple rename issue
- SHA
5c5a6f9f332b266862a2c254437bca84d09758c5- Parents
-
b44a816 - Tree
92fb770
5c5a6f9
5c5a6f9f332b266862a2c254437bca84d09758c5b44a816
92fb770| Status | File | + | - |
|---|---|---|---|
| M |
app/main.f90
|
0 | 50 |
| M |
src/commands/command_handler_module.f90
|
107 | 9 |
| M |
src/lsp/diagnostics_module.f90
|
1 | 19 |
| M |
src/lsp/lsp_protocol_module.f90
|
1 | 11 |
| M |
src/lsp/lsp_server_manager_module.f90
|
15 | 319 |
| M |
src/terminal/input_handler_module.f90
|
59 | 91 |
| M |
src/ui/help_display_module.f90
|
7 | 7 |
| M |
src/ui/rename_prompt_module.f90
|
0 | 25 |
| M |
src/workspace/workspace_module.f90
|
3 | 53 |
| M |
tests/scratch_files/calculator.py
|
1 | 0 |
| M |
tests/scratch_files/long_errors.py
|
1 | 1 |
app/main.f90modified@@ -119,62 +119,42 @@ program facsimile | |||
| 119 | ! User selected a workspace from welcome menu (not browse) | 119 | ! User selected a workspace from welcome menu (not browse) |
| 120 | ! This handles favorites, recents, and CURRENT DIRECTORY | 120 | ! This handles favorites, recents, and CURRENT DIRECTORY |
| 121 | if (allocated(selected_path) .and. .not. is_browse) then | 121 | if (allocated(selected_path) .and. .not. is_browse) then |
| 122 | - write(0, '(A)') '[DEBUG WELCOME] selected_path allocated, value: ' // selected_path | ||
| 123 | - write(0, '(A,L1)') '[DEBUG WELCOME] is_browse: ', is_browse | ||
| 124 | - | ||
| 125 | ! Check if user selected CURRENT DIRECTORY option | 122 | ! Check if user selected CURRENT DIRECTORY option |
| 126 | if (selected_path == "CWD") then | 123 | if (selected_path == "CWD") then |
| 127 | - write(0, '(A)') '[DEBUG WELCOME] CWD selected, getting workspace path' | ||
| 128 | ! Get actual current working directory | 124 | ! Get actual current working directory |
| 129 | call get_workspace_path(selected_path) | 125 | call get_workspace_path(selected_path) |
| 130 | - write(0, '(A)') '[DEBUG WELCOME] Workspace path: ' // selected_path | ||
| 131 | arg = selected_path | 126 | arg = selected_path |
| 132 | else | 127 | else |
| 133 | - write(0, '(A)') '[DEBUG WELCOME] Not CWD, using selected_path directly' | ||
| 134 | arg = selected_path | 128 | arg = selected_path |
| 135 | end if | 129 | end if |
| 136 | 130 | ||
| 137 | ! Check if it's a directory | 131 | ! Check if it's a directory |
| 138 | - write(0, '(A)') '[DEBUG WELCOME] Testing if directory: ' // trim(arg) | ||
| 139 | call execute_command_line("test -d '" // trim(arg) // & | 132 | call execute_command_line("test -d '" // trim(arg) // & |
| 140 | "' && echo 'Directory' > /tmp/.fac_filetype || " // & | 133 | "' && echo 'Directory' > /tmp/.fac_filetype || " // & |
| 141 | "echo 'File' > /tmp/.fac_filetype", wait=.true.) | 134 | "echo 'File' > /tmp/.fac_filetype", wait=.true.) |
| 142 | call read_file_type(status) | 135 | call read_file_type(status) |
| 143 | - write(0, '(A,I0)') '[DEBUG WELCOME] read_file_type status: ', status | ||
| 144 | if (status == 0) then | 136 | if (status == 0) then |
| 145 | ! Directory - workspace mode | 137 | ! Directory - workspace mode |
| 146 | - write(0, '(A)') '[DEBUG WELCOME] Setting is_workspace_mode = TRUE' | ||
| 147 | is_workspace_mode = .true. | 138 | is_workspace_mode = .true. |
| 148 | call workspace_get_path(trim(arg), workspace_dir) | 139 | call workspace_get_path(trim(arg), workspace_dir) |
| 149 | - write(0, '(A)') '[DEBUG WELCOME] workspace_dir: ' // trim(workspace_dir) | ||
| 150 | else | 140 | else |
| 151 | ! Invalid selection (favorites/recents should only have directories) | 141 | ! Invalid selection (favorites/recents should only have directories) |
| 152 | write(error_unit, '(A)') 'Error: Selected path is not a directory' | 142 | write(error_unit, '(A)') 'Error: Selected path is not a directory' |
| 153 | stop 1 | 143 | stop 1 |
| 154 | end if | 144 | end if |
| 155 | - else | ||
| 156 | - write(0, '(A,L1)') '[DEBUG WELCOME] selected_path allocated: ', allocated(selected_path) | ||
| 157 | - if (allocated(selected_path)) then | ||
| 158 | - write(0, '(A)') '[DEBUG WELCOME] selected_path value: ' // selected_path | ||
| 159 | - end if | ||
| 160 | - write(0, '(A,L1)') '[DEBUG WELCOME] is_browse: ', is_browse | ||
| 161 | end if | 145 | end if |
| 162 | end if | 146 | end if |
| 163 | 147 | ||
| 164 | ! Handle workspace mode | 148 | ! Handle workspace mode |
| 165 | - write(0, '(A,L1)') '[DEBUG WORKSPACE] is_workspace_mode: ', is_workspace_mode | ||
| 166 | if (is_workspace_mode) then | 149 | if (is_workspace_mode) then |
| 167 | - write(0, '(A)') '[DEBUG WORKSPACE] In workspace mode, workspace_dir: ' // trim(workspace_dir) | ||
| 168 | ! Check if workspace exists, create if not | 150 | ! Check if workspace exists, create if not |
| 169 | if (.not. workspace_exists(workspace_dir)) then | 151 | if (.not. workspace_exists(workspace_dir)) then |
| 170 | - write(0, '(A)') '[DEBUG WORKSPACE] Workspace does not exist, creating' | ||
| 171 | call workspace_init(workspace_dir, workspace_success) | 152 | call workspace_init(workspace_dir, workspace_success) |
| 172 | if (.not. workspace_success) then | 153 | if (.not. workspace_success) then |
| 173 | write(error_unit, '(A)') 'Error: Failed to create workspace' | 154 | write(error_unit, '(A)') 'Error: Failed to create workspace' |
| 174 | stop 1 | 155 | stop 1 |
| 175 | end if | 156 | end if |
| 176 | else | 157 | else |
| 177 | - write(0, '(A)') '[DEBUG WORKSPACE] Workspace exists, loading' | ||
| 178 | ! Load existing workspace | 158 | ! Load existing workspace |
| 179 | call workspace_load(workspace_dir, workspace_success) | 159 | call workspace_load(workspace_dir, workspace_success) |
| 180 | if (.not. workspace_success) then | 160 | if (.not. workspace_success) then |
@@ -182,8 +162,6 @@ program facsimile | |||
| 182 | stop 1 | 162 | stop 1 |
| 183 | end if | 163 | end if |
| 184 | end if | 164 | end if |
| 185 | - else | ||
| 186 | - write(0, '(A)') '[DEBUG WORKSPACE] NOT in workspace mode' | ||
| 187 | end if | 165 | end if |
| 188 | 166 | ||
| 189 | ! Initialize editor | 167 | ! Initialize editor |
@@ -204,46 +182,23 @@ program facsimile | |||
| 204 | call init_buffer(buffer) | 182 | call init_buffer(buffer) |
| 205 | 183 | ||
| 206 | ! Set workspace path | 184 | ! Set workspace path |
| 207 | - write(0, '(A,L1)') '[DEBUG RESTORE CHECK] is_workspace_mode: ', is_workspace_mode | ||
| 208 | if (is_workspace_mode) then | 185 | if (is_workspace_mode) then |
| 209 | - write(0, '(A)') '[DEBUG RESTORE CHECK] workspace_dir: ' // trim(workspace_dir) | ||
| 210 | ! Use detected/created workspace directory | 186 | ! Use detected/created workspace directory |
| 211 | allocate(character(len=len_trim(workspace_dir)) :: editor%workspace_path) | 187 | allocate(character(len=len_trim(workspace_dir)) :: editor%workspace_path) |
| 212 | editor%workspace_path = trim(workspace_dir) | 188 | editor%workspace_path = trim(workspace_dir) |
| 213 | 189 | ||
| 214 | - ! DEBUG: Print before restoration (unit 0 = stderr) | ||
| 215 | - write(0, '(A)') '[DEBUG RESTORE] About to restore workspace from: ' // trim(editor%workspace_path) | ||
| 216 | - write(0, '(A)') '[DEBUG RESTORE] Workspace JSON path: ' // trim(editor%workspace_path) // '/.fac/workspace.json' | ||
| 217 | - | ||
| 218 | ! Restore workspace state (tabs, cursor positions, etc.) | 190 | ! Restore workspace state (tabs, cursor positions, etc.) |
| 219 | call workspace_restore_state(editor, editor%workspace_path, workspace_success) | 191 | call workspace_restore_state(editor, editor%workspace_path, workspace_success) |
| 220 | 192 | ||
| 221 | - ! DEBUG: Print restoration results | ||
| 222 | - write(0, '(A,L1)') '[DEBUG RESTORE] Workspace restore success: ', workspace_success | ||
| 223 | - if (allocated(editor%tabs)) then | ||
| 224 | - write(0, '(A,I0)') '[DEBUG RESTORE] Number of tabs restored: ', size(editor%tabs) | ||
| 225 | - else | ||
| 226 | - write(0, '(A)') '[DEBUG RESTORE] No tabs allocated after restore' | ||
| 227 | - end if | ||
| 228 | - write(0, '(A,I0)') '[DEBUG RESTORE] Active tab index: ', editor%active_tab_index | ||
| 229 | - | ||
| 230 | ! Sync restored active tab's buffer to main buffer | 193 | ! Sync restored active tab's buffer to main buffer |
| 231 | if (workspace_success .and. allocated(editor%tabs) .and. editor%active_tab_index > 0) then | 194 | if (workspace_success .and. allocated(editor%tabs) .and. editor%active_tab_index > 0) then |
| 232 | if (editor%active_tab_index <= size(editor%tabs)) then | 195 | if (editor%active_tab_index <= size(editor%tabs)) then |
| 233 | if (allocated(editor%tabs(editor%active_tab_index)%panes) .and. & | 196 | if (allocated(editor%tabs(editor%active_tab_index)%panes) .and. & |
| 234 | size(editor%tabs(editor%active_tab_index)%panes) > 0) then | 197 | size(editor%tabs(editor%active_tab_index)%panes) > 0) then |
| 235 | ! Copy active pane's buffer to main buffer (replaces the empty init) | 198 | ! Copy active pane's buffer to main buffer (replaces the empty init) |
| 236 | - write(0, '(A)') '[DEBUG RESTORE] Copying restored tab buffer to main buffer' | ||
| 237 | call copy_buffer(buffer, editor%tabs(editor%active_tab_index)%panes(1)%buffer) | 199 | call copy_buffer(buffer, editor%tabs(editor%active_tab_index)%panes(1)%buffer) |
| 238 | - else | ||
| 239 | - write(0, '(A)') '[DEBUG RESTORE] Active tab has no panes!' | ||
| 240 | end if | 200 | end if |
| 241 | - else | ||
| 242 | - write(0, '(A,I0,A,I0)') '[DEBUG RESTORE] Active tab index ', editor%active_tab_index, & | ||
| 243 | - ' exceeds tab count ', size(editor%tabs) | ||
| 244 | end if | 201 | end if |
| 245 | - else | ||
| 246 | - write(0, '(A)') '[DEBUG RESTORE] Skipping buffer sync - conditions not met' | ||
| 247 | end if | 202 | end if |
| 248 | else | 203 | else |
| 249 | ! Single-file mode - use current directory | 204 | ! Single-file mode - use current directory |
@@ -515,11 +470,6 @@ contains | |||
| 515 | use terminal_io_module, only: terminal_write | 470 | use terminal_io_module, only: terminal_write |
| 516 | type(lsp_message_t), intent(in) :: notification | 471 | type(lsp_message_t), intent(in) :: notification |
| 517 | integer, intent(in) :: server_index | 472 | integer, intent(in) :: server_index |
| 518 | - character(len=256) :: debug_msg | ||
| 519 | - | ||
| 520 | - ! Debug: Log when diagnostics are received | ||
| 521 | - write(debug_msg, '(A,I0)') "[DEBUG] Received diagnostics from server ", server_index | ||
| 522 | - call terminal_write(debug_msg) ! Debug output enabled | ||
| 523 | 473 | ||
| 524 | ! Parse and store diagnostics with server attribution (for multi-LSP) | 474 | ! Parse and store diagnostics with server attribution (for multi-LSP) |
| 525 | ! This keeps diagnostics from different servers separate | 475 | ! This keeps diagnostics from different servers separate |
src/commands/command_handler_module.f90modified@@ -1386,15 +1386,15 @@ contains | |||
| 1386 | 1386 | ||
| 1387 | ! Check if rename response modified the buffer | 1387 | ! Check if rename response modified the buffer |
| 1388 | if (g_lsp_modified_buffer) then | 1388 | if (g_lsp_modified_buffer) then |
| 1389 | - ! Sync buffer from tab (LSP modified tab buffer) | 1389 | + ! LSP now modifies pane buffer directly, sync FROM pane TO local buffer and tab |
| 1390 | - call copy_buffer(buffer, editor%tabs(editor%active_tab_index)%buffer) | ||
| 1391 | - | ||
| 1392 | - ! Also sync to active pane buffer if panes exist | ||
| 1393 | if (allocated(editor%tabs(editor%active_tab_index)%panes) .and. & | 1390 | if (allocated(editor%tabs(editor%active_tab_index)%panes) .and. & |
| 1394 | size(editor%tabs(editor%active_tab_index)%panes) > 0) then | 1391 | size(editor%tabs(editor%active_tab_index)%panes) > 0) then |
| 1395 | pane_idx = editor%tabs(editor%active_tab_index)%active_pane_index | 1392 | pane_idx = editor%tabs(editor%active_tab_index)%active_pane_index |
| 1396 | if (pane_idx > 0 .and. pane_idx <= size(editor%tabs(editor%active_tab_index)%panes)) then | 1393 | if (pane_idx > 0 .and. pane_idx <= size(editor%tabs(editor%active_tab_index)%panes)) then |
| 1397 | - call copy_buffer(editor%tabs(editor%active_tab_index)%panes(pane_idx)%buffer, buffer) | 1394 | + ! Copy FROM pane buffer TO local buffer (for rendering) |
| 1395 | + call copy_buffer(buffer, editor%tabs(editor%active_tab_index)%panes(pane_idx)%buffer) | ||
| 1396 | + ! Also sync to tab buffer (to keep them consistent) | ||
| 1397 | + call copy_buffer(editor%tabs(editor%active_tab_index)%buffer, buffer) | ||
| 1398 | end if | 1398 | end if |
| 1399 | end if | 1399 | end if |
| 1400 | 1400 | ||
@@ -6313,14 +6313,16 @@ contains | |||
| 6313 | subroutine apply_file_edits_obj(editor, uri, edits_arr, changes_applied) | 6313 | subroutine apply_file_edits_obj(editor, uri, edits_arr, changes_applied) |
| 6314 | use json_module, only: json_value_t, json_array_size, json_get_array_element, & | 6314 | use json_module, only: json_value_t, json_array_size, json_get_array_element, & |
| 6315 | json_get_object, json_get_string, json_get_number, json_has_key | 6315 | json_get_object, json_get_string, json_get_number, json_has_key |
| 6316 | + use text_buffer_module, only: buffer_to_string | ||
| 6317 | + use lsp_server_manager_module, only: notify_file_changed | ||
| 6316 | type(editor_state_t), intent(inout) :: editor | 6318 | type(editor_state_t), intent(inout) :: editor |
| 6317 | character(len=*), intent(in) :: uri | 6319 | character(len=*), intent(in) :: uri |
| 6318 | type(json_value_t), intent(in) :: edits_arr | 6320 | type(json_value_t), intent(in) :: edits_arr |
| 6319 | integer, intent(inout) :: changes_applied | 6321 | integer, intent(inout) :: changes_applied |
| 6320 | 6322 | ||
| 6321 | type(json_value_t) :: edit_obj, range_obj, start_obj, end_obj | 6323 | type(json_value_t) :: edit_obj, range_obj, start_obj, end_obj |
| 6322 | - character(len=:), allocatable :: filename, new_text | 6324 | + character(len=:), allocatable :: filename, new_text, buffer_content |
| 6323 | - integer :: num_edits, i, j, tab_idx | 6325 | + integer :: num_edits, i, j, tab_idx, server_idx, pane_idx |
| 6324 | integer :: start_line, start_char, end_line, end_char | 6326 | integer :: start_line, start_char, end_line, end_char |
| 6325 | 6327 | ||
| 6326 | ! Convert URI to filename | 6328 | ! Convert URI to filename |
@@ -6356,6 +6358,25 @@ contains | |||
| 6356 | return | 6358 | return |
| 6357 | end if | 6359 | end if |
| 6358 | 6360 | ||
| 6361 | + ! Get the active pane for this tab (panes contain the actual buffers) | ||
| 6362 | + pane_idx = editor%tabs(tab_idx)%active_pane_index | ||
| 6363 | + if (pane_idx < 1 .or. .not. allocated(editor%tabs(tab_idx)%panes)) then | ||
| 6364 | + pane_idx = 1 ! Default to first pane | ||
| 6365 | + end if | ||
| 6366 | + if (pane_idx > size(editor%tabs(tab_idx)%panes)) then | ||
| 6367 | + if (allocated(filename)) deallocate(filename) | ||
| 6368 | + return | ||
| 6369 | + end if | ||
| 6370 | + | ||
| 6371 | + ! Debug: log tab_idx finding | ||
| 6372 | + open(newunit=server_idx, file='/tmp/fac_tab_debug.log', status='unknown', & | ||
| 6373 | + position='append', action='write') | ||
| 6374 | + write(server_idx, '(A,I3,A,I3)') 'Found tab_idx=', tab_idx, ' pane_idx=', pane_idx | ||
| 6375 | + write(server_idx, '(A,A)') 'Extracted filename: ', trim(filename) | ||
| 6376 | + write(server_idx, '(A,A)') 'Tab filename: ', trim(editor%tabs(tab_idx)%filename) | ||
| 6377 | + write(server_idx, '(A)') '---' | ||
| 6378 | + close(server_idx) | ||
| 6379 | + | ||
| 6359 | ! Apply edits in reverse order (to preserve line numbers) | 6380 | ! Apply edits in reverse order (to preserve line numbers) |
| 6360 | num_edits = json_array_size(edits_arr) | 6381 | num_edits = json_array_size(edits_arr) |
| 6361 | 6382 | ||
@@ -6379,15 +6400,53 @@ contains | |||
| 6379 | new_text = json_get_string(edit_obj, 'newText') | 6400 | new_text = json_get_string(edit_obj, 'newText') |
| 6380 | 6401 | ||
| 6381 | if (allocated(new_text)) then | 6402 | if (allocated(new_text)) then |
| 6382 | - ! Apply the edit to the buffer | 6403 | + ! Apply the edit to the pane buffer (not tab buffer!) |
| 6383 | - call apply_single_edit(editor%tabs(tab_idx)%buffer, & | 6404 | + call apply_single_edit(editor%tabs(tab_idx)%panes(pane_idx)%buffer, & |
| 6384 | start_line, start_char, end_line, end_char, new_text) | 6405 | start_line, start_char, end_line, end_char, new_text) |
| 6385 | changes_applied = changes_applied + 1 | 6406 | changes_applied = changes_applied + 1 |
| 6407 | + | ||
| 6408 | + ! Debug: check buffer size after edit | ||
| 6409 | + block | ||
| 6410 | + character(len=:), allocatable :: check_content | ||
| 6411 | + integer :: check_unit | ||
| 6412 | + check_content = buffer_to_string(editor%tabs(tab_idx)%panes(pane_idx)%buffer) | ||
| 6413 | + open(newunit=check_unit, file='/tmp/fac_after_edit.log', status='unknown', & | ||
| 6414 | + position='append', action='write') | ||
| 6415 | + write(check_unit, '(A,I8)') 'After edit, buffer len: ', len(check_content) | ||
| 6416 | + close(check_unit) | ||
| 6417 | + if (allocated(check_content)) deallocate(check_content) | ||
| 6418 | + end block | ||
| 6419 | + | ||
| 6386 | deallocate(new_text) | 6420 | deallocate(new_text) |
| 6387 | end if | 6421 | end if |
| 6388 | end if | 6422 | end if |
| 6389 | end do | 6423 | end do |
| 6390 | 6424 | ||
| 6425 | + ! Sync the changed document back to all LSP servers | ||
| 6426 | + if (changes_applied > 0) then | ||
| 6427 | + buffer_content = buffer_to_string(editor%tabs(tab_idx)%panes(pane_idx)%buffer) | ||
| 6428 | + if (allocated(buffer_content)) then | ||
| 6429 | + ! Debug: log what we're about to sync | ||
| 6430 | + open(newunit=server_idx, file='/tmp/fac_sync_debug.log', status='unknown', & | ||
| 6431 | + position='append', action='write') | ||
| 6432 | + write(server_idx, '(A,I4)') 'Sync after changes_applied=', changes_applied | ||
| 6433 | + write(server_idx, '(A,I8)') 'Buffer content length: ', len(buffer_content) | ||
| 6434 | + write(server_idx, '(A,A)') 'First 100 chars: ', buffer_content(1:min(100,len(buffer_content))) | ||
| 6435 | + write(server_idx, '(A)') '---' | ||
| 6436 | + close(server_idx) | ||
| 6437 | + | ||
| 6438 | + ! Notify all active LSP servers about the document change | ||
| 6439 | + ! Use the absolute path from the URI (filename variable) not the tab's relative path | ||
| 6440 | + do server_idx = 1, editor%lsp_manager%num_servers | ||
| 6441 | + if (editor%lsp_manager%servers(server_idx)%initialized) then | ||
| 6442 | + call notify_file_changed(editor%lsp_manager, server_idx, & | ||
| 6443 | + 'file://' // filename, buffer_content) | ||
| 6444 | + end if | ||
| 6445 | + end do | ||
| 6446 | + deallocate(buffer_content) | ||
| 6447 | + end if | ||
| 6448 | + end if | ||
| 6449 | + | ||
| 6391 | if (allocated(filename)) deallocate(filename) | 6450 | if (allocated(filename)) deallocate(filename) |
| 6392 | end subroutine apply_file_edits_obj | 6451 | end subroutine apply_file_edits_obj |
| 6393 | 6452 | ||
@@ -6398,23 +6457,62 @@ contains | |||
| 6398 | character(len=*), intent(in) :: new_text | 6457 | character(len=*), intent(in) :: new_text |
| 6399 | 6458 | ||
| 6400 | integer :: start_pos, end_pos, delete_count | 6459 | integer :: start_pos, end_pos, delete_count |
| 6460 | + integer :: debug_unit | ||
| 6461 | + character(len=256) :: debug_msg | ||
| 6401 | 6462 | ||
| 6402 | ! Calculate buffer positions | 6463 | ! Calculate buffer positions |
| 6403 | start_pos = get_buffer_position(buffer, start_line, start_char) | 6464 | start_pos = get_buffer_position(buffer, start_line, start_char) |
| 6404 | end_pos = get_buffer_position(buffer, end_line, end_char) | 6465 | end_pos = get_buffer_position(buffer, end_line, end_char) |
| 6405 | 6466 | ||
| 6467 | + ! Debug logging | ||
| 6468 | + open(newunit=debug_unit, file='/tmp/fac_edit_debug.log', status='unknown', & | ||
| 6469 | + position='append', action='write') | ||
| 6470 | + write(debug_msg, '(A,I4,A,I4,A,I4,A,I4)') 'Edit range: line ', start_line, & | ||
| 6471 | + ' char ', start_char, ' to line ', end_line, ' char ', end_char | ||
| 6472 | + write(debug_unit, '(A)') trim(debug_msg) | ||
| 6473 | + write(debug_msg, '(A,I6,A,I6,A,I4)') 'Buffer pos: start=', start_pos, & | ||
| 6474 | + ' end=', end_pos, ' delete_count=', end_pos - start_pos | ||
| 6475 | + write(debug_unit, '(A)') trim(debug_msg) | ||
| 6476 | + write(debug_msg, '(A,I4,A,A,A)') 'New text len=', len(new_text), ' text="', new_text, '"' | ||
| 6477 | + write(debug_unit, '(A)') trim(debug_msg) | ||
| 6478 | + write(debug_unit, '(A)') '---' | ||
| 6479 | + close(debug_unit) | ||
| 6480 | + | ||
| 6406 | if (start_pos <= 0 .or. end_pos <= 0) return | 6481 | if (start_pos <= 0 .or. end_pos <= 0) return |
| 6407 | 6482 | ||
| 6408 | ! Delete the old text | 6483 | ! Delete the old text |
| 6409 | delete_count = end_pos - start_pos | 6484 | delete_count = end_pos - start_pos |
| 6485 | + | ||
| 6486 | + ! Debug: log gap buffer state before operations | ||
| 6487 | + open(newunit=debug_unit, file='/tmp/fac_gap_debug.log', status='unknown', & | ||
| 6488 | + position='append', action='write') | ||
| 6489 | + write(debug_unit, '(A,I6,A,I6,A,I6)') 'BEFORE: gap_start=', buffer%gap_start, & | ||
| 6490 | + ' gap_end=', buffer%gap_end, ' size=', buffer%size | ||
| 6491 | + close(debug_unit) | ||
| 6492 | + | ||
| 6410 | if (delete_count > 0) then | 6493 | if (delete_count > 0) then |
| 6411 | call buffer_delete(buffer, start_pos, delete_count) | 6494 | call buffer_delete(buffer, start_pos, delete_count) |
| 6412 | end if | 6495 | end if |
| 6413 | 6496 | ||
| 6497 | + ! Debug: log gap buffer state after delete | ||
| 6498 | + open(newunit=debug_unit, file='/tmp/fac_gap_debug.log', status='unknown', & | ||
| 6499 | + position='append', action='write') | ||
| 6500 | + write(debug_unit, '(A,I6,A,I6,A,I6)') 'AFTER DELETE: gap_start=', buffer%gap_start, & | ||
| 6501 | + ' gap_end=', buffer%gap_end, ' size=', buffer%size | ||
| 6502 | + close(debug_unit) | ||
| 6503 | + | ||
| 6414 | ! Insert the new text | 6504 | ! Insert the new text |
| 6415 | if (len(new_text) > 0) then | 6505 | if (len(new_text) > 0) then |
| 6416 | call buffer_insert(buffer, start_pos, new_text) | 6506 | call buffer_insert(buffer, start_pos, new_text) |
| 6417 | end if | 6507 | end if |
| 6508 | + | ||
| 6509 | + ! Debug: log gap buffer state after insert | ||
| 6510 | + open(newunit=debug_unit, file='/tmp/fac_gap_debug.log', status='unknown', & | ||
| 6511 | + position='append', action='write') | ||
| 6512 | + write(debug_unit, '(A,I6,A,I6,A,I6)') 'AFTER INSERT: gap_start=', buffer%gap_start, & | ||
| 6513 | + ' gap_end=', buffer%gap_end, ' size=', buffer%size | ||
| 6514 | + write(debug_unit, '(A)') '---' | ||
| 6515 | + close(debug_unit) | ||
| 6418 | end subroutine apply_single_edit | 6516 | end subroutine apply_single_edit |
| 6419 | 6517 | ||
| 6420 | ! Execute a command from the command palette | 6518 | ! Execute a command from the command palette |
src/lsp/diagnostics_module.f90modified@@ -108,16 +108,11 @@ contains | |||
| 108 | character(len=:), allocatable :: uri | 108 | character(len=:), allocatable :: uri |
| 109 | integer :: i, n_diagnostics, file_idx | 109 | integer :: i, n_diagnostics, file_idx |
| 110 | type(diagnostic_t) :: diag | 110 | type(diagnostic_t) :: diag |
| 111 | - character(len=512) :: debug_msg | ||
| 112 | 111 | ||
| 113 | ! Get URI | 112 | ! Get URI |
| 114 | if (.not. json_has_key(params, "uri")) return | 113 | if (.not. json_has_key(params, "uri")) return |
| 115 | uri = json_get_string(params, "uri") | 114 | uri = json_get_string(params, "uri") |
| 116 | 115 | ||
| 117 | - ! Debug: Log URI | ||
| 118 | - write(debug_msg, '(A,A)') "[DIAG] Parsing diagnostics for URI: ", trim(uri) | ||
| 119 | - call terminal_write(debug_msg) | ||
| 120 | - | ||
| 121 | ! Find or create file entry | 116 | ! Find or create file entry |
| 122 | file_idx = find_or_create_file(store, uri) | 117 | file_idx = find_or_create_file(store, uri) |
| 123 | 118 | ||
@@ -132,10 +127,6 @@ contains | |||
| 132 | diagnostics_array = json_get_array(params, "diagnostics") | 127 | diagnostics_array = json_get_array(params, "diagnostics") |
| 133 | n_diagnostics = json_array_size(diagnostics_array) | 128 | n_diagnostics = json_array_size(diagnostics_array) |
| 134 | 129 | ||
| 135 | - ! Debug: Log number of diagnostics | ||
| 136 | - write(debug_msg, '(A,I0,A)') "[DIAG] Found ", n_diagnostics, " diagnostics" | ||
| 137 | - call terminal_write(debug_msg) | ||
| 138 | - | ||
| 139 | if (n_diagnostics > 0) then | 130 | if (n_diagnostics > 0) then |
| 140 | allocate(store%files(file_idx)%items(n_diagnostics)) | 131 | allocate(store%files(file_idx)%items(n_diagnostics)) |
| 141 | store%files(file_idx)%count = n_diagnostics | 132 | store%files(file_idx)%count = n_diagnostics |
@@ -208,17 +199,12 @@ contains | |||
| 208 | character(len=:), allocatable :: uri | 199 | character(len=:), allocatable :: uri |
| 209 | integer :: i, n_diagnostics, file_idx, old_count, new_count, j | 200 | integer :: i, n_diagnostics, file_idx, old_count, new_count, j |
| 210 | type(diagnostic_t) :: diag | 201 | type(diagnostic_t) :: diag |
| 211 | - type(diagnostic_t), allocatable :: old_items(:), new_items(:) | 202 | + type(diagnostic_t), allocatable :: old_items(:) |
| 212 | - character(len=512) :: debug_msg | ||
| 213 | 203 | ||
| 214 | ! Get URI | 204 | ! Get URI |
| 215 | if (.not. json_has_key(params, "uri")) return | 205 | if (.not. json_has_key(params, "uri")) return |
| 216 | uri = json_get_string(params, "uri") | 206 | uri = json_get_string(params, "uri") |
| 217 | 207 | ||
| 218 | - ! Debug: Log URI | ||
| 219 | - write(debug_msg, '(A,A,A,I0)') "[DIAG] Parsing diagnostics for URI: ", trim(uri), " from server ", server_index | ||
| 220 | - call terminal_write(debug_msg) | ||
| 221 | - | ||
| 222 | ! Find or create file entry | 208 | ! Find or create file entry |
| 223 | file_idx = find_or_create_file(store, uri) | 209 | file_idx = find_or_create_file(store, uri) |
| 224 | 210 | ||
@@ -255,10 +241,6 @@ contains | |||
| 255 | n_diagnostics = json_array_size(diagnostics_array) | 241 | n_diagnostics = json_array_size(diagnostics_array) |
| 256 | end if | 242 | end if |
| 257 | 243 | ||
| 258 | - ! Debug: Log number of diagnostics | ||
| 259 | - write(debug_msg, '(A,I0,A,I0,A)') "[DIAG] Found ", n_diagnostics, " new + ", old_count, " existing diagnostics" | ||
| 260 | - call terminal_write(debug_msg) | ||
| 261 | - | ||
| 262 | ! Allocate combined array | 244 | ! Allocate combined array |
| 263 | new_count = old_count + n_diagnostics | 245 | new_count = old_count + n_diagnostics |
| 264 | if (new_count > 0) then | 246 | if (new_count > 0) then |
src/lsp/lsp_protocol_module.f90modified@@ -106,16 +106,6 @@ contains | |||
| 106 | ! Convert root_path to absolute path | 106 | ! Convert root_path to absolute path |
| 107 | abs_root_path = make_absolute_path(root_path) | 107 | abs_root_path = make_absolute_path(root_path) |
| 108 | 108 | ||
| 109 | - block | ||
| 110 | - integer :: debug_unit | ||
| 111 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 112 | - write(debug_unit, '(A)') '>>> create_initialize_request <<<' | ||
| 113 | - write(debug_unit, '(A)') 'root_path (input): ' // trim(root_path) | ||
| 114 | - write(debug_unit, '(A)') 'abs_root_path: ' // abs_root_path | ||
| 115 | - write(debug_unit, '(A)') 'rootUri: file://' // abs_root_path | ||
| 116 | - close(debug_unit) | ||
| 117 | - end block | ||
| 118 | - | ||
| 119 | params = json_create_object() | 109 | params = json_create_object() |
| 120 | call json_add_number(params, "processId", real(process_id, real64)) | 110 | call json_add_number(params, "processId", real(process_id, real64)) |
| 121 | call json_add_string(params, "rootPath", abs_root_path) | 111 | call json_add_string(params, "rootPath", abs_root_path) |
@@ -238,7 +228,7 @@ contains | |||
| 238 | changes = json_create_array() | 228 | changes = json_create_array() |
| 239 | change = json_create_object() | 229 | change = json_create_object() |
| 240 | call json_add_string(change, "text", text) | 230 | call json_add_string(change, "text", text) |
| 241 | - ! TODO: Add change to array | 231 | + call json_array_add_element(changes, change) |
| 242 | call json_add_array(params, "contentChanges", changes) | 232 | call json_add_array(params, "contentChanges", changes) |
| 243 | 233 | ||
| 244 | msg%params = params | 234 | msg%params = params |
src/lsp/lsp_server_manager_module.f90modified@@ -375,16 +375,6 @@ contains | |||
| 375 | return | 375 | return |
| 376 | end if | 376 | end if |
| 377 | 377 | ||
| 378 | - block | ||
| 379 | - integer :: debug_unit | ||
| 380 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 381 | - write(debug_unit, '(A)') '>>> STARTING LSP SERVER <<<' | ||
| 382 | - write(debug_unit, '(A)') 'Language: ' // trim(language) | ||
| 383 | - write(debug_unit, '(A)') 'Command: ' // trim(command) | ||
| 384 | - write(debug_unit, '(A)') 'Root path: ' // trim(root_path) | ||
| 385 | - close(debug_unit) | ||
| 386 | - end block | ||
| 387 | - | ||
| 388 | ! Expand server array | 378 | ! Expand server array |
| 389 | allocate(new_servers(manager%num_servers + 1)) | 379 | allocate(new_servers(manager%num_servers + 1)) |
| 390 | if (manager%num_servers > 0) then | 380 | if (manager%num_servers > 0) then |
@@ -467,98 +457,20 @@ contains | |||
| 467 | procedure(response_callback), optional :: callback | 457 | procedure(response_callback), optional :: callback |
| 468 | character(len=:), allocatable :: json_msg | 458 | character(len=:), allocatable :: json_msg |
| 469 | 459 | ||
| 470 | - block | 460 | + if (server_index < 1 .or. server_index > manager%num_servers) return |
| 471 | - integer :: debug_unit | ||
| 472 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 473 | - write(debug_unit, '(A)') '>>> send_request: START <<<' | ||
| 474 | - write(debug_unit, '(A,I0)') 'server_index = ', server_index | ||
| 475 | - write(debug_unit, '(A,I0)') 'num_servers = ', manager%num_servers | ||
| 476 | - close(debug_unit) | ||
| 477 | - end block | ||
| 478 | - | ||
| 479 | - if (server_index < 1 .or. server_index > manager%num_servers) then | ||
| 480 | - block | ||
| 481 | - integer :: debug_unit | ||
| 482 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 483 | - write(debug_unit, '(A)') '>>> send_request: EARLY RETURN - invalid server_index <<<' | ||
| 484 | - close(debug_unit) | ||
| 485 | - end block | ||
| 486 | - return | ||
| 487 | - end if | ||
| 488 | 461 | ||
| 489 | if (.not. manager%servers(server_index)%initialized .and. & | 462 | if (.not. manager%servers(server_index)%initialized .and. & |
| 490 | - .not. manager%servers(server_index)%initializing) then | 463 | + .not. manager%servers(server_index)%initializing) return |
| 491 | - block | ||
| 492 | - integer :: debug_unit | ||
| 493 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 494 | - write(debug_unit, '(A)') '>>> send_request: EARLY RETURN - server not initialized <<<' | ||
| 495 | - write(debug_unit, '(A,L1)') 'initialized = ', manager%servers(server_index)%initialized | ||
| 496 | - write(debug_unit, '(A,L1)') 'initializing = ', manager%servers(server_index)%initializing | ||
| 497 | - close(debug_unit) | ||
| 498 | - end block | ||
| 499 | - return | ||
| 500 | - end if | ||
| 501 | - | ||
| 502 | - block | ||
| 503 | - integer :: debug_unit | ||
| 504 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 505 | - write(debug_unit, '(A)') '>>> send_request: Formatting JSON <<<' | ||
| 506 | - close(debug_unit) | ||
| 507 | - end block | ||
| 508 | 464 | ||
| 509 | json_msg = format_json_rpc(msg) | 465 | json_msg = format_json_rpc(msg) |
| 510 | - | ||
| 511 | - block | ||
| 512 | - integer :: debug_unit | ||
| 513 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 514 | - write(debug_unit, '(A)') '>>> send_request: Sending message <<<' | ||
| 515 | - write(debug_unit, '(A)') 'JSON (first 500 chars): ' // json_msg(1:min(500,len(json_msg))) | ||
| 516 | - close(debug_unit) | ||
| 517 | - end block | ||
| 518 | - | ||
| 519 | call send_raw_message(manager%servers(server_index), json_msg) | 466 | call send_raw_message(manager%servers(server_index), json_msg) |
| 520 | 467 | ||
| 521 | - block | ||
| 522 | - integer :: debug_unit | ||
| 523 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 524 | - write(debug_unit, '(A)') '>>> send_request: Tracking request <<<' | ||
| 525 | - close(debug_unit) | ||
| 526 | - end block | ||
| 527 | - | ||
| 528 | ! Track request and register callback | 468 | ! Track request and register callback |
| 529 | call track_request(manager%servers(server_index), msg%id) | 469 | call track_request(manager%servers(server_index), msg%id) |
| 530 | 470 | ||
| 531 | - block | ||
| 532 | - integer :: debug_unit | ||
| 533 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 534 | - write(debug_unit, '(A,L1)') '>>> send_request: callback present = ', present(callback) | ||
| 535 | - close(debug_unit) | ||
| 536 | - end block | ||
| 537 | - | ||
| 538 | if (present(callback)) then | 471 | if (present(callback)) then |
| 539 | - block | ||
| 540 | - integer :: debug_unit | ||
| 541 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 542 | - write(debug_unit, '(A)') '>>> send_request: Calling register_callback <<<' | ||
| 543 | - close(debug_unit) | ||
| 544 | - end block | ||
| 545 | - | ||
| 546 | call register_callback(manager, msg%id, callback) | 472 | call register_callback(manager, msg%id, callback) |
| 547 | - | ||
| 548 | - block | ||
| 549 | - integer :: debug_unit | ||
| 550 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 551 | - write(debug_unit, '(A)') '>>> send_request: register_callback DONE <<<' | ||
| 552 | - close(debug_unit) | ||
| 553 | - end block | ||
| 554 | end if | 473 | end if |
| 555 | - | ||
| 556 | - block | ||
| 557 | - integer :: debug_unit | ||
| 558 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 559 | - write(debug_unit, '(A)') '>>> send_request: DONE <<<' | ||
| 560 | - close(debug_unit) | ||
| 561 | - end block | ||
| 562 | end subroutine send_request | 474 | end subroutine send_request |
| 563 | 475 | ||
| 564 | subroutine send_notification(server, msg) | 476 | subroutine send_notification(server, msg) |
@@ -569,52 +481,15 @@ contains | |||
| 569 | if (.not. server%initialized .and. .not. server%initializing) return | 481 | if (.not. server%initialized .and. .not. server%initializing) return |
| 570 | 482 | ||
| 571 | json_msg = format_json_rpc(msg) | 483 | json_msg = format_json_rpc(msg) |
| 572 | - | ||
| 573 | - ! Debug log for didOpen notifications | ||
| 574 | - if (index(msg%method, 'didOpen') > 0) then | ||
| 575 | - block | ||
| 576 | - integer :: debug_unit | ||
| 577 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 578 | - write(debug_unit, '(A)') '>>> Sending didOpen notification <<<' | ||
| 579 | - write(debug_unit, '(A)') 'JSON (first 800 chars): ' // json_msg(1:min(800,len(json_msg))) | ||
| 580 | - close(debug_unit) | ||
| 581 | - end block | ||
| 582 | - end if | ||
| 583 | - | ||
| 584 | call send_raw_message(server, json_msg) | 484 | call send_raw_message(server, json_msg) |
| 585 | end subroutine send_notification | 485 | end subroutine send_notification |
| 586 | 486 | ||
| 587 | subroutine send_raw_message(server, message) | 487 | subroutine send_raw_message(server, message) |
| 588 | type(lsp_server_t), intent(inout) :: server | 488 | type(lsp_server_t), intent(inout) :: server |
| 589 | character(len=*), intent(in) :: message | 489 | character(len=*), intent(in) :: message |
| 590 | - integer :: result, debug_unit | 490 | + integer :: result |
| 591 | - | ||
| 592 | - ! Check if handle is valid | ||
| 593 | - block | ||
| 594 | - integer :: debug_unit2 | ||
| 595 | - open(newunit=debug_unit2, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 596 | - write(debug_unit2, '(A)') '>>> send_raw_message: START <<<' | ||
| 597 | - write(debug_unit2, '(A,L1)') 'c_associated(server%handle) = ', c_associated(server%handle) | ||
| 598 | - close(debug_unit2) | ||
| 599 | - end block | ||
| 600 | - | ||
| 601 | - if (.not. c_associated(server%handle)) then | ||
| 602 | - block | ||
| 603 | - integer :: debug_unit2 | ||
| 604 | - open(newunit=debug_unit2, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 605 | - write(debug_unit2, '(A)') '>>> send_raw_message: EARLY RETURN - handle is NULL <<<' | ||
| 606 | - close(debug_unit2) | ||
| 607 | - end block | ||
| 608 | - return | ||
| 609 | - end if | ||
| 610 | 491 | ||
| 611 | - ! Log outgoing messages for debugging | 492 | + if (.not. c_associated(server%handle)) return |
| 612 | - open(newunit=debug_unit, file='/tmp/fac_lsp_out.log', position='append', action='write') | ||
| 613 | - write(debug_unit, '(A)') '>>> OUTGOING MESSAGE >>>' | ||
| 614 | - write(debug_unit, '(A)') trim(message) | ||
| 615 | - write(debug_unit, '(A)') '<<< END MESSAGE <<<' | ||
| 616 | - write(debug_unit, '(A)') '' | ||
| 617 | - close(debug_unit) | ||
| 618 | 493 | ||
| 619 | result = lsp_send_message_f(server%handle, message//c_null_char, len(message)) | 494 | result = lsp_send_message_f(server%handle, message//c_null_char, len(message)) |
| 620 | 495 | ||
@@ -675,18 +550,6 @@ contains | |||
| 675 | 550 | ||
| 676 | ! Extract and parse message | 551 | ! Extract and parse message |
| 677 | message = server%read_buffer(1:message_end) | 552 | message = server%read_buffer(1:message_end) |
| 678 | - | ||
| 679 | - ! Log incoming message | ||
| 680 | - block | ||
| 681 | - integer :: debug_unit | ||
| 682 | - open(newunit=debug_unit, file='/tmp/fac_lsp_in.log', position='append', action='write') | ||
| 683 | - write(debug_unit, '(A)') '>>> INCOMING MESSAGE >>>' | ||
| 684 | - write(debug_unit, '(A)') trim(message) | ||
| 685 | - write(debug_unit, '(A)') '<<< END MESSAGE <<<' | ||
| 686 | - write(debug_unit, '(A)') '' | ||
| 687 | - close(debug_unit) | ||
| 688 | - end block | ||
| 689 | - | ||
| 690 | msg = parse_lsp_message(message) | 553 | msg = parse_lsp_message(message) |
| 691 | 554 | ||
| 692 | ! Handle the message | 555 | ! Handle the message |
@@ -818,19 +681,13 @@ contains | |||
| 818 | server%initialized = .true. | 681 | server%initialized = .true. |
| 819 | server%initializing = .false. | 682 | server%initializing = .false. |
| 820 | 683 | ||
| 821 | - write(error_unit, '(a,a)') "LSP server initialized: ", server%language | ||
| 822 | - | ||
| 823 | ! Send all queued didOpen notifications | 684 | ! Send all queued didOpen notifications |
| 824 | if (allocated(server%pending_didopens) .and. server%num_pending_didopens > 0) then | 685 | if (allocated(server%pending_didopens) .and. server%num_pending_didopens > 0) then |
| 825 | block | 686 | block |
| 826 | - integer :: i, debug_unit | 687 | + integer :: i |
| 827 | type(lsp_message_t) :: didopen_msg | 688 | type(lsp_message_t) :: didopen_msg |
| 828 | character(len=:), allocatable :: lang, file_uri | 689 | character(len=:), allocatable :: lang, file_uri |
| 829 | 690 | ||
| 830 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 831 | - write(debug_unit, '(A,I0,A)') '>>> Flushing ', server%num_pending_didopens, ' queued didOpen notifications <<<' | ||
| 832 | - close(debug_unit) | ||
| 833 | - | ||
| 834 | do i = 1, server%num_pending_didopens | 691 | do i = 1, server%num_pending_didopens |
| 835 | if (allocated(server%pending_didopens(i)%filename) .and. & | 692 | if (allocated(server%pending_didopens(i)%filename) .and. & |
| 836 | allocated(server%pending_didopens(i)%content)) then | 693 | allocated(server%pending_didopens(i)%content)) then |
@@ -840,14 +697,6 @@ contains | |||
| 840 | didopen_msg = create_did_open_notification( & | 697 | didopen_msg = create_did_open_notification( & |
| 841 | file_uri, lang, 1, & | 698 | file_uri, lang, 1, & |
| 842 | server%pending_didopens(i)%content) | 699 | server%pending_didopens(i)%content) |
| 843 | - | ||
| 844 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 845 | - write(debug_unit, '(A,A)') ' - Sent didOpen for: ', trim(server%pending_didopens(i)%filename) | ||
| 846 | - write(debug_unit, '(A,A)') ' - URI: ', trim(file_uri) | ||
| 847 | - write(debug_unit, '(A,I0)') ' - Content length: ', len(server%pending_didopens(i)%content) | ||
| 848 | - write(debug_unit, '(A,A)') ' - Language: ', trim(lang) | ||
| 849 | - close(debug_unit) | ||
| 850 | - | ||
| 851 | call send_notification(server, didopen_msg) | 700 | call send_notification(server, didopen_msg) |
| 852 | end if | 701 | end if |
| 853 | end do | 702 | end do |
@@ -865,9 +714,6 @@ contains | |||
| 865 | type(lsp_message_t), intent(in) :: msg | 714 | type(lsp_message_t), intent(in) :: msg |
| 866 | integer :: srv_idx, i | 715 | integer :: srv_idx, i |
| 867 | 716 | ||
| 868 | - ! Debug: log all notifications | ||
| 869 | - write(error_unit, '(A,A)') "[LSP DEBUG] Received notification: ", msg%method | ||
| 870 | - | ||
| 871 | ! Find the server index for this server | 717 | ! Find the server index for this server |
| 872 | srv_idx = 0 | 718 | srv_idx = 0 |
| 873 | do i = 1, manager%num_servers | 719 | do i = 1, manager%num_servers |
@@ -882,12 +728,9 @@ contains | |||
| 882 | 728 | ||
| 883 | select case(msg%method) | 729 | select case(msg%method) |
| 884 | case("textDocument/publishDiagnostics") | 730 | case("textDocument/publishDiagnostics") |
| 885 | - write(error_unit, '(A,I0)') "[LSP DEBUG] Processing publishDiagnostics from server ", srv_idx | ||
| 886 | ! Forward to diagnostics handler if set (with server index) | 731 | ! Forward to diagnostics handler if set (with server index) |
| 887 | if (associated(manager%diagnostics_handler)) then | 732 | if (associated(manager%diagnostics_handler)) then |
| 888 | call manager%diagnostics_handler(msg, srv_idx) | 733 | call manager%diagnostics_handler(msg, srv_idx) |
| 889 | - else | ||
| 890 | - write(error_unit, '(A)') "[LSP DEBUG] No diagnostics handler set!" | ||
| 891 | end if | 734 | end if |
| 892 | case("window/showMessage") | 735 | case("window/showMessage") |
| 893 | ! TODO: Show message to user | 736 | ! TODO: Show message to user |
@@ -940,87 +783,19 @@ contains | |||
| 940 | procedure(response_callback) :: callback | 783 | procedure(response_callback) :: callback |
| 941 | type(callback_entry_t), allocatable :: new_callbacks(:) | 784 | type(callback_entry_t), allocatable :: new_callbacks(:) |
| 942 | 785 | ||
| 943 | - block | ||
| 944 | - integer :: debug_unit | ||
| 945 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 946 | - write(debug_unit, '(A)') '>>> register_callback: START <<<' | ||
| 947 | - write(debug_unit, '(A,I0)') 'request_id = ', request_id | ||
| 948 | - write(debug_unit, '(A,I0)') 'num_callbacks = ', manager%num_callbacks | ||
| 949 | - close(debug_unit) | ||
| 950 | - end block | ||
| 951 | - | ||
| 952 | - block | ||
| 953 | - integer :: debug_unit | ||
| 954 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 955 | - write(debug_unit, '(A)') '>>> register_callback: Allocating new_callbacks <<<' | ||
| 956 | - close(debug_unit) | ||
| 957 | - end block | ||
| 958 | - | ||
| 959 | allocate(new_callbacks(manager%num_callbacks + 1)) | 786 | allocate(new_callbacks(manager%num_callbacks + 1)) |
| 960 | 787 | ||
| 961 | - block | ||
| 962 | - integer :: debug_unit | ||
| 963 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 964 | - write(debug_unit, '(A)') '>>> register_callback: Copying old callbacks <<<' | ||
| 965 | - close(debug_unit) | ||
| 966 | - end block | ||
| 967 | - | ||
| 968 | if (manager%num_callbacks > 0) then | 788 | if (manager%num_callbacks > 0) then |
| 969 | new_callbacks(1:manager%num_callbacks) = manager%callbacks | 789 | new_callbacks(1:manager%num_callbacks) = manager%callbacks |
| 970 | end if | 790 | end if |
| 971 | 791 | ||
| 972 | - block | ||
| 973 | - integer :: debug_unit | ||
| 974 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 975 | - write(debug_unit, '(A)') '>>> register_callback: Setting new callback <<<' | ||
| 976 | - close(debug_unit) | ||
| 977 | - end block | ||
| 978 | - | ||
| 979 | new_callbacks(manager%num_callbacks + 1)%request_id = request_id | 792 | new_callbacks(manager%num_callbacks + 1)%request_id = request_id |
| 980 | new_callbacks(manager%num_callbacks + 1)%callback => callback | 793 | new_callbacks(manager%num_callbacks + 1)%callback => callback |
| 981 | 794 | ||
| 982 | - block | ||
| 983 | - integer :: debug_unit | ||
| 984 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 985 | - write(debug_unit, '(A)') '>>> register_callback: Deallocating old callbacks <<<' | ||
| 986 | - close(debug_unit) | ||
| 987 | - end block | ||
| 988 | - | ||
| 989 | if (allocated(manager%callbacks)) deallocate(manager%callbacks) | 795 | if (allocated(manager%callbacks)) deallocate(manager%callbacks) |
| 990 | - | ||
| 991 | - block | ||
| 992 | - integer :: debug_unit | ||
| 993 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 994 | - write(debug_unit, '(A)') '>>> register_callback: Reallocating manager%callbacks <<<' | ||
| 995 | - close(debug_unit) | ||
| 996 | - end block | ||
| 997 | - | ||
| 998 | allocate(manager%callbacks(size(new_callbacks))) | 796 | allocate(manager%callbacks(size(new_callbacks))) |
| 999 | - | ||
| 1000 | - block | ||
| 1001 | - integer :: debug_unit | ||
| 1002 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 1003 | - write(debug_unit, '(A)') '>>> register_callback: Copying new_callbacks <<<' | ||
| 1004 | - close(debug_unit) | ||
| 1005 | - end block | ||
| 1006 | - | ||
| 1007 | manager%callbacks = new_callbacks | 797 | manager%callbacks = new_callbacks |
| 1008 | - | ||
| 1009 | - block | ||
| 1010 | - integer :: debug_unit | ||
| 1011 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 1012 | - write(debug_unit, '(A)') '>>> register_callback: Incrementing num_callbacks <<<' | ||
| 1013 | - close(debug_unit) | ||
| 1014 | - end block | ||
| 1015 | - | ||
| 1016 | manager%num_callbacks = manager%num_callbacks + 1 | 798 | manager%num_callbacks = manager%num_callbacks + 1 |
| 1017 | - | ||
| 1018 | - block | ||
| 1019 | - integer :: debug_unit | ||
| 1020 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 1021 | - write(debug_unit, '(A)') '>>> register_callback: DONE <<<' | ||
| 1022 | - close(debug_unit) | ||
| 1023 | - end block | ||
| 1024 | end subroutine register_callback | 799 | end subroutine register_callback |
| 1025 | 800 | ||
| 1026 | subroutine remove_callback(manager, index) | 801 | subroutine remove_callback(manager, index) |
@@ -1191,17 +966,6 @@ contains | |||
| 1191 | 966 | ||
| 1192 | command = manager%configs(config_index)%command | 967 | command = manager%configs(config_index)%command |
| 1193 | 968 | ||
| 1194 | - block | ||
| 1195 | - integer :: debug_unit | ||
| 1196 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 1197 | - write(debug_unit, '(A)') '>>> STARTING LSP SERVER (from config) <<<' | ||
| 1198 | - write(debug_unit, '(A)') 'Name: ' // trim(manager%configs(config_index)%name) | ||
| 1199 | - write(debug_unit, '(A)') 'Language: ' // trim(manager%configs(config_index)%language) | ||
| 1200 | - write(debug_unit, '(A)') 'Command: ' // trim(command) | ||
| 1201 | - write(debug_unit, '(A)') 'Root path: ' // trim(root_path) | ||
| 1202 | - close(debug_unit) | ||
| 1203 | - end block | ||
| 1204 | - | ||
| 1205 | ! Expand server array | 969 | ! Expand server array |
| 1206 | allocate(new_servers(manager%num_servers + 1)) | 970 | allocate(new_servers(manager%num_servers + 1)) |
| 1207 | if (manager%num_servers > 0) then | 971 | if (manager%num_servers > 0) then |
@@ -1280,14 +1044,6 @@ contains | |||
| 1280 | 1044 | ||
| 1281 | ! If server not initialized yet, queue the notification | 1045 | ! If server not initialized yet, queue the notification |
| 1282 | if (.not. manager%servers(server_index)%initialized) then | 1046 | if (.not. manager%servers(server_index)%initialized) then |
| 1283 | - block | ||
| 1284 | - integer :: debug_unit | ||
| 1285 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 1286 | - write(debug_unit, '(A)') '>>> notify_file_opened: Queuing (server not ready) <<<' | ||
| 1287 | - write(debug_unit, '(A)') 'File: ' // trim(filename) | ||
| 1288 | - close(debug_unit) | ||
| 1289 | - end block | ||
| 1290 | - | ||
| 1291 | ! Add to pending queue | 1047 | ! Add to pending queue |
| 1292 | if (allocated(manager%servers(server_index)%pending_didopens)) then | 1048 | if (allocated(manager%servers(server_index)%pending_didopens)) then |
| 1293 | ! Grow array | 1049 | ! Grow array |
@@ -1322,14 +1078,6 @@ contains | |||
| 1322 | return | 1078 | return |
| 1323 | end if | 1079 | end if |
| 1324 | 1080 | ||
| 1325 | - block | ||
| 1326 | - integer :: debug_unit | ||
| 1327 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 1328 | - write(debug_unit, '(A)') '>>> notify_file_opened: Sending immediately <<<' | ||
| 1329 | - write(debug_unit, '(A)') 'File: ' // trim(filename) | ||
| 1330 | - close(debug_unit) | ||
| 1331 | - end block | ||
| 1332 | - | ||
| 1333 | ! Server is ready, send immediately | 1081 | ! Server is ready, send immediately |
| 1334 | language = get_language_for_file(filename) | 1082 | language = get_language_for_file(filename) |
| 1335 | block | 1083 | block |
@@ -1338,14 +1086,6 @@ contains | |||
| 1338 | msg = create_did_open_notification(file_uri, language, 1, content) | 1086 | msg = create_did_open_notification(file_uri, language, 1, content) |
| 1339 | end block | 1087 | end block |
| 1340 | 1088 | ||
| 1341 | - block | ||
| 1342 | - integer :: debug_unit | ||
| 1343 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 1344 | - write(debug_unit, '(A)') '>>> didOpen content length: ' // trim(adjustl(char(len(content)))) | ||
| 1345 | - write(debug_unit, '(A)') '>>> didOpen language: ' // trim(language) | ||
| 1346 | - close(debug_unit) | ||
| 1347 | - end block | ||
| 1348 | - | ||
| 1349 | call send_notification(manager%servers(server_index), msg) | 1089 | call send_notification(manager%servers(server_index), msg) |
| 1350 | end subroutine notify_file_opened | 1090 | end subroutine notify_file_opened |
| 1351 | 1091 | ||
@@ -1359,6 +1099,16 @@ contains | |||
| 1359 | integer, intent(in), optional :: version | 1099 | integer, intent(in), optional :: version |
| 1360 | type(lsp_message_t) :: msg | 1100 | type(lsp_message_t) :: msg |
| 1361 | integer :: doc_version | 1101 | integer :: doc_version |
| 1102 | + integer :: debug_unit | ||
| 1103 | + | ||
| 1104 | + ! Debug logging | ||
| 1105 | + open(newunit=debug_unit, file='/tmp/fac_didchange_debug.log', status='unknown', & | ||
| 1106 | + position='append', action='write') | ||
| 1107 | + write(debug_unit, '(A,I2,A)') 'notify_file_changed called for server ', server_index, ':' | ||
| 1108 | + write(debug_unit, '(A,A)') ' URI: ', trim(filename) | ||
| 1109 | + write(debug_unit, '(A,I8)') ' Content length: ', len(content) | ||
| 1110 | + write(debug_unit, '(A)') '---' | ||
| 1111 | + close(debug_unit) | ||
| 1362 | 1112 | ||
| 1363 | if (server_index < 1 .or. server_index > manager%num_servers) return | 1113 | if (server_index < 1 .or. server_index > manager%num_servers) return |
| 1364 | if (.not. manager%servers(server_index)%initialized) return | 1114 | if (.not. manager%servers(server_index)%initialized) return |
@@ -1395,9 +1145,6 @@ contains | |||
| 1395 | end if | 1145 | end if |
| 1396 | 1146 | ||
| 1397 | call send_notification(manager%servers(server_index), msg) | 1147 | call send_notification(manager%servers(server_index), msg) |
| 1398 | - | ||
| 1399 | - ! Debug output | ||
| 1400 | - write(error_unit, '(A,A)') "[LSP DEBUG] Sent didSave for: ", trim(filename) | ||
| 1401 | end subroutine notify_file_saved | 1148 | end subroutine notify_file_saved |
| 1402 | 1149 | ||
| 1403 | ! Send textDocument/didClose notification | 1150 | ! Send textDocument/didClose notification |
@@ -1477,55 +1224,14 @@ contains | |||
| 1477 | type(lsp_message_t) :: msg | 1224 | type(lsp_message_t) :: msg |
| 1478 | character(len=:), allocatable :: uri | 1225 | character(len=:), allocatable :: uri |
| 1479 | 1226 | ||
| 1480 | - block | ||
| 1481 | - integer :: debug_unit | ||
| 1482 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 1483 | - write(debug_unit, '(A)') '>>> request_definition: START <<<' | ||
| 1484 | - close(debug_unit) | ||
| 1485 | - end block | ||
| 1486 | - | ||
| 1487 | request_id = -1 | 1227 | request_id = -1 |
| 1488 | if (server_index < 1 .or. server_index > manager%num_servers) return | 1228 | if (server_index < 1 .or. server_index > manager%num_servers) return |
| 1489 | if (.not. manager%servers(server_index)%initialized) return | 1229 | if (.not. manager%servers(server_index)%initialized) return |
| 1490 | 1230 | ||
| 1491 | - block | ||
| 1492 | - integer :: debug_unit | ||
| 1493 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 1494 | - write(debug_unit, '(A)') '>>> request_definition: Creating URI <<<' | ||
| 1495 | - write(debug_unit, '(A)') 'Filename: ' // trim(filename) | ||
| 1496 | - close(debug_unit) | ||
| 1497 | - end block | ||
| 1498 | - | ||
| 1499 | - ! Convert filename to URI (simple file:// for now) | ||
| 1500 | uri = filename_to_uri(filename) | 1231 | uri = filename_to_uri(filename) |
| 1501 | - | ||
| 1502 | - block | ||
| 1503 | - integer :: debug_unit | ||
| 1504 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 1505 | - write(debug_unit, '(A)') '>>> request_definition: Creating request <<<' | ||
| 1506 | - write(debug_unit, '(A)') 'URI: ' // trim(uri) | ||
| 1507 | - write(debug_unit, '(A,I0,A,I0)') 'Position: line=', line, ' char=', character | ||
| 1508 | - close(debug_unit) | ||
| 1509 | - end block | ||
| 1510 | - | ||
| 1511 | msg = create_definition_request(uri, line, character) | 1232 | msg = create_definition_request(uri, line, character) |
| 1512 | request_id = msg%id | 1233 | request_id = msg%id |
| 1513 | - | ||
| 1514 | - block | ||
| 1515 | - integer :: debug_unit | ||
| 1516 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 1517 | - write(debug_unit, '(A)') '>>> request_definition: Calling send_request <<<' | ||
| 1518 | - close(debug_unit) | ||
| 1519 | - end block | ||
| 1520 | - | ||
| 1521 | call send_request(manager, server_index, msg, callback) | 1234 | call send_request(manager, server_index, msg, callback) |
| 1522 | - | ||
| 1523 | - block | ||
| 1524 | - integer :: debug_unit | ||
| 1525 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 1526 | - write(debug_unit, '(A)') '>>> request_definition: DONE <<<' | ||
| 1527 | - close(debug_unit) | ||
| 1528 | - end block | ||
| 1529 | end function request_definition | 1235 | end function request_definition |
| 1530 | 1236 | ||
| 1531 | ! Request references at cursor position | 1237 | ! Request references at cursor position |
@@ -1568,19 +1274,9 @@ contains | |||
| 1568 | integer :: request_id | 1274 | integer :: request_id |
| 1569 | type(lsp_message_t) :: msg | 1275 | type(lsp_message_t) :: msg |
| 1570 | character(len=:), allocatable :: uri | 1276 | character(len=:), allocatable :: uri |
| 1571 | - integer :: dbg | ||
| 1572 | 1277 | ||
| 1573 | request_id = -1 | 1278 | request_id = -1 |
| 1574 | 1279 | ||
| 1575 | - ! Debug logging | ||
| 1576 | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') | ||
| 1577 | - write(dbg, '(A,I0)') 'request_code_actions: server_index = ', server_index | ||
| 1578 | - write(dbg, '(A,I0)') 'request_code_actions: num_servers = ', manager%num_servers | ||
| 1579 | - if (server_index >= 1 .and. server_index <= manager%num_servers) then | ||
| 1580 | - write(dbg, '(A,L1)') 'request_code_actions: initialized = ', manager%servers(server_index)%initialized | ||
| 1581 | - end if | ||
| 1582 | - close(dbg) | ||
| 1583 | - | ||
| 1584 | if (server_index < 1 .or. server_index > manager%num_servers) return | 1280 | if (server_index < 1 .or. server_index > manager%num_servers) return |
| 1585 | if (.not. manager%servers(server_index)%initialized) return | 1281 | if (.not. manager%servers(server_index)%initialized) return |
| 1586 | 1282 | ||
src/terminal/input_handler_module.f90modified@@ -105,14 +105,6 @@ contains | |||
| 105 | end if | 105 | end if |
| 106 | ch2 = achar(char_code) | 106 | ch2 = achar(char_code) |
| 107 | 107 | ||
| 108 | - block | ||
| 109 | - integer :: debug_unit, ch2_code | ||
| 110 | - ch2_code = ichar(ch2) | ||
| 111 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 112 | - write(debug_unit, '(A,I0,A)') '>>> ESC[ RECEIVED, ch2=', ch2_code, ' (' // ch2 // ')' | ||
| 113 | - close(debug_unit) | ||
| 114 | - end block | ||
| 115 | - | ||
| 116 | select case(ch2) | 108 | select case(ch2) |
| 117 | case('A') | 109 | case('A') |
| 118 | key_str = 'up' | 110 | key_str = 'up' |
@@ -187,22 +179,10 @@ contains | |||
| 187 | end if | 179 | end if |
| 188 | case('1') | 180 | case('1') |
| 189 | ! Could be function key (F1-F9) or modified arrow/home/end | 181 | ! Could be function key (F1-F9) or modified arrow/home/end |
| 190 | - block | ||
| 191 | - integer :: debug_unit | ||
| 192 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 193 | - write(debug_unit, '(A)') '>>> ESC[1 SEQUENCE DETECTED <<<' | ||
| 194 | - close(debug_unit) | ||
| 195 | - end block | ||
| 196 | ! Check next character | 182 | ! Check next character |
| 197 | char_code = terminal_read_char() | 183 | char_code = terminal_read_char() |
| 198 | if (char_code >= 0) then | 184 | if (char_code >= 0) then |
| 199 | ch3 = achar(char_code) | 185 | ch3 = achar(char_code) |
| 200 | - block | ||
| 201 | - integer :: debug_unit | ||
| 202 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 203 | - write(debug_unit, '(A)') 'ch3 = ' // ch3 | ||
| 204 | - close(debug_unit) | ||
| 205 | - end block | ||
| 206 | if (ch3 == '~') then | 186 | if (ch3 == '~') then |
| 207 | ! F1: ESC [ 1 1 ~ (alternate format) | 187 | ! F1: ESC [ 1 1 ~ (alternate format) |
| 208 | key_str = 'f1' | 188 | key_str = 'f1' |
@@ -250,21 +230,9 @@ contains | |||
| 250 | end if | 230 | end if |
| 251 | case('2') | 231 | case('2') |
| 252 | ! Could be F9-F12 or alternate modified keys | 232 | ! Could be F9-F12 or alternate modified keys |
| 253 | - block | ||
| 254 | - integer :: debug_unit | ||
| 255 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 256 | - write(debug_unit, '(A)') '>>> ESC[2 SEQUENCE DETECTED <<<' | ||
| 257 | - close(debug_unit) | ||
| 258 | - end block | ||
| 259 | char_code = terminal_read_char() | 233 | char_code = terminal_read_char() |
| 260 | if (char_code >= 0) then | 234 | if (char_code >= 0) then |
| 261 | ch3 = achar(char_code) | 235 | ch3 = achar(char_code) |
| 262 | - block | ||
| 263 | - integer :: debug_unit | ||
| 264 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 265 | - write(debug_unit, '(A)') 'ch3 = ' // ch3 | ||
| 266 | - close(debug_unit) | ||
| 267 | - end block | ||
| 268 | if (ch3 == '0' .or. ch3 == '1' .or. ch3 == '3' .or. ch3 == '4') then | 236 | if (ch3 == '0' .or. ch3 == '1' .or. ch3 == '3' .or. ch3 == '4') then |
| 269 | ! Function keys F9-F12: ESC [ 2 X ~ or ESC [ 2 X ; modifier ~ | 237 | ! Function keys F9-F12: ESC [ 2 X ~ or ESC [ 2 X ; modifier ~ |
| 270 | char_code = terminal_read_char() | 238 | char_code = terminal_read_char() |
@@ -281,13 +249,6 @@ contains | |||
| 281 | key_str = 'f11' | 249 | key_str = 'f11' |
| 282 | case('4') | 250 | case('4') |
| 283 | key_str = 'f12' | 251 | key_str = 'f12' |
| 284 | - block | ||
| 285 | - integer :: debug_unit | ||
| 286 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 287 | - write(debug_unit, '(A)') '>>> F12 KEY DETECTED IN INPUT HANDLER <<<' | ||
| 288 | - write(debug_unit, '(A)') 'key_str set to: ' // trim(key_str) | ||
| 289 | - close(debug_unit) | ||
| 290 | - end block | ||
| 291 | end select | 252 | end select |
| 292 | else if (ch == ';') then | 253 | else if (ch == ';') then |
| 293 | ! Modified F9-F12: ESC [ 2 X ; modifier ~ | 254 | ! Modified F9-F12: ESC [ 2 X ; modifier ~ |
@@ -465,64 +426,71 @@ contains | |||
| 465 | if (terminator == '') return | 426 | if (terminator == '') return |
| 466 | 427 | ||
| 467 | ! Parse modifier | 428 | ! Parse modifier |
| 468 | - if (len_trim(modifier_seq) > 1 .and. modifier_seq(1:1) == ';') then | 429 | + if (len_trim(modifier_seq) >= 1 .and. modifier_seq(1:1) == ';') then |
| 469 | - ! Standard format: ";2" where 2 is the modifier | 430 | + ! Standard format with leading ';': ";2" where 2 is the modifier |
| 470 | if (len_trim(modifier_seq) >= 2) then | 431 | if (len_trim(modifier_seq) >= 2) then |
| 471 | read(modifier_seq(2:len_trim(modifier_seq)), '(i10)', iostat=ios) modifier | 432 | read(modifier_seq(2:len_trim(modifier_seq)), '(i10)', iostat=ios) modifier |
| 472 | else | 433 | else |
| 473 | ios = -1 | 434 | ios = -1 |
| 474 | end if | 435 | end if |
| 475 | - if (ios == 0) then | 436 | + else if (len_trim(modifier_seq) >= 1 .and. & |
| 476 | - select case(modifier) | 437 | + modifier_seq(1:1) >= '1' .and. modifier_seq(1:1) <= '9') then |
| 477 | - case(2) ! Shift | 438 | + ! Format without leading ';' (already consumed by caller): "2" or "3" etc |
| 478 | - key_str = 'shift-' | 439 | + read(modifier_seq(1:len_trim(modifier_seq)), '(i10)', iostat=ios) modifier |
| 479 | - case(3) ! Alt | 440 | + else |
| 480 | - key_str = 'alt-' | 441 | + ios = -1 |
| 481 | - case(4) ! Alt+Shift | 442 | + end if |
| 482 | - key_str = 'alt-shift-' | ||
| 483 | - case(5) ! Ctrl | ||
| 484 | - key_str = 'ctrl-' | ||
| 485 | - case(6) ! Ctrl+Shift | ||
| 486 | - key_str = 'ctrl-shift-' | ||
| 487 | - case(7) ! Alt+Ctrl | ||
| 488 | - key_str = 'alt-ctrl-' | ||
| 489 | - case(8) ! Alt+Shift (or Option+Shift) | ||
| 490 | - key_str = 'alt-shift-' | ||
| 491 | - case(9) ! Alt+Cmd (or Option+Cmd on macOS) | ||
| 492 | - key_str = 'opt-meta-' | ||
| 493 | - case default | ||
| 494 | - key_str = '' | ||
| 495 | - end select | ||
| 496 | 443 | ||
| 497 | - ! Append the key type using the terminator character | 444 | + if (ios == 0) then |
| 498 | - select case(terminator) | 445 | + select case(modifier) |
| 499 | - case('A') | 446 | + case(2) ! Shift |
| 500 | - key_str = trim(key_str) // 'up' | 447 | + key_str = 'shift-' |
| 501 | - case('B') | 448 | + case(3) ! Alt |
| 502 | - key_str = trim(key_str) // 'down' | 449 | + key_str = 'alt-' |
| 503 | - case('C') | 450 | + case(4) ! Alt+Shift |
| 504 | - key_str = trim(key_str) // 'right' | 451 | + key_str = 'alt-shift-' |
| 505 | - case('D') | 452 | + case(5) ! Ctrl |
| 506 | - key_str = trim(key_str) // 'left' | 453 | + key_str = 'ctrl-' |
| 507 | - case('H') | 454 | + case(6) ! Ctrl+Shift |
| 508 | - key_str = trim(key_str) // 'home' | 455 | + key_str = 'ctrl-shift-' |
| 509 | - case('F') | 456 | + case(7) ! Alt+Ctrl |
| 510 | - key_str = trim(key_str) // 'end' | 457 | + key_str = 'alt-ctrl-' |
| 511 | - case('Z') | 458 | + case(8) ! Alt+Shift (or Option+Shift) |
| 512 | - ! Shift+Z could be ctrl-shift-z for redo | 459 | + key_str = 'alt-shift-' |
| 513 | - if (index(key_str, 'ctrl-shift') == 1) then | 460 | + case(9) ! Alt+Cmd (or Option+Cmd on macOS) |
| 514 | - key_str = 'ctrl-shift-z' | 461 | + key_str = 'opt-meta-' |
| 515 | - else | 462 | + case default |
| 516 | - key_str = trim(key_str) // 'Z' | 463 | + key_str = '' |
| 517 | - end if | 464 | + end select |
| 518 | - case('~') | 465 | + |
| 519 | - ! Check what special key it is based on the beginning of modifier_seq | 466 | + ! Append the key type using the terminator character |
| 520 | - if (index(modifier_seq, ';') == 1 .and. len_trim(modifier_seq) > 1) then | 467 | + select case(terminator) |
| 521 | - ! Already read the ;2 or ;5 etc, the key type should be before | 468 | + case('A') |
| 522 | - key_str = trim(key_str) // 'unknown' | 469 | + key_str = trim(key_str) // 'up' |
| 523 | - end if | 470 | + case('B') |
| 524 | - end select | 471 | + key_str = trim(key_str) // 'down' |
| 525 | - end if | 472 | + case('C') |
| 473 | + key_str = trim(key_str) // 'right' | ||
| 474 | + case('D') | ||
| 475 | + key_str = trim(key_str) // 'left' | ||
| 476 | + case('H') | ||
| 477 | + key_str = trim(key_str) // 'home' | ||
| 478 | + case('F') | ||
| 479 | + key_str = trim(key_str) // 'end' | ||
| 480 | + case('Z') | ||
| 481 | + ! Shift+Z could be ctrl-shift-z for redo | ||
| 482 | + if (index(key_str, 'ctrl-shift') == 1) then | ||
| 483 | + key_str = 'ctrl-shift-z' | ||
| 484 | + else | ||
| 485 | + key_str = trim(key_str) // 'Z' | ||
| 486 | + end if | ||
| 487 | + case('~') | ||
| 488 | + ! Check what special key it is based on the beginning of modifier_seq | ||
| 489 | + if (index(modifier_seq, ';') == 1 .and. len_trim(modifier_seq) > 1) then | ||
| 490 | + ! Already read the ;2 or ;5 etc, the key type should be before | ||
| 491 | + key_str = trim(key_str) // 'unknown' | ||
| 492 | + end if | ||
| 493 | + end select | ||
| 526 | end if | 494 | end if |
| 527 | end subroutine handle_modified_key | 495 | end subroutine handle_modified_key |
| 528 | 496 | ||
src/ui/help_display_module.f90modified@@ -114,7 +114,7 @@ contains | |||
| 114 | n_lines = n_lines + 7 + 2 ! PANES | 114 | n_lines = n_lines + 7 + 2 ! PANES |
| 115 | n_lines = n_lines + 10 + 2 ! GIT | 115 | n_lines = n_lines + 10 + 2 ! GIT |
| 116 | n_lines = n_lines + 5 + 2 ! FILE | 116 | n_lines = n_lines + 5 + 2 ! FILE |
| 117 | - n_lines = n_lines + 6 + 2 ! LSP | 117 | + n_lines = n_lines + 7 + 2 ! LSP (added code actions) |
| 118 | 118 | ||
| 119 | allocate(lines(n_lines)) | 119 | allocate(lines(n_lines)) |
| 120 | i = 1 | 120 | i = 1 |
@@ -244,14 +244,14 @@ contains | |||
| 244 | ! LSP (Language Server Protocol) | 244 | ! LSP (Language Server Protocol) |
| 245 | lines(i) = "LSP (Language Server Protocol)"; i = i + 1 | 245 | lines(i) = "LSP (Language Server Protocol)"; i = i + 1 |
| 246 | lines(i) = " ctrl-space code completion"; i = i + 1 | 246 | lines(i) = " ctrl-space code completion"; i = i + 1 |
| 247 | - lines(i) = " ctrl-h hover information"; i = i + 1 | 247 | + lines(i) = " F12/alt-g go to definition"; i = i + 1 |
| 248 | - lines(i) = " F12 go to definition"; i = i + 1 | 248 | + lines(i) = " shift-F12/alt-r find all references"; i = i + 1 |
| 249 | - lines(i) = " shift-F12 find all references"; i = i + 1 | ||
| 250 | lines(i) = " alt-, (alt-comma) jump back (navigation history)"; i = i + 1 | 249 | lines(i) = " alt-, (alt-comma) jump back (navigation history)"; i = i + 1 |
| 251 | lines(i) = " F2 rename symbol"; i = i + 1 | 250 | lines(i) = " F2 rename symbol"; i = i + 1 |
| 252 | - lines(i) = " F4 document symbols (outline)"; i = i + 1 | 251 | + lines(i) = " F10/alt-. code actions (quick fixes)"; i = i + 1 |
| 253 | - lines(i) = " F6 workspace symbols (search project)"; i = i + 1 | 252 | + lines(i) = " F4/alt-o document symbols (outline)"; i = i + 1 |
| 254 | - lines(i) = " F8 toggle diagnostics panel (errors)"; i = i + 1 | 253 | + lines(i) = " F6/alt-p workspace symbols (search project)"; i = i + 1 |
| 254 | + lines(i) = " F8/alt-e toggle diagnostics panel (errors)"; i = i + 1 | ||
| 255 | lines(i) = " ctrl-p command palette"; i = i + 1 | 255 | lines(i) = " ctrl-p command palette"; i = i + 1 |
| 256 | lines(i) = ""; i = i + 1 | 256 | lines(i) = ""; i = i + 1 |
| 257 | 257 | ||
src/ui/rename_prompt_module.f90modified@@ -23,18 +23,6 @@ contains | |||
| 23 | ! Show the text prompt | 23 | ! Show the text prompt |
| 24 | call show_text_prompt(trim(prompt_text), input_text, cancelled, screen_rows) | 24 | call show_text_prompt(trim(prompt_text), input_text, cancelled, screen_rows) |
| 25 | 25 | ||
| 26 | - ! Debug logging | ||
| 27 | - block | ||
| 28 | - integer :: debug_unit | ||
| 29 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 30 | - write(debug_unit, '(A)') '>>> RENAME PROMPT RETURNED <<<' | ||
| 31 | - write(debug_unit, '(A,L1)') 'Cancelled: ', cancelled | ||
| 32 | - write(debug_unit, '(A)') 'Input text: "' // trim(input_text) // '"' | ||
| 33 | - write(debug_unit, '(A)') 'Old name: "' // trim(old_name) // '"' | ||
| 34 | - write(debug_unit, '(A,I0)') 'Input length: ', len_trim(input_text) | ||
| 35 | - close(debug_unit) | ||
| 36 | - end block | ||
| 37 | - | ||
| 38 | if (.not. cancelled) then | 26 | if (.not. cancelled) then |
| 39 | if (len_trim(input_text) > 0 .and. trim(input_text) /= trim(old_name)) then | 27 | if (len_trim(input_text) > 0 .and. trim(input_text) /= trim(old_name)) then |
| 40 | allocate(character(len=len_trim(input_text)) :: new_name) | 28 | allocate(character(len=len_trim(input_text)) :: new_name) |
@@ -43,19 +31,6 @@ contains | |||
| 43 | cancelled = .true. | 31 | cancelled = .true. |
| 44 | end if | 32 | end if |
| 45 | end if | 33 | end if |
| 46 | - | ||
| 47 | - ! Debug logging after check | ||
| 48 | - block | ||
| 49 | - integer :: debug_unit | ||
| 50 | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') | ||
| 51 | - write(debug_unit, '(A,L1)') 'Final cancelled: ', cancelled | ||
| 52 | - if (allocated(new_name)) then | ||
| 53 | - write(debug_unit, '(A)') 'New name allocated: "' // trim(new_name) // '"' | ||
| 54 | - else | ||
| 55 | - write(debug_unit, '(A)') 'New name NOT allocated' | ||
| 56 | - end if | ||
| 57 | - close(debug_unit) | ||
| 58 | - end block | ||
| 59 | end subroutine show_rename_prompt | 34 | end subroutine show_rename_prompt |
| 60 | 35 | ||
| 61 | end module rename_prompt_module | 36 | end module rename_prompt_module |
src/workspace/workspace_module.f90modified@@ -231,25 +231,9 @@ contains | |||
| 231 | success = .false. | 231 | success = .false. |
| 232 | workspace_file = trim(dir_path) // "/.fac/workspace.json" | 232 | workspace_file = trim(dir_path) // "/.fac/workspace.json" |
| 233 | 233 | ||
| 234 | - ! DEBUG: Write to stderr (unit 0) so it doesn't interfere | ||
| 235 | - write(0, '(A)') '[DEBUG SAVE] workspace_save_state called' | ||
| 236 | - write(0, '(A)') '[DEBUG SAVE] Workspace file: ' // trim(workspace_file) | ||
| 237 | - if (allocated(editor%tabs)) then | ||
| 238 | - write(0, '(A,I0)') '[DEBUG SAVE] Tabs allocated, size: ', size(editor%tabs) | ||
| 239 | - if (size(editor%tabs) > 0) then | ||
| 240 | - write(0, '(A)') '[DEBUG SAVE] First tab filename: ' // trim(editor%tabs(1)%filename) | ||
| 241 | - end if | ||
| 242 | - else | ||
| 243 | - write(0, '(A)') '[DEBUG SAVE] ERROR: Tabs not allocated!' | ||
| 244 | - end if | ||
| 245 | - write(0, '(A,I0)') '[DEBUG SAVE] Active tab index: ', editor%active_tab_index | ||
| 246 | - | ||
| 247 | ! Open file for writing | 234 | ! Open file for writing |
| 248 | open(newunit=unit, file=workspace_file, status='replace', iostat=ios) | 235 | open(newunit=unit, file=workspace_file, status='replace', iostat=ios) |
| 249 | - if (ios /= 0) then | 236 | + if (ios /= 0) return |
| 250 | - write(0, '(A,I0)') '[DEBUG SAVE] ERROR: Failed to open file, ios=', ios | ||
| 251 | - return | ||
| 252 | - end if | ||
| 253 | 237 | ||
| 254 | ! Get current timestamp (simplified) | 238 | ! Get current timestamp (simplified) |
| 255 | call date_and_time(timestamp) | 239 | call date_and_time(timestamp) |
@@ -263,7 +247,6 @@ contains | |||
| 263 | 247 | ||
| 264 | ! Write tabs | 248 | ! Write tabs |
| 265 | if (allocated(editor%tabs)) then | 249 | if (allocated(editor%tabs)) then |
| 266 | - write(0, '(A,I0)') '[DEBUG SAVE] Writing ', size(editor%tabs), ' tabs' | ||
| 267 | ws_len = len_trim(dir_path) | 250 | ws_len = len_trim(dir_path) |
| 268 | do i = 1, size(editor%tabs) | 251 | do i = 1, size(editor%tabs) |
| 269 | ! Write tab start - must be on its own line for parser | 252 | ! Write tab start - must be on its own line for parser |
@@ -426,33 +409,18 @@ contains | |||
| 426 | logical :: file_exists | 409 | logical :: file_exists |
| 427 | integer :: load_status, tab_idx, pane_count, file_unit | 410 | integer :: load_status, tab_idx, pane_count, file_unit |
| 428 | character(len=20) :: value_str | 411 | character(len=20) :: value_str |
| 429 | - character(len=512) :: warning_msg | ||
| 430 | - | ||
| 431 | - ! DEBUG: Start of restoration | ||
| 432 | - write(0, '(A)') '[DEBUG RESTORE WS] workspace_restore_state called' | ||
| 433 | - write(0, '(A)') '[DEBUG RESTORE WS] Dir path: ' // trim(dir_path) | ||
| 434 | 412 | ||
| 435 | success = .false. | 413 | success = .false. |
| 436 | workspace_file = trim(dir_path) // "/.fac/workspace.json" | 414 | workspace_file = trim(dir_path) // "/.fac/workspace.json" |
| 437 | 415 | ||
| 438 | - write(0, '(A)') '[DEBUG RESTORE WS] Workspace file: ' // trim(workspace_file) | ||
| 439 | - | ||
| 440 | ! Open workspace file | 416 | ! Open workspace file |
| 441 | open(newunit=unit, file=workspace_file, status='old', iostat=ios) | 417 | open(newunit=unit, file=workspace_file, status='old', iostat=ios) |
| 442 | if (ios /= 0) then | 418 | if (ios /= 0) then |
| 443 | - ! Workspace file doesn't exist or can't be read (Phase 7: error handling) | 419 | + ! Workspace file doesn't exist or can't be read - initialize new workspace |
| 444 | - write(0, '(A,I0)') '[DEBUG RESTORE WS] ERROR: Failed to open workspace.json, ios=', ios | ||
| 445 | - warning_msg = "Warning: Could not open workspace.json - using empty workspace" | ||
| 446 | - call terminal_write(trim(warning_msg)) | ||
| 447 | - ! Brief pause so user can see the warning | ||
| 448 | - call execute_command_line("sleep 1.0", wait=.true.) | ||
| 449 | - ! Initialize a new workspace instead | ||
| 450 | call workspace_init(dir_path, success) | 420 | call workspace_init(dir_path, success) |
| 451 | return | 421 | return |
| 452 | end if | 422 | end if |
| 453 | 423 | ||
| 454 | - write(0, '(A)') '[DEBUG RESTORE WS] Workspace file opened successfully' | ||
| 455 | - | ||
| 456 | ! Parse JSON line by line (simple parser for our specific format) | 424 | ! Parse JSON line by line (simple parser for our specific format) |
| 457 | in_tabs_array = .false. | 425 | in_tabs_array = .false. |
| 458 | reading_tab = .false. | 426 | reading_tab = .false. |
@@ -601,28 +569,19 @@ contains | |||
| 601 | end if | 569 | end if |
| 602 | 570 | ||
| 603 | if (.not. file_exists) then | 571 | if (.not. file_exists) then |
| 604 | - ! File doesn't exist - show warning and skip this tab | 572 | + ! File doesn't exist - skip this tab silently |
| 605 | - warning_msg = "Warning: File not found (skipping): " // trim(full_path) | ||
| 606 | - call terminal_write(trim(warning_msg)) | ||
| 607 | - ! Brief pause so user can see the warning | ||
| 608 | - call execute_command_line("sleep 0.8", wait=.true.) | ||
| 609 | - ! Continue to next tab without creating this one | ||
| 610 | reading_pane = .false. | 573 | reading_pane = .false. |
| 611 | cycle | 574 | cycle |
| 612 | end if | 575 | end if |
| 613 | 576 | ||
| 614 | ! Create tab | 577 | ! Create tab |
| 615 | - write(0, '(A)') '[DEBUG RESTORE WS] Creating tab for file: ' // trim(full_path) | ||
| 616 | call create_tab(editor, trim(full_path)) | 578 | call create_tab(editor, trim(full_path)) |
| 617 | tab_idx = editor%active_tab_index | 579 | tab_idx = editor%active_tab_index |
| 618 | 580 | ||
| 619 | ! Set orphan flag and load file | 581 | ! Set orphan flag and load file |
| 620 | if (allocated(editor%tabs) .and. tab_idx > 0) then | 582 | if (allocated(editor%tabs) .and. tab_idx > 0) then |
| 621 | - write(0, '(A,I0)') '[DEBUG RESTORE WS] Tab created successfully, index: ', tab_idx | ||
| 622 | editor%tabs(tab_idx)%is_orphan = is_orphan | 583 | editor%tabs(tab_idx)%is_orphan = is_orphan |
| 623 | - | ||
| 624 | call buffer_load_file(editor%tabs(tab_idx)%buffer, trim(full_path), load_status) | 584 | call buffer_load_file(editor%tabs(tab_idx)%buffer, trim(full_path), load_status) |
| 625 | - write(0, '(A,I0)') '[DEBUG RESTORE WS] Buffer loaded, status: ', load_status | ||
| 626 | 585 | ||
| 627 | ! Send LSP didOpen notification for restored tabs | 586 | ! Send LSP didOpen notification for restored tabs |
| 628 | if (load_status == 0 .and. editor%tabs(tab_idx)%num_lsp_servers > 0) then | 587 | if (load_status == 0 .and. editor%tabs(tab_idx)%num_lsp_servers > 0) then |
@@ -799,11 +758,8 @@ contains | |||
| 799 | 758 | ||
| 800 | close(unit) | 759 | close(unit) |
| 801 | 760 | ||
| 802 | - write(0, '(A)') '[DEBUG RESTORE WS] Finished parsing JSON' | ||
| 803 | - | ||
| 804 | ! Clamp active_tab_index to valid range | 761 | ! Clamp active_tab_index to valid range |
| 805 | if (allocated(editor%tabs)) then | 762 | if (allocated(editor%tabs)) then |
| 806 | - write(0, '(A,I0)') '[DEBUG RESTORE WS] Tabs allocated, count: ', size(editor%tabs) | ||
| 807 | if (size(editor%tabs) > 0) then | 763 | if (size(editor%tabs) > 0) then |
| 808 | if (editor%active_tab_index > size(editor%tabs)) then | 764 | if (editor%active_tab_index > size(editor%tabs)) then |
| 809 | editor%active_tab_index = size(editor%tabs) | 765 | editor%active_tab_index = size(editor%tabs) |
@@ -812,16 +768,12 @@ contains | |||
| 812 | editor%active_tab_index = 1 | 768 | editor%active_tab_index = 1 |
| 813 | end if | 769 | end if |
| 814 | else | 770 | else |
| 815 | - write(0, '(A)') '[DEBUG RESTORE WS] No tabs in array!' | ||
| 816 | editor%active_tab_index = 0 ! No tabs | 771 | editor%active_tab_index = 0 ! No tabs |
| 817 | end if | 772 | end if |
| 818 | else | 773 | else |
| 819 | - write(0, '(A)') '[DEBUG RESTORE WS] Tabs NOT allocated!' | ||
| 820 | editor%active_tab_index = 0 ! No tabs | 774 | editor%active_tab_index = 0 ! No tabs |
| 821 | end if | 775 | end if |
| 822 | 776 | ||
| 823 | - write(0, '(A,I0)') '[DEBUG RESTORE WS] Final active_tab_index: ', editor%active_tab_index | ||
| 824 | - | ||
| 825 | ! Sync the active pane to editor state so status bar shows correct filename | 777 | ! Sync the active pane to editor state so status bar shows correct filename |
| 826 | if (allocated(editor%tabs) .and. editor%active_tab_index > 0) then | 778 | if (allocated(editor%tabs) .and. editor%active_tab_index > 0) then |
| 827 | if (editor%active_tab_index <= size(editor%tabs)) then | 779 | if (editor%active_tab_index <= size(editor%tabs)) then |
@@ -829,7 +781,6 @@ contains | |||
| 829 | if (editor%tabs(editor%active_tab_index)%active_pane_index > 0 .and. & | 781 | if (editor%tabs(editor%active_tab_index)%active_pane_index > 0 .and. & |
| 830 | editor%tabs(editor%active_tab_index)%active_pane_index <= & | 782 | editor%tabs(editor%active_tab_index)%active_pane_index <= & |
| 831 | size(editor%tabs(editor%active_tab_index)%panes)) then | 783 | size(editor%tabs(editor%active_tab_index)%panes)) then |
| 832 | - write(0, '(A)') '[DEBUG RESTORE WS] Syncing active pane to editor' | ||
| 833 | call sync_pane_to_editor(editor, editor%active_tab_index, & | 784 | call sync_pane_to_editor(editor, editor%active_tab_index, & |
| 834 | editor%tabs(editor%active_tab_index)%active_pane_index) | 785 | editor%tabs(editor%active_tab_index)%active_pane_index) |
| 835 | end if | 786 | end if |
@@ -838,7 +789,6 @@ contains | |||
| 838 | end if | 789 | end if |
| 839 | 790 | ||
| 840 | success = .true. | 791 | success = .true. |
| 841 | - write(0, '(A)') '[DEBUG RESTORE WS] workspace_restore_state completed successfully' | ||
| 842 | end subroutine workspace_restore_state | 792 | end subroutine workspace_restore_state |
| 843 | 793 | ||
| 844 | !> Track workspace in recents (helper function) | 794 | !> Track workspace in recents (helper function) |
tests/scratch_files/calculator.pymodified@@ -11,6 +11,7 @@ Test these features: | |||
| 11 | - Formatting: Shift+Alt+F to format | 11 | - Formatting: Shift+Alt+F to format |
| 12 | """ | 12 | """ |
| 13 | 13 | ||
| 14 | + | ||
| 14 | def add(x, y): | 15 | def add(x, y): |
| 15 | """Add two numbers together.""" | 16 | """Add two numbers together.""" |
| 16 | return x + y | 17 | return x + y |
tests/scratch_files/long_errors.pymodified@@ -1,6 +1,6 @@ | |||
| 1 | # Test file with errors that generate long diagnostic messages | 1 | # Test file with errors that generate long diagnostic messages |
| 2 | 2 | ||
| 3 | -from typing import Dict, List, Optional, Union, Callable | 3 | +from typing import Callable, Dict, List, Optional, Union |
| 4 | 4 | ||
| 5 | # Type mismatch with long type names | 5 | # Type mismatch with long type names |
| 6 | def process_data( | 6 | def process_data( |