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 | 119 | ! User selected a workspace from welcome menu (not browse) |
| 120 | 120 | ! This handles favorites, recents, and CURRENT DIRECTORY |
| 121 | 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 | 122 | ! Check if user selected CURRENT DIRECTORY option |
| 126 | 123 | if (selected_path == "CWD") then |
| 127 | - write(0, '(A)') '[DEBUG WELCOME] CWD selected, getting workspace path' | |
| 128 | 124 | ! Get actual current working directory |
| 129 | 125 | call get_workspace_path(selected_path) |
| 130 | - write(0, '(A)') '[DEBUG WELCOME] Workspace path: ' // selected_path | |
| 131 | 126 | arg = selected_path |
| 132 | 127 | else |
| 133 | - write(0, '(A)') '[DEBUG WELCOME] Not CWD, using selected_path directly' | |
| 134 | 128 | arg = selected_path |
| 135 | 129 | end if |
| 136 | 130 | |
| 137 | 131 | ! Check if it's a directory |
| 138 | - write(0, '(A)') '[DEBUG WELCOME] Testing if directory: ' // trim(arg) | |
| 139 | 132 | call execute_command_line("test -d '" // trim(arg) // & |
| 140 | 133 | "' && echo 'Directory' > /tmp/.fac_filetype || " // & |
| 141 | 134 | "echo 'File' > /tmp/.fac_filetype", wait=.true.) |
| 142 | 135 | call read_file_type(status) |
| 143 | - write(0, '(A,I0)') '[DEBUG WELCOME] read_file_type status: ', status | |
| 144 | 136 | if (status == 0) then |
| 145 | 137 | ! Directory - workspace mode |
| 146 | - write(0, '(A)') '[DEBUG WELCOME] Setting is_workspace_mode = TRUE' | |
| 147 | 138 | is_workspace_mode = .true. |
| 148 | 139 | call workspace_get_path(trim(arg), workspace_dir) |
| 149 | - write(0, '(A)') '[DEBUG WELCOME] workspace_dir: ' // trim(workspace_dir) | |
| 150 | 140 | else |
| 151 | 141 | ! Invalid selection (favorites/recents should only have directories) |
| 152 | 142 | write(error_unit, '(A)') 'Error: Selected path is not a directory' |
| 153 | 143 | stop 1 |
| 154 | 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 | 145 | end if |
| 162 | 146 | end if |
| 163 | 147 | |
| 164 | 148 | ! Handle workspace mode |
| 165 | - write(0, '(A,L1)') '[DEBUG WORKSPACE] is_workspace_mode: ', is_workspace_mode | |
| 166 | 149 | if (is_workspace_mode) then |
| 167 | - write(0, '(A)') '[DEBUG WORKSPACE] In workspace mode, workspace_dir: ' // trim(workspace_dir) | |
| 168 | 150 | ! Check if workspace exists, create if not |
| 169 | 151 | if (.not. workspace_exists(workspace_dir)) then |
| 170 | - write(0, '(A)') '[DEBUG WORKSPACE] Workspace does not exist, creating' | |
| 171 | 152 | call workspace_init(workspace_dir, workspace_success) |
| 172 | 153 | if (.not. workspace_success) then |
| 173 | 154 | write(error_unit, '(A)') 'Error: Failed to create workspace' |
| 174 | 155 | stop 1 |
| 175 | 156 | end if |
| 176 | 157 | else |
| 177 | - write(0, '(A)') '[DEBUG WORKSPACE] Workspace exists, loading' | |
| 178 | 158 | ! Load existing workspace |
| 179 | 159 | call workspace_load(workspace_dir, workspace_success) |
| 180 | 160 | if (.not. workspace_success) then |
@@ -182,8 +162,6 @@ program facsimile | ||
| 182 | 162 | stop 1 |
| 183 | 163 | end if |
| 184 | 164 | end if |
| 185 | - else | |
| 186 | - write(0, '(A)') '[DEBUG WORKSPACE] NOT in workspace mode' | |
| 187 | 165 | end if |
| 188 | 166 | |
| 189 | 167 | ! Initialize editor |
@@ -204,46 +182,23 @@ program facsimile | ||
| 204 | 182 | call init_buffer(buffer) |
| 205 | 183 | |
| 206 | 184 | ! Set workspace path |
| 207 | - write(0, '(A,L1)') '[DEBUG RESTORE CHECK] is_workspace_mode: ', is_workspace_mode | |
| 208 | 185 | if (is_workspace_mode) then |
| 209 | - write(0, '(A)') '[DEBUG RESTORE CHECK] workspace_dir: ' // trim(workspace_dir) | |
| 210 | 186 | ! Use detected/created workspace directory |
| 211 | 187 | allocate(character(len=len_trim(workspace_dir)) :: editor%workspace_path) |
| 212 | 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 | 190 | ! Restore workspace state (tabs, cursor positions, etc.) |
| 219 | 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 | 193 | ! Sync restored active tab's buffer to main buffer |
| 231 | 194 | if (workspace_success .and. allocated(editor%tabs) .and. editor%active_tab_index > 0) then |
| 232 | 195 | if (editor%active_tab_index <= size(editor%tabs)) then |
| 233 | 196 | if (allocated(editor%tabs(editor%active_tab_index)%panes) .and. & |
| 234 | 197 | size(editor%tabs(editor%active_tab_index)%panes) > 0) then |
| 235 | 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 | 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 | 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 | 201 | end if |
| 245 | - else | |
| 246 | - write(0, '(A)') '[DEBUG RESTORE] Skipping buffer sync - conditions not met' | |
| 247 | 202 | end if |
| 248 | 203 | else |
| 249 | 204 | ! Single-file mode - use current directory |
@@ -515,11 +470,6 @@ contains | ||
| 515 | 470 | use terminal_io_module, only: terminal_write |
| 516 | 471 | type(lsp_message_t), intent(in) :: notification |
| 517 | 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 | 474 | ! Parse and store diagnostics with server attribution (for multi-LSP) |
| 525 | 475 | ! This keeps diagnostics from different servers separate |
src/commands/command_handler_module.f90modified@@ -1386,15 +1386,15 @@ contains | ||
| 1386 | 1386 | |
| 1387 | 1387 | ! Check if rename response modified the buffer |
| 1388 | 1388 | if (g_lsp_modified_buffer) then |
| 1389 | - ! Sync buffer from tab (LSP modified tab buffer) | |
| 1390 | - call copy_buffer(buffer, editor%tabs(editor%active_tab_index)%buffer) | |
| 1391 | - | |
| 1392 | - ! Also sync to active pane buffer if panes exist | |
| 1389 | + ! LSP now modifies pane buffer directly, sync FROM pane TO local buffer and tab | |
| 1393 | 1390 | if (allocated(editor%tabs(editor%active_tab_index)%panes) .and. & |
| 1394 | 1391 | size(editor%tabs(editor%active_tab_index)%panes) > 0) then |
| 1395 | 1392 | pane_idx = editor%tabs(editor%active_tab_index)%active_pane_index |
| 1396 | 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 | 1398 | end if |
| 1399 | 1399 | end if |
| 1400 | 1400 | |
@@ -6313,14 +6313,16 @@ contains | ||
| 6313 | 6313 | subroutine apply_file_edits_obj(editor, uri, edits_arr, changes_applied) |
| 6314 | 6314 | use json_module, only: json_value_t, json_array_size, json_get_array_element, & |
| 6315 | 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 | 6318 | type(editor_state_t), intent(inout) :: editor |
| 6317 | 6319 | character(len=*), intent(in) :: uri |
| 6318 | 6320 | type(json_value_t), intent(in) :: edits_arr |
| 6319 | 6321 | integer, intent(inout) :: changes_applied |
| 6320 | 6322 | |
| 6321 | 6323 | type(json_value_t) :: edit_obj, range_obj, start_obj, end_obj |
| 6322 | - character(len=:), allocatable :: filename, new_text | |
| 6323 | - integer :: num_edits, i, j, tab_idx | |
| 6324 | + character(len=:), allocatable :: filename, new_text, buffer_content | |
| 6325 | + integer :: num_edits, i, j, tab_idx, server_idx, pane_idx | |
| 6324 | 6326 | integer :: start_line, start_char, end_line, end_char |
| 6325 | 6327 | |
| 6326 | 6328 | ! Convert URI to filename |
@@ -6356,6 +6358,25 @@ contains | ||
| 6356 | 6358 | return |
| 6357 | 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 | 6380 | ! Apply edits in reverse order (to preserve line numbers) |
| 6360 | 6381 | num_edits = json_array_size(edits_arr) |
| 6361 | 6382 | |
@@ -6379,15 +6400,53 @@ contains | ||
| 6379 | 6400 | new_text = json_get_string(edit_obj, 'newText') |
| 6380 | 6401 | |
| 6381 | 6402 | if (allocated(new_text)) then |
| 6382 | - ! Apply the edit to the buffer | |
| 6383 | - call apply_single_edit(editor%tabs(tab_idx)%buffer, & | |
| 6403 | + ! Apply the edit to the pane buffer (not tab buffer!) | |
| 6404 | + call apply_single_edit(editor%tabs(tab_idx)%panes(pane_idx)%buffer, & | |
| 6384 | 6405 | start_line, start_char, end_line, end_char, new_text) |
| 6385 | 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 | 6420 | deallocate(new_text) |
| 6387 | 6421 | end if |
| 6388 | 6422 | end if |
| 6389 | 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 | 6450 | if (allocated(filename)) deallocate(filename) |
| 6392 | 6451 | end subroutine apply_file_edits_obj |
| 6393 | 6452 | |
@@ -6398,23 +6457,62 @@ contains | ||
| 6398 | 6457 | character(len=*), intent(in) :: new_text |
| 6399 | 6458 | |
| 6400 | 6459 | integer :: start_pos, end_pos, delete_count |
| 6460 | + integer :: debug_unit | |
| 6461 | + character(len=256) :: debug_msg | |
| 6401 | 6462 | |
| 6402 | 6463 | ! Calculate buffer positions |
| 6403 | 6464 | start_pos = get_buffer_position(buffer, start_line, start_char) |
| 6404 | 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 | 6481 | if (start_pos <= 0 .or. end_pos <= 0) return |
| 6407 | 6482 | |
| 6408 | 6483 | ! Delete the old text |
| 6409 | 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 | 6493 | if (delete_count > 0) then |
| 6411 | 6494 | call buffer_delete(buffer, start_pos, delete_count) |
| 6412 | 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 | 6504 | ! Insert the new text |
| 6415 | 6505 | if (len(new_text) > 0) then |
| 6416 | 6506 | call buffer_insert(buffer, start_pos, new_text) |
| 6417 | 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 | 6516 | end subroutine apply_single_edit |
| 6419 | 6517 | |
| 6420 | 6518 | ! Execute a command from the command palette |
src/lsp/diagnostics_module.f90modified@@ -108,16 +108,11 @@ contains | ||
| 108 | 108 | character(len=:), allocatable :: uri |
| 109 | 109 | integer :: i, n_diagnostics, file_idx |
| 110 | 110 | type(diagnostic_t) :: diag |
| 111 | - character(len=512) :: debug_msg | |
| 112 | 111 | |
| 113 | 112 | ! Get URI |
| 114 | 113 | if (.not. json_has_key(params, "uri")) return |
| 115 | 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 | 116 | ! Find or create file entry |
| 122 | 117 | file_idx = find_or_create_file(store, uri) |
| 123 | 118 | |
@@ -132,10 +127,6 @@ contains | ||
| 132 | 127 | diagnostics_array = json_get_array(params, "diagnostics") |
| 133 | 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 | 130 | if (n_diagnostics > 0) then |
| 140 | 131 | allocate(store%files(file_idx)%items(n_diagnostics)) |
| 141 | 132 | store%files(file_idx)%count = n_diagnostics |
@@ -208,17 +199,12 @@ contains | ||
| 208 | 199 | character(len=:), allocatable :: uri |
| 209 | 200 | integer :: i, n_diagnostics, file_idx, old_count, new_count, j |
| 210 | 201 | type(diagnostic_t) :: diag |
| 211 | - type(diagnostic_t), allocatable :: old_items(:), new_items(:) | |
| 212 | - character(len=512) :: debug_msg | |
| 202 | + type(diagnostic_t), allocatable :: old_items(:) | |
| 213 | 203 | |
| 214 | 204 | ! Get URI |
| 215 | 205 | if (.not. json_has_key(params, "uri")) return |
| 216 | 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 | 208 | ! Find or create file entry |
| 223 | 209 | file_idx = find_or_create_file(store, uri) |
| 224 | 210 | |
@@ -255,10 +241,6 @@ contains | ||
| 255 | 241 | n_diagnostics = json_array_size(diagnostics_array) |
| 256 | 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 | 244 | ! Allocate combined array |
| 263 | 245 | new_count = old_count + n_diagnostics |
| 264 | 246 | if (new_count > 0) then |
src/lsp/lsp_protocol_module.f90modified@@ -106,16 +106,6 @@ contains | ||
| 106 | 106 | ! Convert root_path to absolute path |
| 107 | 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 | 109 | params = json_create_object() |
| 120 | 110 | call json_add_number(params, "processId", real(process_id, real64)) |
| 121 | 111 | call json_add_string(params, "rootPath", abs_root_path) |
@@ -238,7 +228,7 @@ contains | ||
| 238 | 228 | changes = json_create_array() |
| 239 | 229 | change = json_create_object() |
| 240 | 230 | call json_add_string(change, "text", text) |
| 241 | - ! TODO: Add change to array | |
| 231 | + call json_array_add_element(changes, change) | |
| 242 | 232 | call json_add_array(params, "contentChanges", changes) |
| 243 | 233 | |
| 244 | 234 | msg%params = params |
src/lsp/lsp_server_manager_module.f90modified@@ -375,16 +375,6 @@ contains | ||
| 375 | 375 | return |
| 376 | 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 | 378 | ! Expand server array |
| 389 | 379 | allocate(new_servers(manager%num_servers + 1)) |
| 390 | 380 | if (manager%num_servers > 0) then |
@@ -467,98 +457,20 @@ contains | ||
| 467 | 457 | procedure(response_callback), optional :: callback |
| 468 | 458 | character(len=:), allocatable :: json_msg |
| 469 | 459 | |
| 470 | - block | |
| 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 | |
| 460 | + if (server_index < 1 .or. server_index > manager%num_servers) return | |
| 488 | 461 | |
| 489 | 462 | if (.not. manager%servers(server_index)%initialized .and. & |
| 490 | - .not. manager%servers(server_index)%initializing) then | |
| 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 | |
| 463 | + .not. manager%servers(server_index)%initializing) return | |
| 508 | 464 | |
| 509 | 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 | 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 | 468 | ! Track request and register callback |
| 529 | 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 | 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 | 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 | 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 | 474 | end subroutine send_request |
| 563 | 475 | |
| 564 | 476 | subroutine send_notification(server, msg) |
@@ -569,52 +481,15 @@ contains | ||
| 569 | 481 | if (.not. server%initialized .and. .not. server%initializing) return |
| 570 | 482 | |
| 571 | 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 | 484 | call send_raw_message(server, json_msg) |
| 585 | 485 | end subroutine send_notification |
| 586 | 486 | |
| 587 | 487 | subroutine send_raw_message(server, message) |
| 588 | 488 | type(lsp_server_t), intent(inout) :: server |
| 589 | 489 | character(len=*), intent(in) :: message |
| 590 | - integer :: result, debug_unit | |
| 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 | |
| 490 | + integer :: result | |
| 610 | 491 | |
| 611 | - ! Log outgoing messages for debugging | |
| 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) | |
| 492 | + if (.not. c_associated(server%handle)) return | |
| 618 | 493 | |
| 619 | 494 | result = lsp_send_message_f(server%handle, message//c_null_char, len(message)) |
| 620 | 495 | |
@@ -675,18 +550,6 @@ contains | ||
| 675 | 550 | |
| 676 | 551 | ! Extract and parse message |
| 677 | 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 | 553 | msg = parse_lsp_message(message) |
| 691 | 554 | |
| 692 | 555 | ! Handle the message |
@@ -818,19 +681,13 @@ contains | ||
| 818 | 681 | server%initialized = .true. |
| 819 | 682 | server%initializing = .false. |
| 820 | 683 | |
| 821 | - write(error_unit, '(a,a)') "LSP server initialized: ", server%language | |
| 822 | - | |
| 823 | 684 | ! Send all queued didOpen notifications |
| 824 | 685 | if (allocated(server%pending_didopens) .and. server%num_pending_didopens > 0) then |
| 825 | 686 | block |
| 826 | - integer :: i, debug_unit | |
| 687 | + integer :: i | |
| 827 | 688 | type(lsp_message_t) :: didopen_msg |
| 828 | 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 | 691 | do i = 1, server%num_pending_didopens |
| 835 | 692 | if (allocated(server%pending_didopens(i)%filename) .and. & |
| 836 | 693 | allocated(server%pending_didopens(i)%content)) then |
@@ -840,14 +697,6 @@ contains | ||
| 840 | 697 | didopen_msg = create_did_open_notification( & |
| 841 | 698 | file_uri, lang, 1, & |
| 842 | 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 | 700 | call send_notification(server, didopen_msg) |
| 852 | 701 | end if |
| 853 | 702 | end do |
@@ -865,9 +714,6 @@ contains | ||
| 865 | 714 | type(lsp_message_t), intent(in) :: msg |
| 866 | 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 | 717 | ! Find the server index for this server |
| 872 | 718 | srv_idx = 0 |
| 873 | 719 | do i = 1, manager%num_servers |
@@ -882,12 +728,9 @@ contains | ||
| 882 | 728 | |
| 883 | 729 | select case(msg%method) |
| 884 | 730 | case("textDocument/publishDiagnostics") |
| 885 | - write(error_unit, '(A,I0)') "[LSP DEBUG] Processing publishDiagnostics from server ", srv_idx | |
| 886 | 731 | ! Forward to diagnostics handler if set (with server index) |
| 887 | 732 | if (associated(manager%diagnostics_handler)) then |
| 888 | 733 | call manager%diagnostics_handler(msg, srv_idx) |
| 889 | - else | |
| 890 | - write(error_unit, '(A)') "[LSP DEBUG] No diagnostics handler set!" | |
| 891 | 734 | end if |
| 892 | 735 | case("window/showMessage") |
| 893 | 736 | ! TODO: Show message to user |
@@ -940,87 +783,19 @@ contains | ||
| 940 | 783 | procedure(response_callback) :: callback |
| 941 | 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 | 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 | 788 | if (manager%num_callbacks > 0) then |
| 969 | 789 | new_callbacks(1:manager%num_callbacks) = manager%callbacks |
| 970 | 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 | 792 | new_callbacks(manager%num_callbacks + 1)%request_id = request_id |
| 980 | 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 | 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 | 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 | 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 | 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 | 799 | end subroutine register_callback |
| 1025 | 800 | |
| 1026 | 801 | subroutine remove_callback(manager, index) |
@@ -1191,17 +966,6 @@ contains | ||
| 1191 | 966 | |
| 1192 | 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 | 969 | ! Expand server array |
| 1206 | 970 | allocate(new_servers(manager%num_servers + 1)) |
| 1207 | 971 | if (manager%num_servers > 0) then |
@@ -1280,14 +1044,6 @@ contains | ||
| 1280 | 1044 | |
| 1281 | 1045 | ! If server not initialized yet, queue the notification |
| 1282 | 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 | 1047 | ! Add to pending queue |
| 1292 | 1048 | if (allocated(manager%servers(server_index)%pending_didopens)) then |
| 1293 | 1049 | ! Grow array |
@@ -1322,14 +1078,6 @@ contains | ||
| 1322 | 1078 | return |
| 1323 | 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 | 1081 | ! Server is ready, send immediately |
| 1334 | 1082 | language = get_language_for_file(filename) |
| 1335 | 1083 | block |
@@ -1338,14 +1086,6 @@ contains | ||
| 1338 | 1086 | msg = create_did_open_notification(file_uri, language, 1, content) |
| 1339 | 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 | 1089 | call send_notification(manager%servers(server_index), msg) |
| 1350 | 1090 | end subroutine notify_file_opened |
| 1351 | 1091 | |
@@ -1359,6 +1099,16 @@ contains | ||
| 1359 | 1099 | integer, intent(in), optional :: version |
| 1360 | 1100 | type(lsp_message_t) :: msg |
| 1361 | 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 | 1113 | if (server_index < 1 .or. server_index > manager%num_servers) return |
| 1364 | 1114 | if (.not. manager%servers(server_index)%initialized) return |
@@ -1395,9 +1145,6 @@ contains | ||
| 1395 | 1145 | end if |
| 1396 | 1146 | |
| 1397 | 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 | 1148 | end subroutine notify_file_saved |
| 1402 | 1149 | |
| 1403 | 1150 | ! Send textDocument/didClose notification |
@@ -1477,55 +1224,14 @@ contains | ||
| 1477 | 1224 | type(lsp_message_t) :: msg |
| 1478 | 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 | 1227 | request_id = -1 |
| 1488 | 1228 | if (server_index < 1 .or. server_index > manager%num_servers) return |
| 1489 | 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 | 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 | 1232 | msg = create_definition_request(uri, line, character) |
| 1512 | 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 | 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 | 1235 | end function request_definition |
| 1530 | 1236 | |
| 1531 | 1237 | ! Request references at cursor position |
@@ -1568,19 +1274,9 @@ contains | ||
| 1568 | 1274 | integer :: request_id |
| 1569 | 1275 | type(lsp_message_t) :: msg |
| 1570 | 1276 | character(len=:), allocatable :: uri |
| 1571 | - integer :: dbg | |
| 1572 | 1277 | |
| 1573 | 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 | 1280 | if (server_index < 1 .or. server_index > manager%num_servers) return |
| 1585 | 1281 | if (.not. manager%servers(server_index)%initialized) return |
| 1586 | 1282 | |
src/terminal/input_handler_module.f90modified@@ -105,14 +105,6 @@ contains | ||
| 105 | 105 | end if |
| 106 | 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 | 108 | select case(ch2) |
| 117 | 109 | case('A') |
| 118 | 110 | key_str = 'up' |
@@ -187,22 +179,10 @@ contains | ||
| 187 | 179 | end if |
| 188 | 180 | case('1') |
| 189 | 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 | 182 | ! Check next character |
| 197 | 183 | char_code = terminal_read_char() |
| 198 | 184 | if (char_code >= 0) then |
| 199 | 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 | 186 | if (ch3 == '~') then |
| 207 | 187 | ! F1: ESC [ 1 1 ~ (alternate format) |
| 208 | 188 | key_str = 'f1' |
@@ -250,21 +230,9 @@ contains | ||
| 250 | 230 | end if |
| 251 | 231 | case('2') |
| 252 | 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 | 233 | char_code = terminal_read_char() |
| 260 | 234 | if (char_code >= 0) then |
| 261 | 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 | 236 | if (ch3 == '0' .or. ch3 == '1' .or. ch3 == '3' .or. ch3 == '4') then |
| 269 | 237 | ! Function keys F9-F12: ESC [ 2 X ~ or ESC [ 2 X ; modifier ~ |
| 270 | 238 | char_code = terminal_read_char() |
@@ -281,13 +249,6 @@ contains | ||
| 281 | 249 | key_str = 'f11' |
| 282 | 250 | case('4') |
| 283 | 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 | 252 | end select |
| 292 | 253 | else if (ch == ';') then |
| 293 | 254 | ! Modified F9-F12: ESC [ 2 X ; modifier ~ |
@@ -465,64 +426,71 @@ contains | ||
| 465 | 426 | if (terminator == '') return |
| 466 | 427 | |
| 467 | 428 | ! Parse modifier |
| 468 | - if (len_trim(modifier_seq) > 1 .and. modifier_seq(1:1) == ';') then | |
| 469 | - ! Standard format: ";2" where 2 is the modifier | |
| 429 | + if (len_trim(modifier_seq) >= 1 .and. modifier_seq(1:1) == ';') then | |
| 430 | + ! Standard format with leading ';': ";2" where 2 is the modifier | |
| 470 | 431 | if (len_trim(modifier_seq) >= 2) then |
| 471 | 432 | read(modifier_seq(2:len_trim(modifier_seq)), '(i10)', iostat=ios) modifier |
| 472 | 433 | else |
| 473 | 434 | ios = -1 |
| 474 | 435 | end if |
| 475 | - if (ios == 0) then | |
| 476 | - select case(modifier) | |
| 477 | - case(2) ! Shift | |
| 478 | - key_str = 'shift-' | |
| 479 | - case(3) ! Alt | |
| 480 | - key_str = 'alt-' | |
| 481 | - case(4) ! Alt+Shift | |
| 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 | |
| 436 | + else if (len_trim(modifier_seq) >= 1 .and. & | |
| 437 | + modifier_seq(1:1) >= '1' .and. modifier_seq(1:1) <= '9') then | |
| 438 | + ! Format without leading ';' (already consumed by caller): "2" or "3" etc | |
| 439 | + read(modifier_seq(1:len_trim(modifier_seq)), '(i10)', iostat=ios) modifier | |
| 440 | + else | |
| 441 | + ios = -1 | |
| 442 | + end if | |
| 496 | 443 | |
| 497 | - ! Append the key type using the terminator character | |
| 498 | - select case(terminator) | |
| 499 | - case('A') | |
| 500 | - key_str = trim(key_str) // 'up' | |
| 501 | - case('B') | |
| 502 | - key_str = trim(key_str) // 'down' | |
| 503 | - case('C') | |
| 504 | - key_str = trim(key_str) // 'right' | |
| 505 | - case('D') | |
| 506 | - key_str = trim(key_str) // 'left' | |
| 507 | - case('H') | |
| 508 | - key_str = trim(key_str) // 'home' | |
| 509 | - case('F') | |
| 510 | - key_str = trim(key_str) // 'end' | |
| 511 | - case('Z') | |
| 512 | - ! Shift+Z could be ctrl-shift-z for redo | |
| 513 | - if (index(key_str, 'ctrl-shift') == 1) then | |
| 514 | - key_str = 'ctrl-shift-z' | |
| 515 | - else | |
| 516 | - key_str = trim(key_str) // 'Z' | |
| 517 | - end if | |
| 518 | - case('~') | |
| 519 | - ! Check what special key it is based on the beginning of modifier_seq | |
| 520 | - if (index(modifier_seq, ';') == 1 .and. len_trim(modifier_seq) > 1) then | |
| 521 | - ! Already read the ;2 or ;5 etc, the key type should be before | |
| 522 | - key_str = trim(key_str) // 'unknown' | |
| 523 | - end if | |
| 524 | - end select | |
| 525 | - end if | |
| 444 | + if (ios == 0) then | |
| 445 | + select case(modifier) | |
| 446 | + case(2) ! Shift | |
| 447 | + key_str = 'shift-' | |
| 448 | + case(3) ! Alt | |
| 449 | + key_str = 'alt-' | |
| 450 | + case(4) ! Alt+Shift | |
| 451 | + key_str = 'alt-shift-' | |
| 452 | + case(5) ! Ctrl | |
| 453 | + key_str = 'ctrl-' | |
| 454 | + case(6) ! Ctrl+Shift | |
| 455 | + key_str = 'ctrl-shift-' | |
| 456 | + case(7) ! Alt+Ctrl | |
| 457 | + key_str = 'alt-ctrl-' | |
| 458 | + case(8) ! Alt+Shift (or Option+Shift) | |
| 459 | + key_str = 'alt-shift-' | |
| 460 | + case(9) ! Alt+Cmd (or Option+Cmd on macOS) | |
| 461 | + key_str = 'opt-meta-' | |
| 462 | + case default | |
| 463 | + key_str = '' | |
| 464 | + end select | |
| 465 | + | |
| 466 | + ! Append the key type using the terminator character | |
| 467 | + select case(terminator) | |
| 468 | + case('A') | |
| 469 | + key_str = trim(key_str) // 'up' | |
| 470 | + case('B') | |
| 471 | + key_str = trim(key_str) // 'down' | |
| 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 | 494 | end if |
| 527 | 495 | end subroutine handle_modified_key |
| 528 | 496 | |
src/ui/help_display_module.f90modified@@ -114,7 +114,7 @@ contains | ||
| 114 | 114 | n_lines = n_lines + 7 + 2 ! PANES |
| 115 | 115 | n_lines = n_lines + 10 + 2 ! GIT |
| 116 | 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 | 119 | allocate(lines(n_lines)) |
| 120 | 120 | i = 1 |
@@ -244,14 +244,14 @@ contains | ||
| 244 | 244 | ! LSP (Language Server Protocol) |
| 245 | 245 | lines(i) = "LSP (Language Server Protocol)"; i = i + 1 |
| 246 | 246 | lines(i) = " ctrl-space code completion"; i = i + 1 |
| 247 | - lines(i) = " ctrl-h hover information"; i = i + 1 | |
| 248 | - lines(i) = " F12 go to definition"; i = i + 1 | |
| 249 | - lines(i) = " shift-F12 find all references"; i = i + 1 | |
| 247 | + lines(i) = " F12/alt-g go to definition"; i = i + 1 | |
| 248 | + lines(i) = " shift-F12/alt-r find all references"; i = i + 1 | |
| 250 | 249 | lines(i) = " alt-, (alt-comma) jump back (navigation history)"; i = i + 1 |
| 251 | 250 | lines(i) = " F2 rename symbol"; i = i + 1 |
| 252 | - lines(i) = " F4 document symbols (outline)"; i = i + 1 | |
| 253 | - lines(i) = " F6 workspace symbols (search project)"; i = i + 1 | |
| 254 | - lines(i) = " F8 toggle diagnostics panel (errors)"; i = i + 1 | |
| 251 | + lines(i) = " F10/alt-. code actions (quick fixes)"; i = i + 1 | |
| 252 | + lines(i) = " F4/alt-o document symbols (outline)"; 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 | 255 | lines(i) = " ctrl-p command palette"; i = i + 1 |
| 256 | 256 | lines(i) = ""; i = i + 1 |
| 257 | 257 | |
src/ui/rename_prompt_module.f90modified@@ -23,18 +23,6 @@ contains | ||
| 23 | 23 | ! Show the text prompt |
| 24 | 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 | 26 | if (.not. cancelled) then |
| 39 | 27 | if (len_trim(input_text) > 0 .and. trim(input_text) /= trim(old_name)) then |
| 40 | 28 | allocate(character(len=len_trim(input_text)) :: new_name) |
@@ -43,19 +31,6 @@ contains | ||
| 43 | 31 | cancelled = .true. |
| 44 | 32 | end if |
| 45 | 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 | 34 | end subroutine show_rename_prompt |
| 60 | 35 | |
| 61 | 36 | end module rename_prompt_module |
src/workspace/workspace_module.f90modified@@ -231,25 +231,9 @@ contains | ||
| 231 | 231 | success = .false. |
| 232 | 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 | 234 | ! Open file for writing |
| 248 | 235 | open(newunit=unit, file=workspace_file, status='replace', iostat=ios) |
| 249 | - if (ios /= 0) then | |
| 250 | - write(0, '(A,I0)') '[DEBUG SAVE] ERROR: Failed to open file, ios=', ios | |
| 251 | - return | |
| 252 | - end if | |
| 236 | + if (ios /= 0) return | |
| 253 | 237 | |
| 254 | 238 | ! Get current timestamp (simplified) |
| 255 | 239 | call date_and_time(timestamp) |
@@ -263,7 +247,6 @@ contains | ||
| 263 | 247 | |
| 264 | 248 | ! Write tabs |
| 265 | 249 | if (allocated(editor%tabs)) then |
| 266 | - write(0, '(A,I0)') '[DEBUG SAVE] Writing ', size(editor%tabs), ' tabs' | |
| 267 | 250 | ws_len = len_trim(dir_path) |
| 268 | 251 | do i = 1, size(editor%tabs) |
| 269 | 252 | ! Write tab start - must be on its own line for parser |
@@ -426,33 +409,18 @@ contains | ||
| 426 | 409 | logical :: file_exists |
| 427 | 410 | integer :: load_status, tab_idx, pane_count, file_unit |
| 428 | 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 | 413 | success = .false. |
| 436 | 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 | 416 | ! Open workspace file |
| 441 | 417 | open(newunit=unit, file=workspace_file, status='old', iostat=ios) |
| 442 | 418 | if (ios /= 0) then |
| 443 | - ! Workspace file doesn't exist or can't be read (Phase 7: error handling) | |
| 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 | |
| 419 | + ! Workspace file doesn't exist or can't be read - initialize new workspace | |
| 450 | 420 | call workspace_init(dir_path, success) |
| 451 | 421 | return |
| 452 | 422 | end if |
| 453 | 423 | |
| 454 | - write(0, '(A)') '[DEBUG RESTORE WS] Workspace file opened successfully' | |
| 455 | - | |
| 456 | 424 | ! Parse JSON line by line (simple parser for our specific format) |
| 457 | 425 | in_tabs_array = .false. |
| 458 | 426 | reading_tab = .false. |
@@ -601,28 +569,19 @@ contains | ||
| 601 | 569 | end if |
| 602 | 570 | |
| 603 | 571 | if (.not. file_exists) then |
| 604 | - ! File doesn't exist - show warning and skip this tab | |
| 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 | |
| 572 | + ! File doesn't exist - skip this tab silently | |
| 610 | 573 | reading_pane = .false. |
| 611 | 574 | cycle |
| 612 | 575 | end if |
| 613 | 576 | |
| 614 | 577 | ! Create tab |
| 615 | - write(0, '(A)') '[DEBUG RESTORE WS] Creating tab for file: ' // trim(full_path) | |
| 616 | 578 | call create_tab(editor, trim(full_path)) |
| 617 | 579 | tab_idx = editor%active_tab_index |
| 618 | 580 | |
| 619 | 581 | ! Set orphan flag and load file |
| 620 | 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 | 583 | editor%tabs(tab_idx)%is_orphan = is_orphan |
| 623 | - | |
| 624 | 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 | 586 | ! Send LSP didOpen notification for restored tabs |
| 628 | 587 | if (load_status == 0 .and. editor%tabs(tab_idx)%num_lsp_servers > 0) then |
@@ -799,11 +758,8 @@ contains | ||
| 799 | 758 | |
| 800 | 759 | close(unit) |
| 801 | 760 | |
| 802 | - write(0, '(A)') '[DEBUG RESTORE WS] Finished parsing JSON' | |
| 803 | - | |
| 804 | 761 | ! Clamp active_tab_index to valid range |
| 805 | 762 | if (allocated(editor%tabs)) then |
| 806 | - write(0, '(A,I0)') '[DEBUG RESTORE WS] Tabs allocated, count: ', size(editor%tabs) | |
| 807 | 763 | if (size(editor%tabs) > 0) then |
| 808 | 764 | if (editor%active_tab_index > size(editor%tabs)) then |
| 809 | 765 | editor%active_tab_index = size(editor%tabs) |
@@ -812,16 +768,12 @@ contains | ||
| 812 | 768 | editor%active_tab_index = 1 |
| 813 | 769 | end if |
| 814 | 770 | else |
| 815 | - write(0, '(A)') '[DEBUG RESTORE WS] No tabs in array!' | |
| 816 | 771 | editor%active_tab_index = 0 ! No tabs |
| 817 | 772 | end if |
| 818 | 773 | else |
| 819 | - write(0, '(A)') '[DEBUG RESTORE WS] Tabs NOT allocated!' | |
| 820 | 774 | editor%active_tab_index = 0 ! No tabs |
| 821 | 775 | end if |
| 822 | 776 | |
| 823 | - write(0, '(A,I0)') '[DEBUG RESTORE WS] Final active_tab_index: ', editor%active_tab_index | |
| 824 | - | |
| 825 | 777 | ! Sync the active pane to editor state so status bar shows correct filename |
| 826 | 778 | if (allocated(editor%tabs) .and. editor%active_tab_index > 0) then |
| 827 | 779 | if (editor%active_tab_index <= size(editor%tabs)) then |
@@ -829,7 +781,6 @@ contains | ||
| 829 | 781 | if (editor%tabs(editor%active_tab_index)%active_pane_index > 0 .and. & |
| 830 | 782 | editor%tabs(editor%active_tab_index)%active_pane_index <= & |
| 831 | 783 | size(editor%tabs(editor%active_tab_index)%panes)) then |
| 832 | - write(0, '(A)') '[DEBUG RESTORE WS] Syncing active pane to editor' | |
| 833 | 784 | call sync_pane_to_editor(editor, editor%active_tab_index, & |
| 834 | 785 | editor%tabs(editor%active_tab_index)%active_pane_index) |
| 835 | 786 | end if |
@@ -838,7 +789,6 @@ contains | ||
| 838 | 789 | end if |
| 839 | 790 | |
| 840 | 791 | success = .true. |
| 841 | - write(0, '(A)') '[DEBUG RESTORE WS] workspace_restore_state completed successfully' | |
| 842 | 792 | end subroutine workspace_restore_state |
| 843 | 793 | |
| 844 | 794 | !> Track workspace in recents (helper function) |
tests/scratch_files/calculator.pymodified@@ -11,6 +11,7 @@ Test these features: | ||
| 11 | 11 | - Formatting: Shift+Alt+F to format |
| 12 | 12 | """ |
| 13 | 13 | |
| 14 | + | |
| 14 | 15 | def add(x, y): |
| 15 | 16 | """Add two numbers together.""" |
| 16 | 17 | return x + y |
tests/scratch_files/long_errors.pymodified@@ -1,6 +1,6 @@ | ||
| 1 | 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 | 5 | # Type mismatch with long type names |
| 6 | 6 | def process_data( |