@@ -40,6 +40,8 @@ contains |
| 40 | 40 | integer :: left_w, i, parent_idx, current_idx, vis_h, display_len |
| 41 | 41 | character(len=256) :: fname |
| 42 | 42 | character(len=20) :: color_code |
| 43 | + character(len=600) :: footer_text |
| 44 | + integer :: footer_len |
| 43 | 45 | |
| 44 | 46 | left_w = c * 3 / 10 |
| 45 | 47 | vis_h = r - top_padding - 4 ! Visible height with buffer to prevent scrolling |
@@ -227,18 +229,28 @@ contains |
| 227 | 229 | end do |
| 228 | 230 | |
| 229 | 231 | ! Footer - help text only (status moved to header) |
| 232 | + ! Build footer text and truncate to prevent wrapping which causes screen scroll |
| 230 | 233 | if (move_mode) then |
| 231 | | - write(output_unit, '(a)') DIM // "↑↓:next/prev dir →:enter dir ←:parent ~:home /:root v:move here q:cancel" // RESET |
| 234 | + footer_text = DIM // "↑↓:next/prev dir →:enter dir ←:parent ~:home /:root v:move here q:cancel" // RESET |
| 232 | 235 | else if (selection_count > 0) then |
| 233 | | - ! Selection mode footer - show multi-select help |
| 234 | | - write(output_unit, '(a)') DIM // "Ctrl-D:deselect Space:toggle Shift+↑↓:block y:copy x:cut p:paste r:delete | " // RESET // & |
| 235 | | - DIM // "→:enter ←:back ~:home /:root c:cd q:quit" // RESET |
| 236 | + footer_text = DIM // "Ctrl-D:deselect Space:toggle Shift+↑↓:block y:copy x:cut p:paste r:delete | " // RESET // & |
| 237 | + DIM // "→:enter ←:back ~:home /:root c:cd q:quit" // RESET |
| 236 | 238 | else if (in_git_repo) then |
| 237 | | - write(output_unit, '(a)') DIM // "Space:select Shift+↑↓:block | ↑↓:nav →:enter ←:back ~:home /:root s:search 8:favorites *:star o:open n:rename r:remove v:move y:copy x:cut p:paste .:hidden a:add u:unstage m:commit d:diff f:fetch l:pull h:push c:cd q:quit" // RESET |
| 239 | + footer_text = DIM // "Space:select Shift+↑↓:block | ↑↓:nav →:enter ←:back ~:home /:root s:search 8:favorites *:star o:open n:rename r:remove v:move y:copy x:cut p:paste .:hidden a:add u:unstage m:commit d:diff f:fetch l:pull h:push c:cd q:quit" // RESET |
| 238 | 240 | else |
| 239 | | - write(output_unit, '(a)') DIM // "Space:select Shift+↑↓:block | ↑↓:nav →:enter ←:back ~:home /:root s:search 8:favorites *:star o:open n:rename r:remove v:move y:copy x:cut p:paste .:hidden c:cd q:quit" // RESET |
| 241 | + footer_text = DIM // "Space:select Shift+↑↓:block | ↑↓:nav →:enter ←:back ~:home /:root s:search 8:favorites *:star o:open n:rename r:remove v:move y:copy x:cut p:paste .:hidden c:cd q:quit" // RESET |
| 240 | 242 | end if |
| 241 | 243 | |
| 244 | + ! Truncate footer to terminal width - CRITICAL to prevent wrapping which causes screen scroll |
| 245 | + ! Conservative truncation: assume ANSI codes are ~30% of string, so truncate to ~130% of terminal width |
| 246 | + footer_len = len_trim(footer_text) |
| 247 | + if (footer_len > (c * 13 / 10)) then |
| 248 | + footer_text = footer_text(1:c * 13 / 10) |
| 249 | + end if |
| 250 | + |
| 251 | + ! Write footer WITHOUT newline (newline on last row causes wrap which scrolls screen up) |
| 252 | + write(output_unit, '(a)', advance='no') trim(footer_text) |
| 253 | + |
| 242 | 254 | contains |
| 243 | 255 | function itoa(n) result(str) |
| 244 | 256 | integer, intent(in) :: n |