Implements the App side of T5 (toast notifications from the bottom/tlc
synthesis). render_toast() overlay can be wired in a follow-up pass.
- App.toast: Option<String> field
- App.toast_expires: Option<Instant> field
- App.flash_toast(msg): sets toast with 3s auto-dismiss
- App.active_toast(): returns &str if not expired
Key bindings: scrollable help dialog (j/k/PgUp/PgDn/Home/G) wired in
the previous round. dim_backdrop/render_nice_edit/render_open_files
helpers lost to repeated reverts — will be re-added in a clean follow-up.
Press Tab in the cmdline to complete the current word as a
path/filename. Completion resolves against the active panel's
current directory (stored in Cmdline::base_dir when the
cmdline is activated).
- Cmdline::complete(base_dir) extends the input to the
longest common prefix of all matching entries. If there's
only one match, appends a trailing slash.
- Cmdline::set_base_dir(path) is called by dispatch when the
Cmdline Cmd is dispatched.
- Tab key in Cmdline::handle_key calls complete(self.base_dir).
Added 1 unit test verifying LCP extension for partial prefix.
Tests: 1401 pass (was 1400), zero warnings.
Append a '● N marked' badge to the active panel's border title
when files are selected, using the accent colour for visibility.
Makes the selection count visible even when the footer row is
hidden (e.g. on very short panels).
Tests: 1400 pass, zero warnings.
Add a 10-cell log2-bucketed histogram showing file-size
distribution across the directory. Each cell is the count of
files in a bucket (1B..1KiB, 1KiB..2KiB, ... >=512GiB) scaled to
a 0..8 block-char level. Rendered in accent colour next to
the existing per-file size bar.
- size_histogram() returns [u64; 10] counts per bucket
- Uses u64 leading_zeros trick for O(1) log2 size
- Skips directories and the '..' entry
- Directories are excluded from the histogram
- Renders after the cursor file's size bar
Added 1 unit test verifying bucket placement for 2B and 16KiB.
Tests: 1400 pass (was 1399), zero warnings.
The viewer's ensure_cursor_visible scrolled the cursor to the
exact top or bottom edge of the viewport. Add a 2-line context
margin so the cursor sits 2 lines from the top (when scrolling
down) or 2 lines from the bottom (when scrolling up). Premium
polish — keeps the surrounding lines visible for context.
Tests: 1399 pass, zero warnings.
Similar to the search history (W31), the goto-line prompt now
keeps a history of recently-visited line numbers. Up/Down arrows
cycle through the history; Down past the newest entry clears
back to the live input.
- Editor::goto_history: Vec<u32> field (max 50 entries)
- Editor::goto_history_cursor: Option<usize> navigation position
- Editor::push_goto_history(line) / goto_history_up() /
goto_history_down() / reset_goto_history_cursor()
- GotoLine prompt commit pushes the line to history
- Up/Down arrows in the GotoLine prompt cycle through history
- push_goto_history skips consecutive duplicates
Added 2 unit tests covering: walk backwards/forwards, dedup.
Tests: 1399 pass (was 1397), zero warnings.
When the editor mode changes (e.g. Esc → Normal, i → Insert),
the mode tag in the status bar flashes to the accent colour
for ~300ms. Provides instant visual feedback for mode changes.
- Editor::mode_flash: Option<Instant> field
- Editor::trigger_mode_flash() / mode_flash_progress()
- Editor::set_mode() helper that triggers the flash on actual
mode changes (no-op when setting the same mode)
- All self.mode = Mode::* sites in handlers.rs updated to use
set_mode() so the flash triggers consistently
- status_spans uses accent + cursor_fg for the mode tag while
the flash is active
Added 1 unit test verifying flash triggers on mode change and
NOT on setting the same mode.
Tests: 1397 pass (was 1396), zero warnings.
Append a 'N% free' indicator to the active panel's border
title using the existing disk_free() helper. Inactive panels
keep the plain path-only title. The percentage is shown as
an integer (0-100) which fits comfortably in the border even
on narrow terminals.
Tests: 1396 pass, zero warnings.
MC has search history navigation in the find prompt via arrow
keys. TLC's SearchState already had a history() list but no
way to navigate it without using the Alt-/ popup.
Add history_up() / history_down() / reset_history_cursor() to
SearchState. Wire Up/Down in the Find/Replace prompt to cycle
through the history. Down past the newest entry clears the
prompt back to the live pattern.
Added 3 unit tests covering: walk backwards, walk forward with
stop signal, empty history.
Tests: 1396 pass (was 1393), zero warnings.
The existing bracket_flash only triggered when the cursor was
ON a bracket character. This meant that after typing a closing
bracket (the most common trigger scenario), the cursor sits
AFTER the bracket and the flash doesn't fire.
Update update_bracket_flash to also check the character BEFORE
the cursor (pos - 1) and use it as a fallback. The pair position
is adjusted accordingly (the match is at pos - 1 for the before-
cursor case).
Tests: 1393 pass, zero warnings.
The F9 audit found that Cmd::OptionsConfirm was a single-boolean
toggle (cycle on/off) instead of MC's proper confirmation dialog
with per-operation checkboxes. The ConfirmDialog already existed
in confirm_dialog.rs with 4 toggles (delete, overwrite, execute,
exit) but wasn't wired into the F9 menu.
Wire the existing ConfirmDialog:
- DialogState::Confirm(Box<ConfirmDialog>) variant
- Cmd::OptionsConfirm now opens the dialog pre-populated with
the current safe_delete / safe_execute settings
- Dispatch handler processes ConfirmResult::Confirm by saving the
settings to runtime.safe_delete / safe_execute
- Added RuntimeConfig::safe_execute field with default Some(false)
- Added dialog_title() and render() arms for DialogState::Confirm
Tests: 1393 pass, zero warnings.
The F9 audit found the editor had no Format menu at all. MC
has a dedicated Format menu with paragraph format, sort,
insert date/time, and external formatter entries.
Add a Format menu to the editor F9 menubar with 'Format paragraph'
(wired to the existing Editor::format_paragraph method, also
reachable via Alt-P). Sort, insert date/time, and external
formatter are documented as follow-ups.
- EditorCmd::FormatParagraph variant
- dispatch_editor_cmd handles it by calling format_paragraph()
- Format menu inserted between Edit and Search in the menubar
Updated 2 existing tests that counted menus (6→7) and checked
menu index (2→3 for Search after Format).
Tests: 1393 pass, zero warnings.
The F9 audit found that the Panel menu (Left/Right) was missing
the MC-style VFS link entries (FTP link..., Shell link...,
SFTP link...). The ConnectionDialog already supported all three
kinds but the user could only reach them via the catch-all
Cmd::Connection which defaulted to FTP.
Add three new Cmd variants (ConnectFtp, ConnectShell, ConnectSftp)
that each open the ConnectionDialog pre-set to the matching
ConnectionKind. Wire them into the Panel menu (Left/Right)
between 'External panelize' and 'Reload', separated by a
separator so the group reads as a VFS submenu.
Tests: 1393 pass, zero warnings.
Press F9 in the viewer to toggle the menubar at the top of the
viewer. The menubar occupies the top row, and the viewer content
shifts down by 1 row when the menubar is open.
- Viewer::menubar: Option<ViewerMenuBar> field
- Viewer::render: calls mb.render() at the top when menubar is open
- Viewer::handle_key: F9 toggles, other keys route to menubar when open
- Viewer::execute_menubar_cmd: dispatches ViewerCmd to existing
viewer methods (ToggleHex, ToggleMagic, ToggleWrap, ToggleGrowing,
Search, SearchNext, SearchPrev, Goto)
Bookmark / file navigation / close commands are documented as a
planned follow-up — still reachable via their keyboard shortcuts.
Tests: 1393 pass, zero warnings.
Add a 6-cell mini-gauge at the right edge of the cursor row that
shows the cursor file's size as a fraction of the largest file
in the current directory. Uses block characters (filled/empty)
in the accent colour over the cursor background. Only renders
for non-directory entries on the active panel, so directories
and the '..' parent entry skip the gauge.
This gives an instant visual sense of relative file sizes
without needing to read the numeric size column.
Tests: 1388 pass, zero warnings.
Show the free-space percentage next to the disk indicator dot
so the user can quickly assess remaining capacity without doing
mental math from the size string.
Tests: 1388 pass, zero warnings.
Add a bright accent-coloured 1-column bar on the inner left edge
of the active panel. This is a premium TUI pattern (also used by
bottom, lazygit, btop) that gives a much clearer visual focus
indicator than a border colour change alone.
The bar uses the same active_border_color as the panel border so
it stays thematically consistent. The panel inner content shifts
right by one column to accommodate the bar without losing content.
Tests: 1388 pass, zero warnings.
When a critical operation fails (chmod/chown/rmdir/view), the status
line pulses its background between status_bg and theme.error for 400ms.
This gives the user immediate visual confirmation that something went
wrong, even if the message text is short or they aren't looking at
the status bar.
- StatusLine::set_error() — sets message + triggers flash
- StatusLine::error_flash_progress() — remaining fraction (0.0..=1.0)
- blend_bg() — RGB linear interpolation between two Color values
- rgb() — named-color → RGB tuple for interpolation
Wired into 4 critical error paths in dialog_ops.rs (chmod, chown,
rmdir, view). Other transient messages continue to use set_message().
Tests: 1388 pass (was 1384), zero warnings.
MC parity audit found 4 semantic bugs in dispatch_ctrl_x_followup:
l -> Link (hard link, was Cmd::Symlink)
s -> Symlink (absolute symlink, was Cmd::SymlinkRelative)
v -> SymlinkRelative (relative symlink, was Cmd::SymlinkEdit)
Added 2 ctrl+letter chord entries:
ctrl-s -> SymlinkEdit (edit symlink)
ctrl-p -> InsertOtherPath (insert other panel path)
Added 3 chord aliases for MC-compatibility:
p -> InsertCurPath (MC's PutCurrentPath)
r -> InsertCurFile (MC's PutCurrentLink)
ctrl-d, ctrl-s, ctrl-p handled via modifier check
Tests: 1381 pass, zero warnings.
Add 'Charset: UTF-8' to the editor status bar (TLC is UTF-8 native).
Upgrade status bar from a single-styled Span to a multi-segment Line
with per-segment accent colours so the status reads at a glance:
- modified flag: warning colour (bold)
- filename: accent colour
- position (Ln/Col): info colour
- tab/charset/eol labels: dim shadow colour
- mode tag: warning colour
Tests: 1381 pass, zero warnings.