@@ -27,7 +27,7 @@ module command_handler_module |
| 27 | 27 | request_references, request_code_actions, request_document_symbols, & |
| 28 | 28 | request_signature_help, request_formatting, request_rename, & |
| 29 | 29 | process_server_messages, filename_to_uri, & |
| 30 | | - get_server_with_capability, & |
| 30 | + get_server_with_capability, notify_file_opened, & |
| 31 | 31 | CAP_COMPLETION, CAP_DEFINITION, CAP_REFERENCES, CAP_RENAME, & |
| 32 | 32 | CAP_CODE_ACTIONS, CAP_FORMATTING, CAP_HOVER, CAP_DOCUMENT_SYMBOLS |
| 33 | 33 | use rename_prompt_module, only: show_rename_prompt |
@@ -188,13 +188,30 @@ contains |
| 188 | 188 | end if |
| 189 | 189 | end if |
| 190 | 190 | |
| 191 | | - ! Debug: log all incoming keys |
| 192 | | - block |
| 193 | | - integer :: dbg |
| 194 | | - open(newunit=dbg, file='/tmp/fac_keys_all.log', position='append', action='write') |
| 195 | | - write(dbg, '(A,A,A)') 'key_str = [', trim(key_str), ']' |
| 196 | | - close(dbg) |
| 197 | | - end block |
| 191 | + ! Route keys to code actions panel when visible |
| 192 | + if (is_code_actions_panel_visible(editor%code_actions_panel)) then |
| 193 | + if (code_actions_panel_handle_key(editor%code_actions_panel, trim(key_str))) then |
| 194 | + ! For Enter, we need to apply the code action here since panel just returns handled=true |
| 195 | + if (trim(key_str) == 'enter') then |
| 196 | + call apply_selected_code_action(editor, buffer) |
| 197 | + end if |
| 198 | + return |
| 199 | + end if |
| 200 | + end if |
| 201 | + |
| 202 | + ! Route keys to references panel when visible |
| 203 | + if (is_references_panel_visible(editor%references_panel)) then |
| 204 | + if (references_panel_handle_key(editor%references_panel, trim(key_str))) then |
| 205 | + return |
| 206 | + end if |
| 207 | + end if |
| 208 | + |
| 209 | + ! Route keys to symbols panel when visible |
| 210 | + if (is_symbols_panel_visible(editor%symbols_panel)) then |
| 211 | + if (symbols_panel_handle_key(editor%symbols_panel, trim(key_str))) then |
| 212 | + return |
| 213 | + end if |
| 214 | + end if |
| 198 | 215 | |
| 199 | 216 | select case(trim(key_str)) |
| 200 | 217 | ! File operations |
@@ -225,33 +242,7 @@ contains |
| 225 | 242 | return |
| 226 | 243 | end if |
| 227 | 244 | |
| 228 | | - ! If diagnostics panel is visible, hide it |
| 229 | | - if (is_diagnostics_panel_visible(editor%diagnostics_panel)) then |
| 230 | | - if (diagnostics_panel_handle_key(editor%diagnostics_panel, trim(key_str))) then |
| 231 | | - return |
| 232 | | - end if |
| 233 | | - end if |
| 234 | | - |
| 235 | | - ! If references panel is visible, hide it |
| 236 | | - if (is_references_panel_visible(editor%references_panel)) then |
| 237 | | - if (references_panel_handle_key(editor%references_panel, trim(key_str))) then |
| 238 | | - return |
| 239 | | - end if |
| 240 | | - end if |
| 241 | | - |
| 242 | | - ! If code actions menu is visible, hide it |
| 243 | | - if (is_code_actions_panel_visible(editor%code_actions_panel)) then |
| 244 | | - if (code_actions_panel_handle_key(editor%code_actions_panel, trim(key_str))) then |
| 245 | | - return |
| 246 | | - end if |
| 247 | | - end if |
| 248 | | - |
| 249 | | - ! If symbols panel is visible, hide it |
| 250 | | - if (is_symbols_panel_visible(editor%symbols_panel)) then |
| 251 | | - if (symbols_panel_handle_key(editor%symbols_panel, trim(key_str))) then |
| 252 | | - return |
| 253 | | - end if |
| 254 | | - end if |
| 245 | + ! Other panels (diagnostics, code_actions, references, symbols) are handled in early routing |
| 255 | 246 | |
| 256 | 247 | ! ESC - Clear selections and return to single cursor mode |
| 257 | 248 | if (size(editor%cursors) > 1) then |
@@ -357,33 +348,7 @@ contains |
| 357 | 348 | return |
| 358 | 349 | end if |
| 359 | 350 | |
| 360 | | - ! If diagnostics panel is visible, navigate it |
| 361 | | - if (is_diagnostics_panel_visible(editor%diagnostics_panel)) then |
| 362 | | - if (diagnostics_panel_handle_key(editor%diagnostics_panel, trim(key_str))) then |
| 363 | | - return |
| 364 | | - end if |
| 365 | | - end if |
| 366 | | - |
| 367 | | - ! If references panel is visible, navigate it |
| 368 | | - if (is_references_panel_visible(editor%references_panel)) then |
| 369 | | - if (references_panel_handle_key(editor%references_panel, trim(key_str))) then |
| 370 | | - return |
| 371 | | - end if |
| 372 | | - end if |
| 373 | | - |
| 374 | | - ! If code actions menu is visible, navigate it |
| 375 | | - if (is_code_actions_panel_visible(editor%code_actions_panel)) then |
| 376 | | - if (code_actions_panel_handle_key(editor%code_actions_panel, trim(key_str))) then |
| 377 | | - return |
| 378 | | - end if |
| 379 | | - end if |
| 380 | | - |
| 381 | | - ! If symbols panel is visible, navigate it |
| 382 | | - if (is_symbols_panel_visible(editor%symbols_panel)) then |
| 383 | | - if (symbols_panel_handle_key(editor%symbols_panel, trim(key_str))) then |
| 384 | | - return |
| 385 | | - end if |
| 386 | | - end if |
| 351 | + ! Other panels (diagnostics, code_actions, references, symbols) are handled in early routing |
| 387 | 352 | |
| 388 | 353 | if (size(editor%cursors) > 1) then |
| 389 | 354 | ! Move all cursors |
@@ -405,33 +370,7 @@ contains |
| 405 | 370 | return |
| 406 | 371 | end if |
| 407 | 372 | |
| 408 | | - ! If diagnostics panel is visible, navigate it |
| 409 | | - if (is_diagnostics_panel_visible(editor%diagnostics_panel)) then |
| 410 | | - if (diagnostics_panel_handle_key(editor%diagnostics_panel, trim(key_str))) then |
| 411 | | - return |
| 412 | | - end if |
| 413 | | - end if |
| 414 | | - |
| 415 | | - ! If references panel is visible, navigate it |
| 416 | | - if (is_references_panel_visible(editor%references_panel)) then |
| 417 | | - if (references_panel_handle_key(editor%references_panel, trim(key_str))) then |
| 418 | | - return |
| 419 | | - end if |
| 420 | | - end if |
| 421 | | - |
| 422 | | - ! If code actions menu is visible, navigate it |
| 423 | | - if (is_code_actions_panel_visible(editor%code_actions_panel)) then |
| 424 | | - if (code_actions_panel_handle_key(editor%code_actions_panel, trim(key_str))) then |
| 425 | | - return |
| 426 | | - end if |
| 427 | | - end if |
| 428 | | - |
| 429 | | - ! If symbols panel is visible, navigate it |
| 430 | | - if (is_symbols_panel_visible(editor%symbols_panel)) then |
| 431 | | - if (symbols_panel_handle_key(editor%symbols_panel, trim(key_str))) then |
| 432 | | - return |
| 433 | | - end if |
| 434 | | - end if |
| 373 | + ! Other panels (diagnostics, code_actions, references, symbols) are handled in early routing |
| 435 | 374 | |
| 436 | 375 | if (size(editor%cursors) > 1) then |
| 437 | 376 | ! Move all cursors |
@@ -743,71 +682,7 @@ contains |
| 743 | 682 | is_edit_action = .true. |
| 744 | 683 | |
| 745 | 684 | case('enter') |
| 746 | | - ! If code actions menu is visible, apply selected action |
| 747 | | - if (is_code_actions_panel_visible(editor%code_actions_panel)) then |
| 748 | | - block |
| 749 | | - use json_module, only: json_parse, json_value_t, json_get_object, & |
| 750 | | - json_has_key, json_stringify |
| 751 | | - character(len=:), allocatable :: action_json, edit_json |
| 752 | | - type(json_value_t) :: action_obj, edit_obj |
| 753 | | - integer :: changes_applied |
| 754 | | - |
| 755 | | - if (get_selected_action(editor%code_actions_panel, action_json)) then |
| 756 | | - ! Debug: log the action JSON |
| 757 | | - block |
| 758 | | - integer :: dbg |
| 759 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 760 | | - write(dbg, '(A)') '=== APPLYING CODE ACTION ===' |
| 761 | | - write(dbg, '(A)') 'action_json:' |
| 762 | | - write(dbg, '(A)') action_json(1:min(1000, len(action_json))) |
| 763 | | - close(dbg) |
| 764 | | - end block |
| 765 | | - |
| 766 | | - ! Parse the action JSON to extract the edit |
| 767 | | - action_obj = json_parse(action_json) |
| 768 | | - |
| 769 | | - if (json_has_key(action_obj, 'edit')) then |
| 770 | | - ! Get the edit object and convert to string for apply_workspace_edit |
| 771 | | - edit_obj = json_get_object(action_obj, 'edit') |
| 772 | | - edit_json = json_stringify(edit_obj) |
| 773 | | - |
| 774 | | - ! Debug: log the edit JSON |
| 775 | | - block |
| 776 | | - integer :: dbg |
| 777 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 778 | | - write(dbg, '(A)') 'edit_json:' |
| 779 | | - write(dbg, '(A)') edit_json(1:min(1000, len(edit_json))) |
| 780 | | - close(dbg) |
| 781 | | - end block |
| 782 | | - |
| 783 | | - ! Apply the workspace edit |
| 784 | | - call apply_workspace_edit(editor, edit_json, changes_applied) |
| 785 | | - |
| 786 | | - if (changes_applied > 0) then |
| 787 | | - ! Sync modified tab buffer back to the buffer parameter |
| 788 | | - if (editor%active_tab_index > 0 .and. & |
| 789 | | - editor%active_tab_index <= size(editor%tabs)) then |
| 790 | | - call copy_buffer(buffer, editor%tabs(editor%active_tab_index)%buffer) |
| 791 | | - end if |
| 792 | | - ! Re-render screen to show the applied changes |
| 793 | | - call render_screen(buffer, editor) |
| 794 | | - call terminal_move_cursor(editor%screen_rows, 1) |
| 795 | | - call terminal_write('Code action applied ') |
| 796 | | - else |
| 797 | | - call terminal_move_cursor(editor%screen_rows, 1) |
| 798 | | - call terminal_write('No changes from code action ') |
| 799 | | - end if |
| 800 | | - else |
| 801 | | - call terminal_move_cursor(editor%screen_rows, 1) |
| 802 | | - call terminal_write('Code action has no edit ') |
| 803 | | - end if |
| 804 | | - |
| 805 | | - ! Hide menu after selection |
| 806 | | - call hide_code_actions_panel(editor%code_actions_panel) |
| 807 | | - end if |
| 808 | | - end block |
| 809 | | - return |
| 810 | | - end if |
| 685 | + ! Code actions panel is handled in early routing above |
| 811 | 686 | |
| 812 | 687 | ! If symbols panel is visible, jump to selected symbol |
| 813 | 688 | if (is_symbols_panel_visible(editor%symbols_panel)) then |
@@ -1269,13 +1144,6 @@ contains |
| 1269 | 1144 | |
| 1270 | 1145 | case('f10', 'alt-.') |
| 1271 | 1146 | ! Trigger code actions (F10 or Alt+.) - toggle behavior |
| 1272 | | - block |
| 1273 | | - integer :: dbg |
| 1274 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 1275 | | - write(dbg, '(A)') '=== F10/ALT-. KEY DETECTED ===' |
| 1276 | | - write(dbg, '(A,L1)') 'panel visible = ', is_code_actions_panel_visible(editor%code_actions_panel) |
| 1277 | | - close(dbg) |
| 1278 | | - end block |
| 1279 | 1147 | ! If panel is already visible, close it |
| 1280 | 1148 | if (is_code_actions_panel_visible(editor%code_actions_panel)) then |
| 1281 | 1149 | call hide_code_actions_panel(editor%code_actions_panel) |
@@ -1286,7 +1154,7 @@ contains |
| 1286 | 1154 | if (code_actions_server > 0) then |
| 1287 | 1155 | ! Request code actions for the current line |
| 1288 | 1156 | block |
| 1289 | | - integer :: request_id, lsp_line, dbg, dbg_i |
| 1157 | + integer :: request_id, lsp_line |
| 1290 | 1158 | character(len=:), allocatable :: file_uri |
| 1291 | 1159 | type(diagnostic_t), allocatable :: line_diags(:) |
| 1292 | 1160 | type(json_value_t) :: diags_json |
@@ -1300,58 +1168,12 @@ contains |
| 1300 | 1168 | ! This is critical for multi-LSP: Ruff should only see Ruff's diagnostics |
| 1301 | 1169 | file_uri = filename_to_uri(editor%tabs(editor%active_tab_index)%filename) |
| 1302 | 1170 | |
| 1303 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 1304 | | - write(dbg, '(A,A)') 'file_uri = ', trim(file_uri) |
| 1305 | | - write(dbg, '(A,I0)') 'cursor line (1-based) = ', editor%cursors(editor%active_cursor)%line |
| 1306 | | - write(dbg, '(A,I0)') 'lsp_line (0-based) = ', lsp_line |
| 1307 | | - write(dbg, '(A,I0)') 'code_actions_server = ', code_actions_server |
| 1308 | | - close(dbg) |
| 1309 | | - |
| 1310 | 1171 | line_diags = get_diagnostics_for_line_by_server(editor%diagnostics, file_uri, & |
| 1311 | 1172 | editor%cursors(editor%active_cursor)%line, code_actions_server) |
| 1312 | 1173 | |
| 1313 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 1314 | | - write(dbg, '(A,I0)') 'Found diagnostics on line: ', size(line_diags) |
| 1315 | | - close(dbg) |
| 1316 | | - |
| 1317 | | - ! Debug: check each diagnostic before calling diagnostics_to_json |
| 1318 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 1319 | | - write(dbg, '(A)') 'About to check diagnostics...' |
| 1320 | | - do dbg_i = 1, size(line_diags) |
| 1321 | | - write(dbg, '(A,I0)') 'Checking diagnostic ', dbg_i |
| 1322 | | - write(dbg, '(A,L1)') ' message allocated: ', allocated(line_diags(dbg_i)%message) |
| 1323 | | - write(dbg, '(A,L1)') ' source allocated: ', allocated(line_diags(dbg_i)%source) |
| 1324 | | - write(dbg, '(A,L1)') ' code allocated: ', allocated(line_diags(dbg_i)%code) |
| 1325 | | - write(dbg, '(A,L1)') ' data allocated: ', allocated(line_diags(dbg_i)%data) |
| 1326 | | - if (allocated(line_diags(dbg_i)%message)) then |
| 1327 | | - write(dbg, '(A,I0)') ' message len: ', len(line_diags(dbg_i)%message) |
| 1328 | | - end if |
| 1329 | | - end do |
| 1330 | | - write(dbg, '(A)') 'Diagnostics check complete' |
| 1331 | | - close(dbg) |
| 1332 | | - |
| 1333 | 1174 | ! Convert diagnostics to JSON for request |
| 1334 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 1335 | | - write(dbg, '(A)') 'Calling diagnostics_to_json...' |
| 1336 | | - close(dbg) |
| 1337 | | - |
| 1338 | 1175 | diags_json = diagnostics_to_json(line_diags) |
| 1339 | 1176 | |
| 1340 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 1341 | | - write(dbg, '(A)') 'diagnostics_to_json returned' |
| 1342 | | - close(dbg) |
| 1343 | | - |
| 1344 | | - ! Debug: log the diagnostics JSON |
| 1345 | | - block |
| 1346 | | - use json_module, only: json_stringify |
| 1347 | | - character(len=:), allocatable :: diags_str |
| 1348 | | - diags_str = json_stringify(diags_json) |
| 1349 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 1350 | | - write(dbg, '(A)') 'Diagnostics JSON being sent:' |
| 1351 | | - write(dbg, '(A)') diags_str |
| 1352 | | - close(dbg) |
| 1353 | | - end block |
| 1354 | | - |
| 1355 | 1177 | ! Request code actions for entire line with diagnostics context |
| 1356 | 1178 | request_id = request_code_actions(editor%lsp_manager, & |
| 1357 | 1179 | code_actions_server, & |
@@ -1360,10 +1182,6 @@ contains |
| 1360 | 1182 | lsp_line, 999, & |
| 1361 | 1183 | handle_code_actions_response_wrapper, & |
| 1362 | 1184 | diags_json) |
| 1363 | | - |
| 1364 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 1365 | | - write(dbg, '(A,I0)') 'request_id = ', request_id |
| 1366 | | - close(dbg) |
| 1367 | 1185 | ! Panel will be shown when response arrives in handle_code_actions_response_impl |
| 1368 | 1186 | end block |
| 1369 | 1187 | end if |
@@ -1372,14 +1190,6 @@ contains |
| 1372 | 1190 | |
| 1373 | 1191 | case('f12', 'ctrl-\\', 'alt-g') |
| 1374 | 1192 | ! Go to definition (F12, Ctrl+\, or Alt+G) |
| 1375 | | - block |
| 1376 | | - integer :: debug_unit, def_server |
| 1377 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 1378 | | - write(debug_unit, '(A)') '>>> INSIDE F12/ALT-G HANDLER <<<' |
| 1379 | | - write(debug_unit, '(A,I0)') 'active_tab_index = ', editor%active_tab_index |
| 1380 | | - write(debug_unit, '(A,I0)') 'size(tabs) = ', size(editor%tabs) |
| 1381 | | - close(debug_unit) |
| 1382 | | - end block |
| 1383 | 1193 | call terminal_move_cursor(editor%screen_rows, 1) |
| 1384 | 1194 | block |
| 1385 | 1195 | integer :: def_server |
@@ -1408,13 +1218,6 @@ contains |
| 1408 | 1218 | editor%tabs(editor%active_tab_index)%filename, & |
| 1409 | 1219 | lsp_line, lsp_char, handle_definition_response_wrapper) |
| 1410 | 1220 | |
| 1411 | | - block |
| 1412 | | - integer :: debug_unit |
| 1413 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 1414 | | - write(debug_unit, '(A,I0)') 'request_definition returned request_id = ', request_id |
| 1415 | | - close(debug_unit) |
| 1416 | | - end block |
| 1417 | | - |
| 1418 | 1221 | if (request_id > 0) then |
| 1419 | 1222 | ! Response will be handled by callback |
| 1420 | 1223 | call terminal_write('Searching for definition... ') |
@@ -1429,12 +1232,6 @@ contains |
| 1429 | 1232 | |
| 1430 | 1233 | case('shift-f12', 'alt-r') |
| 1431 | 1234 | ! Find all references (Shift+F12 or Alt+R) |
| 1432 | | - block |
| 1433 | | - integer :: debug_unit |
| 1434 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 1435 | | - write(debug_unit, '(A)') '>>> INSIDE SHIFT-F12/ALT-R HANDLER <<<' |
| 1436 | | - close(debug_unit) |
| 1437 | | - end block |
| 1438 | 1235 | block |
| 1439 | 1236 | integer :: refs_server |
| 1440 | 1237 | refs_server = get_lsp_server_for_cap(editor, CAP_REFERENCES) |
@@ -1540,13 +1337,6 @@ contains |
| 1540 | 1337 | |
| 1541 | 1338 | case('f2') |
| 1542 | 1339 | ! Rename symbol |
| 1543 | | - block |
| 1544 | | - integer :: debug_unit |
| 1545 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 1546 | | - write(debug_unit, '(A)') '>>> F2 KEY DETECTED <<<' |
| 1547 | | - write(debug_unit, '(A,I0)') 'active_tab_index: ', editor%active_tab_index |
| 1548 | | - close(debug_unit) |
| 1549 | | - end block |
| 1550 | 1340 | block |
| 1551 | 1341 | integer :: rename_server |
| 1552 | 1342 | rename_server = get_lsp_server_for_cap(editor, CAP_RENAME) |
@@ -1572,17 +1362,6 @@ contains |
| 1572 | 1362 | lsp_line = editor%cursors(editor%active_cursor)%line - 1 |
| 1573 | 1363 | lsp_char = editor%cursors(editor%active_cursor)%column - 1 |
| 1574 | 1364 | |
| 1575 | | - ! Debug logging |
| 1576 | | - block |
| 1577 | | - integer :: debug_unit |
| 1578 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 1579 | | - write(debug_unit, '(A)') '>>> SENDING RENAME REQUEST <<<' |
| 1580 | | - write(debug_unit, '(A)') 'Old name: ' // trim(old_name) |
| 1581 | | - write(debug_unit, '(A)') 'New name: ' // trim(new_name) |
| 1582 | | - write(debug_unit, '(A,I0,A,I0)') 'Position: line=', lsp_line, ' char=', lsp_char |
| 1583 | | - close(debug_unit) |
| 1584 | | - end block |
| 1585 | | - |
| 1586 | 1365 | ! Save editor state for callback |
| 1587 | 1366 | saved_editor_for_callback => editor |
| 1588 | 1367 | |
@@ -1597,26 +1376,16 @@ contains |
| 1597 | 1376 | |
| 1598 | 1377 | ! Poll for LSP response and render immediately when received |
| 1599 | 1378 | block |
| 1600 | | - integer :: poll_count, max_polls, pane_idx, debug_unit |
| 1379 | + integer :: poll_count, max_polls, pane_idx |
| 1601 | 1380 | integer(8) :: start_time, end_time, count_rate, target_time |
| 1602 | 1381 | max_polls = 100 ! Poll up to 100 times (1 second total) |
| 1603 | 1382 | |
| 1604 | | - ! Debug: Start polling |
| 1605 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 1606 | | - write(debug_unit, '(A)') '>>> STARTING RENAME POLLING <<<' |
| 1607 | | - close(debug_unit) |
| 1608 | | - |
| 1609 | 1383 | do poll_count = 1, max_polls |
| 1610 | 1384 | ! Process any LSP messages |
| 1611 | 1385 | call process_server_messages(editor%lsp_manager) |
| 1612 | 1386 | |
| 1613 | 1387 | ! Check if rename response modified the buffer |
| 1614 | 1388 | if (g_lsp_modified_buffer) then |
| 1615 | | - ! Debug: Flag detected! |
| 1616 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 1617 | | - write(debug_unit, '(A,I0,A)') '>>> FLAG DETECTED at poll ', poll_count, ' - RENDERING NOW <<<' |
| 1618 | | - close(debug_unit) |
| 1619 | | - |
| 1620 | 1389 | ! Sync buffer from tab (LSP modified tab buffer) |
| 1621 | 1390 | call copy_buffer(buffer, editor%tabs(editor%active_tab_index)%buffer) |
| 1622 | 1391 | |
@@ -1649,13 +1418,6 @@ contains |
| 1649 | 1418 | if (end_time >= target_time) exit |
| 1650 | 1419 | end do |
| 1651 | 1420 | end do |
| 1652 | | - |
| 1653 | | - ! Debug: Polling finished without detecting flag |
| 1654 | | - if (.not. g_lsp_modified_buffer) then |
| 1655 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 1656 | | - write(debug_unit, '(A)') '>>> POLLING TIMEOUT - FLAG NEVER SET <<<' |
| 1657 | | - close(debug_unit) |
| 1658 | | - end if |
| 1659 | 1421 | end block |
| 1660 | 1422 | end if |
| 1661 | 1423 | |
@@ -1704,12 +1466,6 @@ contains |
| 1704 | 1466 | |
| 1705 | 1467 | case('f4', 'alt-o') |
| 1706 | 1468 | ! Document symbols outline (F4 or Alt+O) |
| 1707 | | - block |
| 1708 | | - integer :: debug_unit |
| 1709 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 1710 | | - write(debug_unit, '(A)') '>>> INSIDE F4/ALT-O HANDLER <<<' |
| 1711 | | - close(debug_unit) |
| 1712 | | - end block |
| 1713 | 1469 | block |
| 1714 | 1470 | integer :: symbols_server |
| 1715 | 1471 | symbols_server = get_lsp_server_for_cap(editor, CAP_DOCUMENT_SYMBOLS) |
@@ -1900,29 +1656,9 @@ contains |
| 1900 | 1656 | |
| 1901 | 1657 | case('f8', 'alt-e') |
| 1902 | 1658 | ! Toggle diagnostics panel (F8 or Alt+E for errors) |
| 1903 | | - block |
| 1904 | | - integer :: debug_unit |
| 1905 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 1906 | | - write(debug_unit, '(A)') '>>> INSIDE F8/ALT-E HANDLER <<<' |
| 1907 | | - write(debug_unit, '(A)') 'Calling toggle_diagnostics_panel...' |
| 1908 | | - close(debug_unit) |
| 1909 | | - end block |
| 1910 | 1659 | call toggle_panel(editor%diagnostics_panel) |
| 1911 | | - block |
| 1912 | | - integer :: debug_unit |
| 1913 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 1914 | | - write(debug_unit, '(A)') 'toggle_diagnostics_panel returned' |
| 1915 | | - write(debug_unit, '(A)') '>>> ABOUT TO CALL render_screen <<<' |
| 1916 | | - close(debug_unit) |
| 1917 | | - end block |
| 1918 | 1660 | ! Re-render screen to show/hide the panel |
| 1919 | 1661 | call render_screen(buffer, editor) |
| 1920 | | - block |
| 1921 | | - integer :: debug_unit |
| 1922 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 1923 | | - write(debug_unit, '(A)') '>>> render_screen COMPLETED <<<' |
| 1924 | | - close(debug_unit) |
| 1925 | | - end block |
| 1926 | 1662 | |
| 1927 | 1663 | case('alt-c') |
| 1928 | 1664 | ! Toggle case sensitivity for match mode (ctrl-d) |
@@ -1999,12 +1735,6 @@ contains |
| 1999 | 1735 | end if |
| 2000 | 1736 | |
| 2001 | 1737 | case default |
| 2002 | | - ! DEBUG: Show unhandled function keys |
| 2003 | | - if (index(key_str, 'f') == 1 .or. index(key_str, 'shift-f') == 1) then |
| 2004 | | - call terminal_move_cursor(editor%screen_rows, 1) |
| 2005 | | - call terminal_write('[DEBUG] Unhandled key: ' // trim(key_str) // ' ') |
| 2006 | | - end if |
| 2007 | | - |
| 2008 | 1738 | ! Check for mouse events |
| 2009 | 1739 | if (index(key_str, 'mouse-') == 1) then |
| 2010 | 1740 | call handle_mouse_event_action(key_str, editor, buffer) |
@@ -5238,6 +4968,18 @@ contains |
| 5238 | 4968 | allocate(character(len=len_trim(full_path)) :: editor%filename) |
| 5239 | 4969 | editor%filename = full_path |
| 5240 | 4970 | |
| 4971 | + ! Send LSP didOpen notification to ALL active servers |
| 4972 | + if (editor%tabs(editor%active_tab_index)%num_lsp_servers > 0) then |
| 4973 | + block |
| 4974 | + integer :: srv_i |
| 4975 | + do srv_i = 1, editor%tabs(editor%active_tab_index)%num_lsp_servers |
| 4976 | + call notify_file_opened(editor%lsp_manager, & |
| 4977 | + editor%tabs(editor%active_tab_index)%lsp_server_indices(srv_i), & |
| 4978 | + full_path, buffer_to_string(editor%tabs(editor%active_tab_index)%buffer)) |
| 4979 | + end do |
| 4980 | + end block |
| 4981 | + end if |
| 4982 | + |
| 5241 | 4983 | ! Reset cursor to top of file |
| 5242 | 4984 | editor%cursors(editor%active_cursor)%line = 1 |
| 5243 | 4985 | editor%cursors(editor%active_cursor)%column = 1 |
@@ -5989,13 +5731,6 @@ contains |
| 5989 | 5731 | integer, intent(in) :: request_id |
| 5990 | 5732 | type(lsp_message_t), intent(in) :: response |
| 5991 | 5733 | |
| 5992 | | - block |
| 5993 | | - integer :: debug_unit |
| 5994 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 5995 | | - write(debug_unit, '(A)') '>>> REFERENCES RESPONSE RECEIVED <<<' |
| 5996 | | - close(debug_unit) |
| 5997 | | - end block |
| 5998 | | - |
| 5999 | 5734 | ! Call the actual handler with saved editor state |
| 6000 | 5735 | if (associated(saved_editor_for_callback)) then |
| 6001 | 5736 | call handle_references_response_impl(saved_editor_for_callback, response) |
@@ -6122,27 +5857,14 @@ contains |
| 6122 | 5857 | type(lsp_message_t), intent(in) :: response |
| 6123 | 5858 | type(json_value_t) :: result_array, action_obj, edit_obj |
| 6124 | 5859 | type(code_action_t), allocatable :: actions(:) |
| 6125 | | - integer :: num_actions, i, dbg |
| 6126 | | - character(len=:), allocatable :: title, kind, action_json, result_str |
| 5860 | + integer :: num_actions, i |
| 5861 | + character(len=:), allocatable :: title, kind, action_json |
| 6127 | 5862 | logical :: is_preferred |
| 6128 | 5863 | |
| 6129 | | - ! Debug: Log that callback was invoked |
| 6130 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 6131 | | - write(dbg, '(A)') '=== CODE ACTIONS RESPONSE RECEIVED ===' |
| 6132 | | - write(dbg, '(A,I0)') 'response%id = ', response%id |
| 6133 | | - result_str = json_stringify(response%result) |
| 6134 | | - write(dbg, '(A)') 'response%result (first 500 chars):' |
| 6135 | | - write(dbg, '(A)') result_str(1:min(500, len(result_str))) |
| 6136 | | - close(dbg) |
| 6137 | | - |
| 6138 | 5864 | ! The result is directly in response%result for LSP responses |
| 6139 | 5865 | result_array = response%result |
| 6140 | 5866 | num_actions = json_array_size(result_array) |
| 6141 | 5867 | |
| 6142 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 6143 | | - write(dbg, '(A,I0)') 'num_actions from json_array_size = ', num_actions |
| 6144 | | - close(dbg) |
| 6145 | | - |
| 6146 | 5868 | if (num_actions == 0) then |
| 6147 | 5869 | ! No actions available - don't show panel |
| 6148 | 5870 | return |
@@ -6206,13 +5928,6 @@ contains |
| 6206 | 5928 | integer, intent(in) :: request_id |
| 6207 | 5929 | type(lsp_message_t), intent(in) :: response |
| 6208 | 5930 | |
| 6209 | | - block |
| 6210 | | - integer :: debug_unit |
| 6211 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 6212 | | - write(debug_unit, '(A)') '>>> SYMBOLS RESPONSE RECEIVED <<<' |
| 6213 | | - close(debug_unit) |
| 6214 | | - end block |
| 6215 | | - |
| 6216 | 5931 | ! Call the actual handler with saved editor state |
| 6217 | 5932 | if (associated(saved_editor_for_callback)) then |
| 6218 | 5933 | call handle_symbols_response_impl(saved_editor_for_callback, response) |
@@ -6238,26 +5953,6 @@ contains |
| 6238 | 5953 | result_array = response%result |
| 6239 | 5954 | num_symbols = json_array_size(result_array) |
| 6240 | 5955 | |
| 6241 | | - block |
| 6242 | | - integer :: debug_unit |
| 6243 | | - character(len=:), allocatable :: result_str, error_str |
| 6244 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 6245 | | - write(debug_unit, '(A)') '>>> SYMBOLS RESPONSE RECEIVED <<<' |
| 6246 | | - |
| 6247 | | - ! Check for error |
| 6248 | | - if (json_has_key(response%error, "message")) then |
| 6249 | | - error_str = json_get_string(response%error, "message") |
| 6250 | | - write(debug_unit, '(A)') 'ERROR: ' // trim(error_str) |
| 6251 | | - end if |
| 6252 | | - |
| 6253 | | - write(debug_unit, '(A,I0)') 'num_symbols = ', num_symbols |
| 6254 | | - result_str = json_stringify(response%result) |
| 6255 | | - if (allocated(result_str)) then |
| 6256 | | - write(debug_unit, '(A)') 'Result JSON: ' // result_str(1:min(500,len(result_str))) |
| 6257 | | - end if |
| 6258 | | - close(debug_unit) |
| 6259 | | - end block |
| 6260 | | - |
| 6261 | 5956 | if (num_symbols == 0) then |
| 6262 | 5957 | call clear_symbols(editor%symbols_panel) |
| 6263 | 5958 | call terminal_move_cursor(editor%screen_rows, 1) |
@@ -6406,24 +6101,12 @@ contains |
| 6406 | 6101 | |
| 6407 | 6102 | character(len=:), allocatable :: result_str |
| 6408 | 6103 | integer :: changes_applied |
| 6409 | | - integer :: debug_unit |
| 6410 | 6104 | |
| 6411 | 6105 | if (.not. associated(saved_editor_for_callback)) return |
| 6412 | 6106 | |
| 6413 | 6107 | ! Convert result to string for apply_workspace_edit |
| 6414 | 6108 | result_str = json_stringify(response%result) |
| 6415 | 6109 | |
| 6416 | | - ! Debug logging |
| 6417 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 6418 | | - write(debug_unit, '(A)') '>>> RENAME RESPONSE <<<' |
| 6419 | | - if (allocated(result_str)) then |
| 6420 | | - write(debug_unit, '(A,I0)') 'Result length: ', len(result_str) |
| 6421 | | - write(debug_unit, '(A)') 'Result (first 500 chars): ' // result_str(1:min(500, len(result_str))) |
| 6422 | | - else |
| 6423 | | - write(debug_unit, '(A)') 'Result: NOT ALLOCATED' |
| 6424 | | - end if |
| 6425 | | - close(debug_unit) |
| 6426 | | - |
| 6427 | 6110 | if (.not. allocated(result_str) .or. result_str == 'null' .or. len_trim(result_str) == 0) then |
| 6428 | 6111 | call terminal_move_cursor(saved_editor_for_callback%screen_rows, 1) |
| 6429 | 6112 | call terminal_write('Rename failed or not supported ') |
@@ -6434,21 +6117,6 @@ contains |
| 6434 | 6117 | ! Apply workspace edit |
| 6435 | 6118 | call apply_workspace_edit(saved_editor_for_callback, result_str, changes_applied) |
| 6436 | 6119 | |
| 6437 | | - ! Debug: verify edits were applied |
| 6438 | | - if (changes_applied > 0) then |
| 6439 | | - block |
| 6440 | | - integer :: tab_idx, debug_unit |
| 6441 | | - tab_idx = saved_editor_for_callback%active_tab_index |
| 6442 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 6443 | | - write(debug_unit, '(A)') '>>> AFTER ALL EDITS APPLIED <<<' |
| 6444 | | - write(debug_unit, '(A,I0)') 'Active tab index: ', tab_idx |
| 6445 | | - write(debug_unit, '(A,I0)') 'Changes applied: ', changes_applied |
| 6446 | | - write(debug_unit, '(A,L1)') 'Buffer modified flag: ', saved_editor_for_callback%tabs(tab_idx)%buffer%modified |
| 6447 | | - write(debug_unit, '(A)') 'NOTE: Screen will be rendered by main loop' |
| 6448 | | - close(debug_unit) |
| 6449 | | - end block |
| 6450 | | - end if |
| 6451 | | - |
| 6452 | 6120 | call terminal_move_cursor(saved_editor_for_callback%screen_rows, 1) |
| 6453 | 6121 | if (changes_applied > 0) then |
| 6454 | 6122 | block |
@@ -6533,6 +6201,52 @@ contains |
| 6533 | 6201 | end if |
| 6534 | 6202 | end subroutine handle_formatting_response_wrapper |
| 6535 | 6203 | |
| 6204 | + ! Apply the selected code action from the panel |
| 6205 | + subroutine apply_selected_code_action(editor, buffer) |
| 6206 | + use json_module, only: json_parse, json_value_t, json_get_object, & |
| 6207 | + json_has_key, json_stringify |
| 6208 | + type(editor_state_t), intent(inout) :: editor |
| 6209 | + type(buffer_t), intent(inout) :: buffer |
| 6210 | + character(len=:), allocatable :: action_json, edit_json |
| 6211 | + type(json_value_t) :: action_obj, edit_obj |
| 6212 | + integer :: changes_applied |
| 6213 | + |
| 6214 | + if (get_selected_action(editor%code_actions_panel, action_json)) then |
| 6215 | + ! Parse the action JSON to extract the edit |
| 6216 | + action_obj = json_parse(action_json) |
| 6217 | + |
| 6218 | + if (json_has_key(action_obj, 'edit')) then |
| 6219 | + ! Get the edit object and convert to string for apply_workspace_edit |
| 6220 | + edit_obj = json_get_object(action_obj, 'edit') |
| 6221 | + edit_json = json_stringify(edit_obj) |
| 6222 | + |
| 6223 | + ! Apply the workspace edit |
| 6224 | + call apply_workspace_edit(editor, edit_json, changes_applied) |
| 6225 | + |
| 6226 | + if (changes_applied > 0) then |
| 6227 | + ! Sync modified tab buffer back to the buffer parameter |
| 6228 | + if (editor%active_tab_index > 0 .and. & |
| 6229 | + editor%active_tab_index <= size(editor%tabs)) then |
| 6230 | + call copy_buffer(buffer, editor%tabs(editor%active_tab_index)%buffer) |
| 6231 | + end if |
| 6232 | + ! Re-render screen to show the applied changes |
| 6233 | + call render_screen(buffer, editor) |
| 6234 | + call terminal_move_cursor(editor%screen_rows, 1) |
| 6235 | + call terminal_write('Code action applied ') |
| 6236 | + else |
| 6237 | + call terminal_move_cursor(editor%screen_rows, 1) |
| 6238 | + call terminal_write('No changes from code action ') |
| 6239 | + end if |
| 6240 | + else |
| 6241 | + call terminal_move_cursor(editor%screen_rows, 1) |
| 6242 | + call terminal_write('Code action has no edit ') |
| 6243 | + end if |
| 6244 | + |
| 6245 | + ! Hide menu after selection |
| 6246 | + call hide_code_actions_panel(editor%code_actions_panel) |
| 6247 | + end if |
| 6248 | + end subroutine apply_selected_code_action |
| 6249 | + |
| 6536 | 6250 | ! Apply a workspace edit from LSP |
| 6537 | 6251 | subroutine apply_workspace_edit(editor, edit_json, changes_applied) |
| 6538 | 6252 | use json_module, only: json_parse, json_value_t, json_get_array, json_array_size, & |
@@ -6549,15 +6263,6 @@ contains |
| 6549 | 6263 | |
| 6550 | 6264 | changes_applied = 0 |
| 6551 | 6265 | |
| 6552 | | - ! Debug logging |
| 6553 | | - block |
| 6554 | | - integer :: dbg |
| 6555 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 6556 | | - write(dbg, '(A)') '=== apply_workspace_edit called ===' |
| 6557 | | - write(dbg, '(A,I0)') 'edit_json length = ', len(edit_json) |
| 6558 | | - close(dbg) |
| 6559 | | - end block |
| 6560 | | - |
| 6561 | 6266 | ! Parse the edit JSON |
| 6562 | 6267 | edit_obj = json_parse(edit_json) |
| 6563 | 6268 | |
@@ -6566,13 +6271,6 @@ contains |
| 6566 | 6271 | doc_changes_arr = json_get_array(edit_obj, 'documentChanges') |
| 6567 | 6272 | num_files = json_array_size(doc_changes_arr) |
| 6568 | 6273 | |
| 6569 | | - block |
| 6570 | | - integer :: dbg |
| 6571 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 6572 | | - write(dbg, '(A,I0)') 'Found documentChanges, num_files = ', num_files |
| 6573 | | - close(dbg) |
| 6574 | | - end block |
| 6575 | | - |
| 6576 | 6274 | do i = 0, num_files - 1 ! 0-based index |
| 6577 | 6275 | file_change_obj = json_get_array_element(doc_changes_arr, i) |
| 6578 | 6276 | |
@@ -6580,33 +6278,11 @@ contains |
| 6580 | 6278 | if (json_has_key(file_change_obj, 'textDocument')) then |
| 6581 | 6279 | text_doc_obj = json_get_object(file_change_obj, 'textDocument') |
| 6582 | 6280 | uri = json_get_string(text_doc_obj, 'uri') |
| 6583 | | - |
| 6584 | | - block |
| 6585 | | - integer :: dbg |
| 6586 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 6587 | | - write(dbg, '(A,I0)') 'Processing file ', i |
| 6588 | | - if (allocated(uri)) then |
| 6589 | | - write(dbg, '(A,A)') 'uri = ', trim(uri) |
| 6590 | | - else |
| 6591 | | - write(dbg, '(A)') 'uri NOT allocated' |
| 6592 | | - end if |
| 6593 | | - write(dbg, '(A,L1)') 'has edits key = ', json_has_key(file_change_obj, 'edits') |
| 6594 | | - close(dbg) |
| 6595 | | - end block |
| 6596 | 6281 | end if |
| 6597 | 6282 | |
| 6598 | 6283 | ! Get edits array |
| 6599 | 6284 | if (json_has_key(file_change_obj, 'edits') .and. allocated(uri)) then |
| 6600 | 6285 | edits_arr = json_get_array(file_change_obj, 'edits') |
| 6601 | | - |
| 6602 | | - block |
| 6603 | | - integer :: dbg, num_edits |
| 6604 | | - num_edits = json_array_size(edits_arr) |
| 6605 | | - open(newunit=dbg, file='/tmp/fac_code_actions.log', position='append', action='write') |
| 6606 | | - write(dbg, '(A,I0)') 'num_edits = ', num_edits |
| 6607 | | - close(dbg) |
| 6608 | | - end block |
| 6609 | | - |
| 6610 | 6286 | call apply_file_edits_obj(editor, uri, edits_arr, changes_applied) |
| 6611 | 6287 | deallocate(uri) |
| 6612 | 6288 | end if |
@@ -6656,38 +6332,10 @@ contains |
| 6656 | 6332 | filename = uri |
| 6657 | 6333 | end if |
| 6658 | 6334 | |
| 6659 | | - ! Debug logging |
| 6660 | | - block |
| 6661 | | - integer :: debug_unit |
| 6662 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 6663 | | - write(debug_unit, '(A)') '>>> APPLY_FILE_EDITS_OBJ <<<' |
| 6664 | | - write(debug_unit, '(A)') 'URI: ' // trim(uri) |
| 6665 | | - write(debug_unit, '(A)') 'Extracted filename: ' // trim(filename) |
| 6666 | | - write(debug_unit, '(A,I0)') 'Number of tabs: ', size(editor%tabs) |
| 6667 | | - close(debug_unit) |
| 6668 | | - end block |
| 6669 | | - |
| 6670 | 6335 | ! Find the tab with this file |
| 6671 | 6336 | tab_idx = 0 |
| 6672 | 6337 | do j = 1, size(editor%tabs) |
| 6673 | 6338 | if (allocated(editor%tabs(j)%filename)) then |
| 6674 | | - ! Debug logging for each tab |
| 6675 | | - block |
| 6676 | | - integer :: debug_unit |
| 6677 | | - logical :: exact_match, ends_with_match |
| 6678 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 6679 | | - write(debug_unit, '(A,I0,A)') 'Tab ', j, ': ' // trim(editor%tabs(j)%filename) |
| 6680 | | - exact_match = trim(editor%tabs(j)%filename) == trim(filename) |
| 6681 | | - ! Check if filename ends with tab filename (for absolute vs relative path matching) |
| 6682 | | - ends_with_match = .false. |
| 6683 | | - if (len(filename) >= len(editor%tabs(j)%filename)) then |
| 6684 | | - ends_with_match = filename(len(filename)-len(editor%tabs(j)%filename)+1:) == editor%tabs(j)%filename |
| 6685 | | - end if |
| 6686 | | - write(debug_unit, '(A,L1)') ' Exact match: ', exact_match |
| 6687 | | - write(debug_unit, '(A,L1)') ' Ends-with match: ', ends_with_match |
| 6688 | | - close(debug_unit) |
| 6689 | | - end block |
| 6690 | | - |
| 6691 | 6339 | ! Try exact match first, then check if the absolute path ends with the relative path |
| 6692 | 6340 | if (trim(editor%tabs(j)%filename) == trim(filename)) then |
| 6693 | 6341 | tab_idx = j |
@@ -6702,13 +6350,6 @@ contains |
| 6702 | 6350 | end if |
| 6703 | 6351 | end do |
| 6704 | 6352 | |
| 6705 | | - block |
| 6706 | | - integer :: debug_unit |
| 6707 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 6708 | | - write(debug_unit, '(A,I0)') 'Found tab_idx: ', tab_idx |
| 6709 | | - close(debug_unit) |
| 6710 | | - end block |
| 6711 | | - |
| 6712 | 6353 | if (tab_idx == 0) then |
| 6713 | 6354 | ! File not open - skip for now |
| 6714 | 6355 | if (allocated(filename)) deallocate(filename) |
@@ -6758,75 +6399,22 @@ contains |
| 6758 | 6399 | |
| 6759 | 6400 | integer :: start_pos, end_pos, delete_count |
| 6760 | 6401 | |
| 6761 | | - ! Debug logging |
| 6762 | | - block |
| 6763 | | - integer :: debug_unit |
| 6764 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 6765 | | - write(debug_unit, '(A)') '>>> APPLY_SINGLE_EDIT <<<' |
| 6766 | | - write(debug_unit, '(A,I0,A,I0)') 'Start: line=', start_line, ', char=', start_char |
| 6767 | | - write(debug_unit, '(A,I0,A,I0)') 'End: line=', end_line, ', char=', end_char |
| 6768 | | - write(debug_unit, '(A)') 'New text: ' // trim(new_text) |
| 6769 | | - close(debug_unit) |
| 6770 | | - end block |
| 6771 | | - |
| 6772 | 6402 | ! Calculate buffer positions |
| 6773 | 6403 | start_pos = get_buffer_position(buffer, start_line, start_char) |
| 6774 | 6404 | end_pos = get_buffer_position(buffer, end_line, end_char) |
| 6775 | 6405 | |
| 6776 | | - block |
| 6777 | | - integer :: debug_unit |
| 6778 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 6779 | | - write(debug_unit, '(A,I0)') 'Calculated start_pos: ', start_pos |
| 6780 | | - write(debug_unit, '(A,I0)') 'Calculated end_pos: ', end_pos |
| 6781 | | - close(debug_unit) |
| 6782 | | - end block |
| 6783 | | - |
| 6784 | | - if (start_pos <= 0 .or. end_pos <= 0) then |
| 6785 | | - block |
| 6786 | | - integer :: debug_unit |
| 6787 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 6788 | | - write(debug_unit, '(A)') 'EARLY RETURN: start_pos or end_pos <= 0' |
| 6789 | | - close(debug_unit) |
| 6790 | | - end block |
| 6791 | | - return |
| 6792 | | - end if |
| 6406 | + if (start_pos <= 0 .or. end_pos <= 0) return |
| 6793 | 6407 | |
| 6794 | 6408 | ! Delete the old text |
| 6795 | 6409 | delete_count = end_pos - start_pos |
| 6796 | | - block |
| 6797 | | - integer :: debug_unit |
| 6798 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 6799 | | - write(debug_unit, '(A,I0)') 'Delete count: ', delete_count |
| 6800 | | - close(debug_unit) |
| 6801 | | - end block |
| 6802 | | - |
| 6803 | 6410 | if (delete_count > 0) then |
| 6804 | | - block |
| 6805 | | - integer :: debug_unit |
| 6806 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 6807 | | - write(debug_unit, '(A,I0,A,I0)') 'Calling buffer_delete(pos=', start_pos, ', count=', delete_count, ')' |
| 6808 | | - close(debug_unit) |
| 6809 | | - end block |
| 6810 | 6411 | call buffer_delete(buffer, start_pos, delete_count) |
| 6811 | 6412 | end if |
| 6812 | 6413 | |
| 6813 | 6414 | ! Insert the new text |
| 6814 | 6415 | if (len(new_text) > 0) then |
| 6815 | | - block |
| 6816 | | - integer :: debug_unit |
| 6817 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 6818 | | - write(debug_unit, '(A,I0,A)') 'Calling buffer_insert(pos=', start_pos, ', text="' // trim(new_text) // '")' |
| 6819 | | - close(debug_unit) |
| 6820 | | - end block |
| 6821 | 6416 | call buffer_insert(buffer, start_pos, new_text) |
| 6822 | 6417 | end if |
| 6823 | | - |
| 6824 | | - block |
| 6825 | | - integer :: debug_unit |
| 6826 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 6827 | | - write(debug_unit, '(A)') 'apply_single_edit COMPLETED' |
| 6828 | | - close(debug_unit) |
| 6829 | | - end block |
| 6830 | 6418 | end subroutine apply_single_edit |
| 6831 | 6419 | |
| 6832 | 6420 | ! Execute a command from the command palette |
@@ -7048,39 +6636,9 @@ contains |
| 7048 | 6636 | integer :: target_line, target_col, i, num_locations |
| 7049 | 6637 | logical :: found_file |
| 7050 | 6638 | |
| 7051 | | - ! Log response for debugging |
| 7052 | | - block |
| 7053 | | - integer :: debug_unit |
| 7054 | | - character(len=:), allocatable :: result_str, error_str |
| 7055 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 7056 | | - write(debug_unit, '(A)') '>>> DEFINITION RESPONSE RECEIVED <<<' |
| 7057 | | - |
| 7058 | | - ! Check for error |
| 7059 | | - if (json_has_key(response%error, "message")) then |
| 7060 | | - error_str = json_get_string(response%error, "message") |
| 7061 | | - write(debug_unit, '(A)') 'ERROR: ' // trim(error_str) |
| 7062 | | - end if |
| 7063 | | - |
| 7064 | | - result_str = json_stringify(response%result) |
| 7065 | | - if (allocated(result_str)) then |
| 7066 | | - write(debug_unit, '(A)') 'Result JSON: ' // result_str(1:min(500,len(result_str))) |
| 7067 | | - else |
| 7068 | | - write(debug_unit, '(A)') 'Result JSON: (not allocated)' |
| 7069 | | - end if |
| 7070 | | - close(debug_unit) |
| 7071 | | - end block |
| 7072 | | - |
| 7073 | 6639 | ! Try to treat result as array first |
| 7074 | 6640 | num_locations = json_array_size(response%result) |
| 7075 | 6641 | |
| 7076 | | - block |
| 7077 | | - integer :: debug_unit |
| 7078 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 7079 | | - write(debug_unit, '(A,I0)') 'num_locations = ', num_locations |
| 7080 | | - write(debug_unit, '(A,L1)') 'has uri key = ', json_has_key(response%result, "uri") |
| 7081 | | - close(debug_unit) |
| 7082 | | - end block |
| 7083 | | - |
| 7084 | 6642 | if (num_locations > 0) then |
| 7085 | 6643 | ! Array of locations - take first one |
| 7086 | 6644 | location_obj = json_get_array_element(response%result, 0) |
@@ -7089,12 +6647,6 @@ contains |
| 7089 | 6647 | location_obj = response%result |
| 7090 | 6648 | else |
| 7091 | 6649 | ! No definition found |
| 7092 | | - block |
| 7093 | | - integer :: debug_unit |
| 7094 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 7095 | | - write(debug_unit, '(A)') '>>> NO DEFINITION FOUND (empty response) <<<' |
| 7096 | | - close(debug_unit) |
| 7097 | | - end block |
| 7098 | 6650 | call terminal_move_cursor(editor%screen_rows, 1) |
| 7099 | 6651 | call terminal_write('No definition found ') |
| 7100 | 6652 | if (associated(saved_buffer_for_callback)) then |
@@ -7132,23 +6684,31 @@ contains |
| 7132 | 6684 | target_line = int(line_real) + 1 |
| 7133 | 6685 | target_col = int(col_real) + 1 |
| 7134 | 6686 | |
| 7135 | | - ! Log details |
| 7136 | | - block |
| 7137 | | - integer :: debug_unit |
| 7138 | | - open(newunit=debug_unit, file='/tmp/fac_keys.log', position='append', action='write') |
| 7139 | | - write(debug_unit, '(A)') 'File: ' // trim(filepath) |
| 7140 | | - write(debug_unit, '(A,I0,A,I0)') 'Position: line=', target_line, ', col=', target_col |
| 7141 | | - close(debug_unit) |
| 7142 | | - end block |
| 7143 | | - |
| 7144 | 6687 | ! Check if the file is already open in a tab |
| 7145 | 6688 | found_file = .false. |
| 7146 | 6689 | do i = 1, size(editor%tabs) |
| 7147 | 6690 | if (allocated(editor%tabs(i)%filename)) then |
| 6691 | + ! Check for exact match or suffix match (handles relative vs absolute paths) |
| 7148 | 6692 | if (trim(editor%tabs(i)%filename) == trim(filepath)) then |
| 7149 | | - ! Switch to this tab |
| 7150 | | - editor%active_tab_index = i |
| 7151 | 6693 | found_file = .true. |
| 6694 | + else if (len_trim(filepath) > len_trim(editor%tabs(i)%filename)) then |
| 6695 | + ! Check if filepath ends with tab filename |
| 6696 | + if (filepath(len_trim(filepath)-len_trim(editor%tabs(i)%filename)+1:) == & |
| 6697 | + trim(editor%tabs(i)%filename)) then |
| 6698 | + found_file = .true. |
| 6699 | + end if |
| 6700 | + else if (len_trim(editor%tabs(i)%filename) > len_trim(filepath)) then |
| 6701 | + ! Check if tab filename ends with filepath |
| 6702 | + if (editor%tabs(i)%filename(len_trim(editor%tabs(i)%filename)-len_trim(filepath)+1:) == & |
| 6703 | + trim(filepath)) then |
| 6704 | + found_file = .true. |
| 6705 | + end if |
| 6706 | + end if |
| 6707 | + |
| 6708 | + if (found_file) then |
| 6709 | + ! Properly switch to this tab |
| 6710 | + call switch_to_tab(editor, i) |
| 6711 | + call sync_pane_to_editor(editor, i, editor%tabs(i)%active_pane_index) |
| 7152 | 6712 | exit |
| 7153 | 6713 | end if |
| 7154 | 6714 | end if |
@@ -7173,6 +6733,19 @@ contains |
| 7173 | 6733 | call copy_buffer(editor%tabs(new_tab_idx)%panes(1)%buffer, editor%tabs(new_tab_idx)%buffer) |
| 7174 | 6734 | end if |
| 7175 | 6735 | |
| 6736 | + ! Send LSP didOpen notification to all active servers for this tab |
| 6737 | + if (editor%tabs(new_tab_idx)%num_lsp_servers > 0) then |
| 6738 | + block |
| 6739 | + use text_buffer_module, only: buffer_to_string |
| 6740 | + integer :: srv_i |
| 6741 | + do srv_i = 1, editor%tabs(new_tab_idx)%num_lsp_servers |
| 6742 | + call notify_file_opened(editor%lsp_manager, & |
| 6743 | + editor%tabs(new_tab_idx)%lsp_server_indices(srv_i), & |
| 6744 | + filepath, buffer_to_string(editor%tabs(new_tab_idx)%buffer)) |
| 6745 | + end do |
| 6746 | + end block |
| 6747 | + end if |
| 6748 | + |
| 7176 | 6749 | ! Switch to the new tab |
| 7177 | 6750 | call switch_to_tab(editor, new_tab_idx) |
| 7178 | 6751 | |
@@ -7208,10 +6781,14 @@ contains |
| 7208 | 6781 | ! File already open in tabs - jump to the line and column |
| 7209 | 6782 | editor%cursors(editor%active_cursor)%line = target_line |
| 7210 | 6783 | editor%cursors(editor%active_cursor)%column = target_col |
| 6784 | + editor%cursors(editor%active_cursor)%desired_column = target_col |
| 7211 | 6785 | |
| 7212 | 6786 | ! Center viewport on target |
| 7213 | 6787 | editor%viewport_line = max(1, target_line - editor%screen_rows / 2) |
| 7214 | 6788 | |
| 6789 | + ! Sync cursor changes back to pane |
| 6790 | + call sync_editor_to_pane(editor) |
| 6791 | + |
| 7215 | 6792 | call terminal_move_cursor(editor%screen_rows, 1) |
| 7216 | 6793 | call terminal_write('Jumped to definition ') |
| 7217 | 6794 | if (associated(saved_buffer_for_callback)) then |