@@ -27,7 +27,7 @@ module command_handler_module |
| 27 | request_references, request_code_actions, request_document_symbols, & | 27 | request_references, request_code_actions, request_document_symbols, & |
| 28 | request_signature_help, request_formatting, request_rename, & | 28 | request_signature_help, request_formatting, request_rename, & |
| 29 | process_server_messages, filename_to_uri, & | 29 | process_server_messages, filename_to_uri, & |
| 30 | - get_server_with_capability, & | 30 | + get_server_with_capability, notify_file_opened, & |
| 31 | CAP_COMPLETION, CAP_DEFINITION, CAP_REFERENCES, CAP_RENAME, & | 31 | CAP_COMPLETION, CAP_DEFINITION, CAP_REFERENCES, CAP_RENAME, & |
| 32 | CAP_CODE_ACTIONS, CAP_FORMATTING, CAP_HOVER, CAP_DOCUMENT_SYMBOLS | 32 | CAP_CODE_ACTIONS, CAP_FORMATTING, CAP_HOVER, CAP_DOCUMENT_SYMBOLS |
| 33 | use rename_prompt_module, only: show_rename_prompt | 33 | use rename_prompt_module, only: show_rename_prompt |
@@ -188,13 +188,30 @@ contains |
| 188 | end if | 188 | end if |
| 189 | end if | 189 | end if |
| 190 | | 190 | |
| 191 | - ! Debug: log all incoming keys | 191 | + ! Route keys to code actions panel when visible |
| 192 | - block | 192 | + if (is_code_actions_panel_visible(editor%code_actions_panel)) then |
| 193 | - integer :: dbg | 193 | + if (code_actions_panel_handle_key(editor%code_actions_panel, trim(key_str))) then |
| 194 | - open(newunit=dbg, file='/tmp/fac_keys_all.log', position='append', action='write') | 194 | + ! For Enter, we need to apply the code action here since panel just returns handled=true |
| 195 | - write(dbg, '(A,A,A)') 'key_str = [', trim(key_str), ']' | 195 | + if (trim(key_str) == 'enter') then |
| 196 | - close(dbg) | 196 | + call apply_selected_code_action(editor, buffer) |
| 197 | - end block | 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 | select case(trim(key_str)) | 216 | select case(trim(key_str)) |
| 200 | ! File operations | 217 | ! File operations |
@@ -225,33 +242,7 @@ contains |
| 225 | return | 242 | return |
| 226 | end if | 243 | end if |
| 227 | | 244 | |
| 228 | - ! If diagnostics panel is visible, hide it | 245 | + ! Other panels (diagnostics, code_actions, references, symbols) are handled in early routing |
| 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 | | |
| 255 | | 246 | |
| 256 | ! ESC - Clear selections and return to single cursor mode | 247 | ! ESC - Clear selections and return to single cursor mode |
| 257 | if (size(editor%cursors) > 1) then | 248 | if (size(editor%cursors) > 1) then |
@@ -357,33 +348,7 @@ contains |
| 357 | return | 348 | return |
| 358 | end if | 349 | end if |
| 359 | | 350 | |
| 360 | - ! If diagnostics panel is visible, navigate it | 351 | + ! Other panels (diagnostics, code_actions, references, symbols) are handled in early routing |
| 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 | | |
| 387 | | 352 | |
| 388 | if (size(editor%cursors) > 1) then | 353 | if (size(editor%cursors) > 1) then |
| 389 | ! Move all cursors | 354 | ! Move all cursors |
@@ -405,33 +370,7 @@ contains |
| 405 | return | 370 | return |
| 406 | end if | 371 | end if |
| 407 | | 372 | |
| 408 | - ! If diagnostics panel is visible, navigate it | 373 | + ! Other panels (diagnostics, code_actions, references, symbols) are handled in early routing |
| 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 | | |
| 435 | | 374 | |
| 436 | if (size(editor%cursors) > 1) then | 375 | if (size(editor%cursors) > 1) then |
| 437 | ! Move all cursors | 376 | ! Move all cursors |
@@ -743,71 +682,7 @@ contains |
| 743 | is_edit_action = .true. | 682 | is_edit_action = .true. |
| 744 | | 683 | |
| 745 | case('enter') | 684 | case('enter') |
| 746 | - ! If code actions menu is visible, apply selected action | 685 | + ! Code actions panel is handled in early routing above |
| 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 | | |
| 811 | | 686 | |
| 812 | ! If symbols panel is visible, jump to selected symbol | 687 | ! If symbols panel is visible, jump to selected symbol |
| 813 | if (is_symbols_panel_visible(editor%symbols_panel)) then | 688 | if (is_symbols_panel_visible(editor%symbols_panel)) then |
@@ -1269,13 +1144,6 @@ contains |
| 1269 | | 1144 | |
| 1270 | case('f10', 'alt-.') | 1145 | case('f10', 'alt-.') |
| 1271 | ! Trigger code actions (F10 or Alt+.) - toggle behavior | 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 | ! If panel is already visible, close it | 1147 | ! If panel is already visible, close it |
| 1280 | if (is_code_actions_panel_visible(editor%code_actions_panel)) then | 1148 | if (is_code_actions_panel_visible(editor%code_actions_panel)) then |
| 1281 | call hide_code_actions_panel(editor%code_actions_panel) | 1149 | call hide_code_actions_panel(editor%code_actions_panel) |
@@ -1286,7 +1154,7 @@ contains |
| 1286 | if (code_actions_server > 0) then | 1154 | if (code_actions_server > 0) then |
| 1287 | ! Request code actions for the current line | 1155 | ! Request code actions for the current line |
| 1288 | block | 1156 | block |
| 1289 | - integer :: request_id, lsp_line, dbg, dbg_i | 1157 | + integer :: request_id, lsp_line |
| 1290 | character(len=:), allocatable :: file_uri | 1158 | character(len=:), allocatable :: file_uri |
| 1291 | type(diagnostic_t), allocatable :: line_diags(:) | 1159 | type(diagnostic_t), allocatable :: line_diags(:) |
| 1292 | type(json_value_t) :: diags_json | 1160 | type(json_value_t) :: diags_json |
@@ -1300,58 +1168,12 @@ contains |
| 1300 | ! This is critical for multi-LSP: Ruff should only see Ruff's diagnostics | 1168 | ! This is critical for multi-LSP: Ruff should only see Ruff's diagnostics |
| 1301 | file_uri = filename_to_uri(editor%tabs(editor%active_tab_index)%filename) | 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 | line_diags = get_diagnostics_for_line_by_server(editor%diagnostics, file_uri, & | 1171 | line_diags = get_diagnostics_for_line_by_server(editor%diagnostics, file_uri, & |
| 1311 | editor%cursors(editor%active_cursor)%line, code_actions_server) | 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 | ! Convert diagnostics to JSON for request | 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 | diags_json = diagnostics_to_json(line_diags) | 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 | ! Request code actions for entire line with diagnostics context | 1177 | ! Request code actions for entire line with diagnostics context |
| 1356 | request_id = request_code_actions(editor%lsp_manager, & | 1178 | request_id = request_code_actions(editor%lsp_manager, & |
| 1357 | code_actions_server, & | 1179 | code_actions_server, & |
@@ -1360,10 +1182,6 @@ contains |
| 1360 | lsp_line, 999, & | 1182 | lsp_line, 999, & |
| 1361 | handle_code_actions_response_wrapper, & | 1183 | handle_code_actions_response_wrapper, & |
| 1362 | diags_json) | 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 | ! Panel will be shown when response arrives in handle_code_actions_response_impl | 1185 | ! Panel will be shown when response arrives in handle_code_actions_response_impl |
| 1368 | end block | 1186 | end block |
| 1369 | end if | 1187 | end if |
@@ -1372,14 +1190,6 @@ contains |
| 1372 | | 1190 | |
| 1373 | case('f12', 'ctrl-\\', 'alt-g') | 1191 | case('f12', 'ctrl-\\', 'alt-g') |
| 1374 | ! Go to definition (F12, Ctrl+\, or Alt+G) | 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 | call terminal_move_cursor(editor%screen_rows, 1) | 1193 | call terminal_move_cursor(editor%screen_rows, 1) |
| 1384 | block | 1194 | block |
| 1385 | integer :: def_server | 1195 | integer :: def_server |
@@ -1408,13 +1218,6 @@ contains |
| 1408 | editor%tabs(editor%active_tab_index)%filename, & | 1218 | editor%tabs(editor%active_tab_index)%filename, & |
| 1409 | lsp_line, lsp_char, handle_definition_response_wrapper) | 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 | if (request_id > 0) then | 1221 | if (request_id > 0) then |
| 1419 | ! Response will be handled by callback | 1222 | ! Response will be handled by callback |
| 1420 | call terminal_write('Searching for definition... ') | 1223 | call terminal_write('Searching for definition... ') |
@@ -1429,12 +1232,6 @@ contains |
| 1429 | | 1232 | |
| 1430 | case('shift-f12', 'alt-r') | 1233 | case('shift-f12', 'alt-r') |
| 1431 | ! Find all references (Shift+F12 or Alt+R) | 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 | block | 1235 | block |
| 1439 | integer :: refs_server | 1236 | integer :: refs_server |
| 1440 | refs_server = get_lsp_server_for_cap(editor, CAP_REFERENCES) | 1237 | refs_server = get_lsp_server_for_cap(editor, CAP_REFERENCES) |
@@ -1540,13 +1337,6 @@ contains |
| 1540 | | 1337 | |
| 1541 | case('f2') | 1338 | case('f2') |
| 1542 | ! Rename symbol | 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 | block | 1340 | block |
| 1551 | integer :: rename_server | 1341 | integer :: rename_server |
| 1552 | rename_server = get_lsp_server_for_cap(editor, CAP_RENAME) | 1342 | rename_server = get_lsp_server_for_cap(editor, CAP_RENAME) |
@@ -1572,17 +1362,6 @@ contains |
| 1572 | lsp_line = editor%cursors(editor%active_cursor)%line - 1 | 1362 | lsp_line = editor%cursors(editor%active_cursor)%line - 1 |
| 1573 | lsp_char = editor%cursors(editor%active_cursor)%column - 1 | 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 | ! Save editor state for callback | 1365 | ! Save editor state for callback |
| 1587 | saved_editor_for_callback => editor | 1366 | saved_editor_for_callback => editor |
| 1588 | | 1367 | |
@@ -1597,26 +1376,16 @@ contains |
| 1597 | | 1376 | |
| 1598 | ! Poll for LSP response and render immediately when received | 1377 | ! Poll for LSP response and render immediately when received |
| 1599 | block | 1378 | block |
| 1600 | - integer :: poll_count, max_polls, pane_idx, debug_unit | 1379 | + integer :: poll_count, max_polls, pane_idx |
| 1601 | integer(8) :: start_time, end_time, count_rate, target_time | 1380 | integer(8) :: start_time, end_time, count_rate, target_time |
| 1602 | max_polls = 100 ! Poll up to 100 times (1 second total) | 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 | do poll_count = 1, max_polls | 1383 | do poll_count = 1, max_polls |
| 1610 | ! Process any LSP messages | 1384 | ! Process any LSP messages |
| 1611 | call process_server_messages(editor%lsp_manager) | 1385 | call process_server_messages(editor%lsp_manager) |
| 1612 | | 1386 | |
| 1613 | ! Check if rename response modified the buffer | 1387 | ! Check if rename response modified the buffer |
| 1614 | if (g_lsp_modified_buffer) then | 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 | ! Sync buffer from tab (LSP modified tab buffer) | 1389 | ! Sync buffer from tab (LSP modified tab buffer) |
| 1621 | call copy_buffer(buffer, editor%tabs(editor%active_tab_index)%buffer) | 1390 | call copy_buffer(buffer, editor%tabs(editor%active_tab_index)%buffer) |
| 1622 | | 1391 | |
@@ -1649,13 +1418,6 @@ contains |
| 1649 | if (end_time >= target_time) exit | 1418 | if (end_time >= target_time) exit |
| 1650 | end do | 1419 | end do |
| 1651 | end do | 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 | end block | 1421 | end block |
| 1660 | end if | 1422 | end if |
| 1661 | | 1423 | |
@@ -1704,12 +1466,6 @@ contains |
| 1704 | | 1466 | |
| 1705 | case('f4', 'alt-o') | 1467 | case('f4', 'alt-o') |
| 1706 | ! Document symbols outline (F4 or Alt+O) | 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 | block | 1469 | block |
| 1714 | integer :: symbols_server | 1470 | integer :: symbols_server |
| 1715 | symbols_server = get_lsp_server_for_cap(editor, CAP_DOCUMENT_SYMBOLS) | 1471 | symbols_server = get_lsp_server_for_cap(editor, CAP_DOCUMENT_SYMBOLS) |
@@ -1900,29 +1656,9 @@ contains |
| 1900 | | 1656 | |
| 1901 | case('f8', 'alt-e') | 1657 | case('f8', 'alt-e') |
| 1902 | ! Toggle diagnostics panel (F8 or Alt+E for errors) | 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 | call toggle_panel(editor%diagnostics_panel) | 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 | ! Re-render screen to show/hide the panel | 1660 | ! Re-render screen to show/hide the panel |
| 1919 | call render_screen(buffer, editor) | 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 | case('alt-c') | 1663 | case('alt-c') |
| 1928 | ! Toggle case sensitivity for match mode (ctrl-d) | 1664 | ! Toggle case sensitivity for match mode (ctrl-d) |
@@ -1999,12 +1735,6 @@ contains |
| 1999 | end if | 1735 | end if |
| 2000 | | 1736 | |
| 2001 | case default | 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 | ! Check for mouse events | 1738 | ! Check for mouse events |
| 2009 | if (index(key_str, 'mouse-') == 1) then | 1739 | if (index(key_str, 'mouse-') == 1) then |
| 2010 | call handle_mouse_event_action(key_str, editor, buffer) | 1740 | call handle_mouse_event_action(key_str, editor, buffer) |
@@ -5238,6 +4968,18 @@ contains |
| 5238 | allocate(character(len=len_trim(full_path)) :: editor%filename) | 4968 | allocate(character(len=len_trim(full_path)) :: editor%filename) |
| 5239 | editor%filename = full_path | 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 | ! Reset cursor to top of file | 4983 | ! Reset cursor to top of file |
| 5242 | editor%cursors(editor%active_cursor)%line = 1 | 4984 | editor%cursors(editor%active_cursor)%line = 1 |
| 5243 | editor%cursors(editor%active_cursor)%column = 1 | 4985 | editor%cursors(editor%active_cursor)%column = 1 |
@@ -5989,13 +5731,6 @@ contains |
| 5989 | integer, intent(in) :: request_id | 5731 | integer, intent(in) :: request_id |
| 5990 | type(lsp_message_t), intent(in) :: response | 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 | ! Call the actual handler with saved editor state | 5734 | ! Call the actual handler with saved editor state |
| 6000 | if (associated(saved_editor_for_callback)) then | 5735 | if (associated(saved_editor_for_callback)) then |
| 6001 | call handle_references_response_impl(saved_editor_for_callback, response) | 5736 | call handle_references_response_impl(saved_editor_for_callback, response) |
@@ -6122,27 +5857,14 @@ contains |
| 6122 | type(lsp_message_t), intent(in) :: response | 5857 | type(lsp_message_t), intent(in) :: response |
| 6123 | type(json_value_t) :: result_array, action_obj, edit_obj | 5858 | type(json_value_t) :: result_array, action_obj, edit_obj |
| 6124 | type(code_action_t), allocatable :: actions(:) | 5859 | type(code_action_t), allocatable :: actions(:) |
| 6125 | - integer :: num_actions, i, dbg | 5860 | + integer :: num_actions, i |
| 6126 | - character(len=:), allocatable :: title, kind, action_json, result_str | 5861 | + character(len=:), allocatable :: title, kind, action_json |
| 6127 | logical :: is_preferred | 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 | ! The result is directly in response%result for LSP responses | 5864 | ! The result is directly in response%result for LSP responses |
| 6139 | result_array = response%result | 5865 | result_array = response%result |
| 6140 | num_actions = json_array_size(result_array) | 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 | if (num_actions == 0) then | 5868 | if (num_actions == 0) then |
| 6147 | ! No actions available - don't show panel | 5869 | ! No actions available - don't show panel |
| 6148 | return | 5870 | return |
@@ -6206,13 +5928,6 @@ contains |
| 6206 | integer, intent(in) :: request_id | 5928 | integer, intent(in) :: request_id |
| 6207 | type(lsp_message_t), intent(in) :: response | 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 | ! Call the actual handler with saved editor state | 5931 | ! Call the actual handler with saved editor state |
| 6217 | if (associated(saved_editor_for_callback)) then | 5932 | if (associated(saved_editor_for_callback)) then |
| 6218 | call handle_symbols_response_impl(saved_editor_for_callback, response) | 5933 | call handle_symbols_response_impl(saved_editor_for_callback, response) |
@@ -6238,26 +5953,6 @@ contains |
| 6238 | result_array = response%result | 5953 | result_array = response%result |
| 6239 | num_symbols = json_array_size(result_array) | 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 | if (num_symbols == 0) then | 5956 | if (num_symbols == 0) then |
| 6262 | call clear_symbols(editor%symbols_panel) | 5957 | call clear_symbols(editor%symbols_panel) |
| 6263 | call terminal_move_cursor(editor%screen_rows, 1) | 5958 | call terminal_move_cursor(editor%screen_rows, 1) |
@@ -6406,24 +6101,12 @@ contains |
| 6406 | | 6101 | |
| 6407 | character(len=:), allocatable :: result_str | 6102 | character(len=:), allocatable :: result_str |
| 6408 | integer :: changes_applied | 6103 | integer :: changes_applied |
| 6409 | - integer :: debug_unit | | |
| 6410 | | 6104 | |
| 6411 | if (.not. associated(saved_editor_for_callback)) return | 6105 | if (.not. associated(saved_editor_for_callback)) return |
| 6412 | | 6106 | |
| 6413 | ! Convert result to string for apply_workspace_edit | 6107 | ! Convert result to string for apply_workspace_edit |
| 6414 | result_str = json_stringify(response%result) | 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 | if (.not. allocated(result_str) .or. result_str == 'null' .or. len_trim(result_str) == 0) then | 6110 | if (.not. allocated(result_str) .or. result_str == 'null' .or. len_trim(result_str) == 0) then |
| 6428 | call terminal_move_cursor(saved_editor_for_callback%screen_rows, 1) | 6111 | call terminal_move_cursor(saved_editor_for_callback%screen_rows, 1) |
| 6429 | call terminal_write('Rename failed or not supported ') | 6112 | call terminal_write('Rename failed or not supported ') |
@@ -6434,21 +6117,6 @@ contains |
| 6434 | ! Apply workspace edit | 6117 | ! Apply workspace edit |
| 6435 | call apply_workspace_edit(saved_editor_for_callback, result_str, changes_applied) | 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 | call terminal_move_cursor(saved_editor_for_callback%screen_rows, 1) | 6120 | call terminal_move_cursor(saved_editor_for_callback%screen_rows, 1) |
| 6453 | if (changes_applied > 0) then | 6121 | if (changes_applied > 0) then |
| 6454 | block | 6122 | block |
@@ -6533,6 +6201,52 @@ contains |
| 6533 | end if | 6201 | end if |
| 6534 | end subroutine handle_formatting_response_wrapper | 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 | ! Apply a workspace edit from LSP | 6250 | ! Apply a workspace edit from LSP |
| 6537 | subroutine apply_workspace_edit(editor, edit_json, changes_applied) | 6251 | subroutine apply_workspace_edit(editor, edit_json, changes_applied) |
| 6538 | use json_module, only: json_parse, json_value_t, json_get_array, json_array_size, & | 6252 | use json_module, only: json_parse, json_value_t, json_get_array, json_array_size, & |
@@ -6549,15 +6263,6 @@ contains |
| 6549 | | 6263 | |
| 6550 | changes_applied = 0 | 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 | ! Parse the edit JSON | 6266 | ! Parse the edit JSON |
| 6562 | edit_obj = json_parse(edit_json) | 6267 | edit_obj = json_parse(edit_json) |
| 6563 | | 6268 | |
@@ -6566,13 +6271,6 @@ contains |
| 6566 | doc_changes_arr = json_get_array(edit_obj, 'documentChanges') | 6271 | doc_changes_arr = json_get_array(edit_obj, 'documentChanges') |
| 6567 | num_files = json_array_size(doc_changes_arr) | 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 | do i = 0, num_files - 1 ! 0-based index | 6274 | do i = 0, num_files - 1 ! 0-based index |
| 6577 | file_change_obj = json_get_array_element(doc_changes_arr, i) | 6275 | file_change_obj = json_get_array_element(doc_changes_arr, i) |
| 6578 | | 6276 | |
@@ -6580,33 +6278,11 @@ contains |
| 6580 | if (json_has_key(file_change_obj, 'textDocument')) then | 6278 | if (json_has_key(file_change_obj, 'textDocument')) then |
| 6581 | text_doc_obj = json_get_object(file_change_obj, 'textDocument') | 6279 | text_doc_obj = json_get_object(file_change_obj, 'textDocument') |
| 6582 | uri = json_get_string(text_doc_obj, 'uri') | 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 | end if | 6281 | end if |
| 6597 | | 6282 | |
| 6598 | ! Get edits array | 6283 | ! Get edits array |
| 6599 | if (json_has_key(file_change_obj, 'edits') .and. allocated(uri)) then | 6284 | if (json_has_key(file_change_obj, 'edits') .and. allocated(uri)) then |
| 6600 | edits_arr = json_get_array(file_change_obj, 'edits') | 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 | call apply_file_edits_obj(editor, uri, edits_arr, changes_applied) | 6286 | call apply_file_edits_obj(editor, uri, edits_arr, changes_applied) |
| 6611 | deallocate(uri) | 6287 | deallocate(uri) |
| 6612 | end if | 6288 | end if |
@@ -6656,38 +6332,10 @@ contains |
| 6656 | filename = uri | 6332 | filename = uri |
| 6657 | end if | 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 | ! Find the tab with this file | 6335 | ! Find the tab with this file |
| 6671 | tab_idx = 0 | 6336 | tab_idx = 0 |
| 6672 | do j = 1, size(editor%tabs) | 6337 | do j = 1, size(editor%tabs) |
| 6673 | if (allocated(editor%tabs(j)%filename)) then | 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 | ! Try exact match first, then check if the absolute path ends with the relative path | 6339 | ! Try exact match first, then check if the absolute path ends with the relative path |
| 6692 | if (trim(editor%tabs(j)%filename) == trim(filename)) then | 6340 | if (trim(editor%tabs(j)%filename) == trim(filename)) then |
| 6693 | tab_idx = j | 6341 | tab_idx = j |
@@ -6702,13 +6350,6 @@ contains |
| 6702 | end if | 6350 | end if |
| 6703 | end do | 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 | if (tab_idx == 0) then | 6353 | if (tab_idx == 0) then |
| 6713 | ! File not open - skip for now | 6354 | ! File not open - skip for now |
| 6714 | if (allocated(filename)) deallocate(filename) | 6355 | if (allocated(filename)) deallocate(filename) |
@@ -6758,75 +6399,22 @@ contains |
| 6758 | | 6399 | |
| 6759 | integer :: start_pos, end_pos, delete_count | 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 | ! Calculate buffer positions | 6402 | ! Calculate buffer positions |
| 6773 | start_pos = get_buffer_position(buffer, start_line, start_char) | 6403 | start_pos = get_buffer_position(buffer, start_line, start_char) |
| 6774 | end_pos = get_buffer_position(buffer, end_line, end_char) | 6404 | end_pos = get_buffer_position(buffer, end_line, end_char) |
| 6775 | | 6405 | |
| 6776 | - block | 6406 | + if (start_pos <= 0 .or. end_pos <= 0) return |
| 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 | | |
| 6793 | | 6407 | |
| 6794 | ! Delete the old text | 6408 | ! Delete the old text |
| 6795 | delete_count = end_pos - start_pos | 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 | if (delete_count > 0) then | 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 | call buffer_delete(buffer, start_pos, delete_count) | 6411 | call buffer_delete(buffer, start_pos, delete_count) |
| 6811 | end if | 6412 | end if |
| 6812 | | 6413 | |
| 6813 | ! Insert the new text | 6414 | ! Insert the new text |
| 6814 | if (len(new_text) > 0) then | 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 | call buffer_insert(buffer, start_pos, new_text) | 6416 | call buffer_insert(buffer, start_pos, new_text) |
| 6822 | end if | 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 | end subroutine apply_single_edit | 6418 | end subroutine apply_single_edit |
| 6831 | | 6419 | |
| 6832 | ! Execute a command from the command palette | 6420 | ! Execute a command from the command palette |
@@ -7048,39 +6636,9 @@ contains |
| 7048 | integer :: target_line, target_col, i, num_locations | 6636 | integer :: target_line, target_col, i, num_locations |
| 7049 | logical :: found_file | 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 | ! Try to treat result as array first | 6639 | ! Try to treat result as array first |
| 7074 | num_locations = json_array_size(response%result) | 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 | if (num_locations > 0) then | 6642 | if (num_locations > 0) then |
| 7085 | ! Array of locations - take first one | 6643 | ! Array of locations - take first one |
| 7086 | location_obj = json_get_array_element(response%result, 0) | 6644 | location_obj = json_get_array_element(response%result, 0) |
@@ -7089,12 +6647,6 @@ contains |
| 7089 | location_obj = response%result | 6647 | location_obj = response%result |
| 7090 | else | 6648 | else |
| 7091 | ! No definition found | 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 | call terminal_move_cursor(editor%screen_rows, 1) | 6650 | call terminal_move_cursor(editor%screen_rows, 1) |
| 7099 | call terminal_write('No definition found ') | 6651 | call terminal_write('No definition found ') |
| 7100 | if (associated(saved_buffer_for_callback)) then | 6652 | if (associated(saved_buffer_for_callback)) then |
@@ -7132,23 +6684,31 @@ contains |
| 7132 | target_line = int(line_real) + 1 | 6684 | target_line = int(line_real) + 1 |
| 7133 | target_col = int(col_real) + 1 | 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 | ! Check if the file is already open in a tab | 6687 | ! Check if the file is already open in a tab |
| 7145 | found_file = .false. | 6688 | found_file = .false. |
| 7146 | do i = 1, size(editor%tabs) | 6689 | do i = 1, size(editor%tabs) |
| 7147 | if (allocated(editor%tabs(i)%filename)) then | 6690 | if (allocated(editor%tabs(i)%filename)) then |
| | 6691 | + ! Check for exact match or suffix match (handles relative vs absolute paths) |
| 7148 | if (trim(editor%tabs(i)%filename) == trim(filepath)) then | 6692 | if (trim(editor%tabs(i)%filename) == trim(filepath)) then |
| 7149 | - ! Switch to this tab | | |
| 7150 | - editor%active_tab_index = i | | |
| 7151 | found_file = .true. | 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 | exit | 6712 | exit |
| 7153 | end if | 6713 | end if |
| 7154 | end if | 6714 | end if |
@@ -7173,6 +6733,19 @@ contains |
| 7173 | call copy_buffer(editor%tabs(new_tab_idx)%panes(1)%buffer, editor%tabs(new_tab_idx)%buffer) | 6733 | call copy_buffer(editor%tabs(new_tab_idx)%panes(1)%buffer, editor%tabs(new_tab_idx)%buffer) |
| 7174 | end if | 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 | ! Switch to the new tab | 6749 | ! Switch to the new tab |
| 7177 | call switch_to_tab(editor, new_tab_idx) | 6750 | call switch_to_tab(editor, new_tab_idx) |
| 7178 | | 6751 | |
@@ -7208,10 +6781,14 @@ contains |
| 7208 | ! File already open in tabs - jump to the line and column | 6781 | ! File already open in tabs - jump to the line and column |
| 7209 | editor%cursors(editor%active_cursor)%line = target_line | 6782 | editor%cursors(editor%active_cursor)%line = target_line |
| 7210 | editor%cursors(editor%active_cursor)%column = target_col | 6783 | editor%cursors(editor%active_cursor)%column = target_col |
| | 6784 | + editor%cursors(editor%active_cursor)%desired_column = target_col |
| 7211 | | 6785 | |
| 7212 | ! Center viewport on target | 6786 | ! Center viewport on target |
| 7213 | editor%viewport_line = max(1, target_line - editor%screen_rows / 2) | 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 | call terminal_move_cursor(editor%screen_rows, 1) | 6792 | call terminal_move_cursor(editor%screen_rows, 1) |
| 7216 | call terminal_write('Jumped to definition ') | 6793 | call terminal_write('Jumped to definition ') |
| 7217 | if (associated(saved_buffer_for_callback)) then | 6794 | if (associated(saved_buffer_for_callback)) then |