fortrangoingonforty/facsimile / d4831b3

Browse files

adjust command palette to top center, wire up items to fire

Authored by espadonne
SHA
d4831b3b095ed98cf54b1313447da6b22f20e310
Parents
f9c65b5
Tree
d4972b0

2 changed files

StatusFile+-
M src/commands/command_handler_module.f90 73 5
M src/ui/command_palette_module.f90 76 38
src/commands/command_handler_module.f90modified
@@ -1562,7 +1562,7 @@ contains
1562
                 use command_palette_module, only: show_command_palette_interactive
1562
                 use command_palette_module, only: show_command_palette_interactive
1563
                 character(len=:), allocatable :: cmd_id
1563
                 character(len=:), allocatable :: cmd_id
1564
 
1564
 
1565
-                cmd_id = show_command_palette_interactive(editor%command_palette, editor%screen_rows)
1565
+                cmd_id = show_command_palette_interactive(editor%command_palette, editor%screen_rows, editor%screen_cols)
1566
 
1566
 
1567
                 if (allocated(cmd_id) .and. len_trim(cmd_id) > 0) then
1567
                 if (allocated(cmd_id) .and. len_trim(cmd_id) > 0) then
1568
                     ! Execute the command by re-processing as a key
1568
                     ! Execute the command by re-processing as a key
@@ -6584,11 +6584,79 @@ contains
6584
         character(len=*), intent(in) :: cmd_id
6584
         character(len=*), intent(in) :: cmd_id
6585
         logical, intent(out) :: should_quit
6585
         logical, intent(out) :: should_quit
6586
 
6586
 
6587
-        ! For now, just display the selected command
6588
-        ! TODO: Implement full command execution in next iteration
6589
-        call terminal_move_cursor(editor%screen_rows, 1)
6590
-        call terminal_write('Selected: ' // trim(cmd_id) // '                    ')
6591
         should_quit = .false.
6587
         should_quit = .false.
6588
+
6589
+        ! Map command IDs to their corresponding key commands
6590
+        select case(trim(cmd_id))
6591
+        ! File operations
6592
+        case('save')
6593
+            call handle_key_command('ctrl-s', editor, buffer, should_quit)
6594
+        case('save-all')
6595
+            call handle_key_command('ctrl-shift-s', editor, buffer, should_quit)
6596
+        case('quit')
6597
+            call handle_key_command('ctrl-q', editor, buffer, should_quit)
6598
+        case('open')
6599
+            ! Open fortress mode for file browsing
6600
+            editor%fuss_mode_active = .true.
6601
+            call render_screen(buffer, editor)
6602
+        case('toggle-tree')
6603
+            call handle_key_command('f3', editor, buffer, should_quit)
6604
+
6605
+        ! Edit operations
6606
+        case('copy')
6607
+            call handle_key_command('ctrl-c', editor, buffer, should_quit)
6608
+        case('paste')
6609
+            call handle_key_command('ctrl-v', editor, buffer, should_quit)
6610
+        case('cut')
6611
+            call handle_key_command('ctrl-x', editor, buffer, should_quit)
6612
+        case('undo')
6613
+            call handle_key_command('ctrl-z', editor, buffer, should_quit)
6614
+        case('redo')
6615
+            call handle_key_command('ctrl-y', editor, buffer, should_quit)
6616
+
6617
+        ! Search operations
6618
+        case('find')
6619
+            call handle_key_command('ctrl-f', editor, buffer, should_quit)
6620
+        case('replace')
6621
+            call handle_key_command('ctrl-h', editor, buffer, should_quit)
6622
+        case('find-next')
6623
+            call handle_key_command('ctrl-g', editor, buffer, should_quit)
6624
+
6625
+        ! Navigation
6626
+        case('goto-line')
6627
+            call handle_key_command('alt-g', editor, buffer, should_quit)
6628
+        case('goto-def')
6629
+            call handle_key_command('f12', editor, buffer, should_quit)
6630
+        case('find-refs')
6631
+            call handle_key_command('shift-f12', editor, buffer, should_quit)
6632
+        case('jump-back')
6633
+            call handle_key_command('alt-,', editor, buffer, should_quit)
6634
+        case('goto-symbol')
6635
+            call handle_key_command('f4', editor, buffer, should_quit)
6636
+
6637
+        ! LSP features
6638
+        case('code-actions')
6639
+            call handle_key_command('f8', editor, buffer, should_quit)
6640
+        case('rename')
6641
+            call handle_key_command('f2', editor, buffer, should_quit)
6642
+        case('diagnostics')
6643
+            call handle_key_command('alt-e', editor, buffer, should_quit)
6644
+
6645
+        ! View
6646
+        case('split-v')
6647
+            call handle_key_command('ctrl-\\', editor, buffer, should_quit)
6648
+        case('close-pane')
6649
+            call handle_key_command('ctrl-w', editor, buffer, should_quit)
6650
+
6651
+        ! Help
6652
+        case('help')
6653
+            call handle_key_command('f1', editor, buffer, should_quit)
6654
+
6655
+        case default
6656
+            ! Unknown command - show message
6657
+            call terminal_move_cursor(editor%screen_rows, 1)
6658
+            call terminal_write('Unknown command: ' // trim(cmd_id) // repeat(' ', 20))
6659
+        end select
6592
     end subroutine execute_palette_command
6660
     end subroutine execute_palette_command
6593
 
6661
 
6594
     ! Handle workspace symbols LSP response
6662
     ! Handle workspace symbols LSP response
src/ui/command_palette_module.f90modified
@@ -13,6 +13,7 @@ module command_palette_module
13
 
13
 
14
     integer, parameter :: MAX_COMMANDS = 100
14
     integer, parameter :: MAX_COMMANDS = 100
15
     integer, parameter :: MAX_VISIBLE = 10
15
     integer, parameter :: MAX_VISIBLE = 10
16
+    integer, parameter :: PALETTE_WIDTH = 60  ! Fixed width for centered palette
16
 
17
 
17
     type :: command_t
18
     type :: command_t
18
         character(len=:), allocatable :: name
19
         character(len=:), allocatable :: name
@@ -291,37 +292,65 @@ contains
291
         end select
292
         end select
292
     end subroutine command_palette_handle_key
293
     end subroutine command_palette_handle_key
293
 
294
 
294
-    subroutine render_command_palette(palette, screen_rows)
295
+    subroutine render_command_palette(palette, screen_rows, screen_cols)
295
         type(command_palette_t), intent(in) :: palette
296
         type(command_palette_t), intent(in) :: palette
296
-        integer, intent(in) :: screen_rows
297
+        integer, intent(in) :: screen_rows, screen_cols
297
-        integer :: i, visible_start, visible_end, row
298
+        integer :: i, visible_start, visible_end, row, start_col, start_row
299
+        integer :: content_width, display_width
298
         character(len=256) :: line, category_tag
300
         character(len=256) :: line, category_tag
299
         type(command_t) :: cmd
301
         type(command_t) :: cmd
300
-
302
+        character(len=:), allocatable :: border_top, border_bottom
301
-        ! Clear and draw header
303
+        ! ANSI escape codes
302
-        call terminal_move_cursor(screen_rows - MAX_VISIBLE - 2, 1)
304
+        character(len=*), parameter :: ESC = char(27)
303
-        call terminal_write(repeat(' ', 80))
305
+        character(len=*), parameter :: CYAN = ESC // '[36m'
304
-        call terminal_move_cursor(screen_rows - MAX_VISIBLE - 2, 1)
306
+        character(len=*), parameter :: YELLOW = ESC // '[33m'
305
-        call terminal_write('Command Palette (type to search, Esc to cancel)')
307
+        character(len=*), parameter :: INVERSE = ESC // '[7m'
306
-
308
+        character(len=*), parameter :: RESET = ESC // '[0m'
307
-        ! Draw search query
309
+
308
-        call terminal_move_cursor(screen_rows - MAX_VISIBLE - 1, 1)
310
+        ! Calculate centering - top-center like VSCode
309
-        call terminal_write(repeat(' ', 80))
311
+        content_width = min(PALETTE_WIDTH, screen_cols - 4)
310
-        call terminal_move_cursor(screen_rows - MAX_VISIBLE - 1, 1)
312
+        start_col = max(1, (screen_cols - content_width) / 2)
311
-        call terminal_write('> ' // trim(palette%search_query))
313
+        start_row = 2  ! Start near top (below tab bar if present)
314
+
315
+        ! Build border strings
316
+        border_top = '┌' // repeat('─', content_width - 2) // '┐'
317
+        border_bottom = '└' // repeat('─', content_width - 2) // '┘'
318
+
319
+        ! Draw top border
320
+        call terminal_move_cursor(start_row, start_col)
321
+        call terminal_write(border_top)
322
+
323
+        ! Draw header line with cyan title
324
+        row = start_row + 1
325
+        call terminal_move_cursor(row, start_col)
326
+        call terminal_write('│' // CYAN // ' Command Palette' // RESET)
327
+        display_width = 17  ! " Command Palette" length
328
+        call terminal_write(repeat(' ', content_width - display_width - 2) // '│')
329
+
330
+        ! Draw search query line with yellow prompt
331
+        row = row + 1
332
+        call terminal_move_cursor(row, start_col)
333
+        call terminal_write('│' // YELLOW // ' > ' // RESET)
334
+        call terminal_write(trim(palette%search_query))
335
+        display_width = 3 + len_trim(palette%search_query)
336
+        call terminal_write(repeat(' ', content_width - display_width - 2) // '│')
337
+
338
+        ! Draw separator
339
+        row = row + 1
340
+        call terminal_move_cursor(row, start_col)
341
+        call terminal_write('├' // repeat('─', content_width - 2) // '┤')
312
 
342
 
313
         ! Calculate visible range
343
         ! Calculate visible range
314
         visible_start = palette%scroll_offset + 1
344
         visible_start = palette%scroll_offset + 1
315
         visible_end = min(visible_start + MAX_VISIBLE - 1, palette%num_filtered)
345
         visible_end = min(visible_start + MAX_VISIBLE - 1, palette%num_filtered)
316
 
346
 
317
         ! Draw commands
347
         ! Draw commands
318
-        row = screen_rows - MAX_VISIBLE
319
         do i = visible_start, visible_end
348
         do i = visible_start, visible_end
349
+            row = row + 1
320
             cmd = palette%filtered_commands(i)
350
             cmd = palette%filtered_commands(i)
321
 
351
 
322
-            call terminal_move_cursor(row, 1)
352
+            call terminal_move_cursor(row, start_col)
323
-            call terminal_write(repeat(' ', 80))
353
+            call terminal_write('│')
324
-            call terminal_move_cursor(row, 1)
325
 
354
 
326
             ! Build line with category, name, and shortcut
355
             ! Build line with category, name, and shortcut
327
             if (len_trim(cmd%category) > 0) then
356
             if (len_trim(cmd%category) > 0) then
@@ -330,37 +359,46 @@ contains
330
                 category_tag = ''
359
                 category_tag = ''
331
             end if
360
             end if
332
 
361
 
333
-            if (i == palette%selected_index) then
362
+            write(line, '(A,A,A)') ' ', trim(category_tag), trim(cmd%name)
334
-                ! Highlight selected item
335
-                write(line, '(A,A,A)') '> ', trim(category_tag), trim(cmd%name)
336
-            else
337
-                write(line, '(A,A,A)') '  ', trim(category_tag), trim(cmd%name)
338
-            end if
339
 
363
 
340
             ! Add shortcut if available
364
             ! Add shortcut if available
341
             if (len_trim(cmd%shortcut) > 0) then
365
             if (len_trim(cmd%shortcut) > 0) then
342
-                write(line, '(A,A,A)') trim(line), ' (', trim(cmd%shortcut) // ')'
366
+                write(line, '(A,A,A)') trim(line), '  ', trim(cmd%shortcut)
343
             end if
367
             end if
344
 
368
 
345
-            call terminal_write(trim(line))
369
+            ! Truncate if too long
346
-            row = row + 1
370
+            display_width = min(len_trim(line), content_width - 3)
371
+
372
+            if (i == palette%selected_index) then
373
+                ! Highlight selected item with inverse colors
374
+                call terminal_write(INVERSE // line(1:display_width))
375
+                call terminal_write(repeat(' ', content_width - display_width - 2) // RESET // '│')
376
+            else
377
+                call terminal_write(line(1:display_width))
378
+                call terminal_write(repeat(' ', content_width - display_width - 2) // '│')
379
+            end if
347
         end do
380
         end do
348
 
381
 
349
-        ! Clear remaining lines
382
+        ! Fill remaining visible slots with empty rows
350
-        do while (row <= screen_rows)
383
+        do i = visible_end + 1, visible_start + MAX_VISIBLE - 1
351
-            call terminal_move_cursor(row, 1)
352
-            call terminal_write(repeat(' ', 80))
353
             row = row + 1
384
             row = row + 1
385
+            call terminal_move_cursor(row, start_col)
386
+            call terminal_write('│' // repeat(' ', content_width - 2) // '│')
354
         end do
387
         end do
355
 
388
 
356
-        ! Position cursor at end of search query
389
+        ! Draw bottom border
357
-        call terminal_move_cursor(screen_rows - MAX_VISIBLE - 1, 3 + palette%search_pos)
390
+        row = row + 1
391
+        call terminal_move_cursor(row, start_col)
392
+        call terminal_write(border_bottom)
393
+
394
+        ! Position cursor at end of search query (inside the box)
395
+        call terminal_move_cursor(start_row + 2, start_col + 4 + palette%search_pos)
358
     end subroutine render_command_palette
396
     end subroutine render_command_palette
359
 
397
 
360
-    function show_command_palette_interactive(palette, screen_rows) result(selected_cmd_id)
398
+    function show_command_palette_interactive(palette, screen_rows, screen_cols) result(selected_cmd_id)
361
         use input_handler_module, only: get_key_input
399
         use input_handler_module, only: get_key_input
362
         type(command_palette_t), intent(inout) :: palette
400
         type(command_palette_t), intent(inout) :: palette
363
-        integer, intent(in) :: screen_rows
401
+        integer, intent(in) :: screen_rows, screen_cols
364
         character(len=:), allocatable :: selected_cmd_id
402
         character(len=:), allocatable :: selected_cmd_id
365
         character(len=32) :: key_input
403
         character(len=32) :: key_input
366
         integer :: ch, status
404
         integer :: ch, status
@@ -368,7 +406,7 @@ contains
368
         type(command_t) :: cmd
406
         type(command_t) :: cmd
369
 
407
 
370
         call show_command_palette(palette)
408
         call show_command_palette(palette)
371
-        call render_command_palette(palette, screen_rows)
409
+        call render_command_palette(palette, screen_rows, screen_cols)
372
 
410
 
373
         do
411
         do
374
             call get_key_input(key_input, status)
412
             call get_key_input(key_input, status)
@@ -406,7 +444,7 @@ contains
406
                 end if
444
                 end if
407
             end if
445
             end if
408
 
446
 
409
-            call render_command_palette(palette, screen_rows)
447
+            call render_command_palette(palette, screen_rows, screen_cols)
410
         end do
448
         end do
411
     end function show_command_palette_interactive
449
     end function show_command_palette_interactive
412
 
450