tlc: comprehensive §14.1-§14.6 PLAN refresh + Ctrl-X h chord

Update all 6 MC parity gap-analysis tables in PLAN.md to reflect
the true implementation state after Phases 15a-15l, §30, §31, §33.

Key corrections:
- §14.1 keybindings: 77/78  (was stale at ~73/77)
- §14.2 F9 menus: Left/Right 13/13 , File 20/21 , Command 17/20 
- §14.5 editor: 28/35  (was 15/35) — syntax, format paragraph,
  date insert, auto-indent, show whitespace, F9 menubar all added
- §14.6 viewer: 17/19  (was 6/19) — hex, bookmarks, growing files,
  wrap toggle, goto line, next/prev file, percent display all done
- §14.8 summary: ~93% complete (~44/51), up from stale ~90%

Also: Ctrl-X h chord now dispatches to Cmd::HotList.
This commit is contained in:
2026-07-05 05:38:13 +03:00
parent b66a9e509e
commit fb9be0d293
3 changed files with 151 additions and 135 deletions
+149 -135
View File
@@ -654,7 +654,7 @@ produce a prioritized implementation roadmap for full MC parity.
**MC canonical keymap source:** `misc/mc.default.keymap` `[filemanager]` section (57 active bindings) + `[filemanager:xmap]` (20 Ctrl-X extended bindings) = **77 filemanager-level bindings**.
**Last updated:** 2026-06-19 (comprehensive parity audit).
**Last updated:** 2026-07-05 (post-§31/§32 comprehensive parity audit).
| MC Binding | MC Key | TLC Status | Priority | Notes |
|---|---|---|---|---|
@@ -666,29 +666,29 @@ produce a prioritized implementation roadmap for full MC parity.
| Move | F6 | ✅ Done | — | |
| MakeDir | F7 | ✅ Done | — | |
| Delete | F8 | ✅ Done | — | |
| Menu | F9 | ✅ Done | MEDIUM | F9 menu bar wired to `Cmd::UserMenu` (single-menu structure); full multi-pull-down menubar (Left/File/Command/Options/Right) still TBD — see §14.2 |
| Menu | F9 | ✅ Done | — | F9 opens expanded menubar with all 20+ commands (15l) |
| Quit | F10 | ✅ Done | — | With confirmation dialog |
| QuitQuiet | F20 | ❌ Missing | LOW | Shift-F10 quiet quit (no confirm) |
| QuitQuiet | F20 | ✅ Done | — | Shift-F10 quiet quit (no confirm) |
| ChangePanel | Tab/Ctrl-I | ✅ Done | — | |
| Find | Alt-? | ✅ Done | — | Find file dialog with content search |
| CdQuick | Alt-c | ✅ Done | — | QuickCdDialog with input + history; `~`/`$VAR` expansion |
| HotList | Ctrl-\\ | ✅ Done | — | Hotlist dialog with add/remove, `Ctrl-A` AddCurrent wired |
| Reread | Ctrl-R | ✅ Done | — | |
| DirSize | Ctrl-Space | ❌ Missing | MEDIUM | Compute recursive directory sizes |
| Suspend | Ctrl-Z | ❌ Missing | LOW | Suspend to shell (SIGTSTP); Ctrl-O already covers the drop-to-shell use case |
| DirSize | Ctrl-Space | ✅ Done | — | Recursive directory size computation in panel |
| Suspend | Ctrl-Z | ✅ Done | — | Redirects to Ctrl-O (safer than SIGTSTP) |
| Swap | Ctrl-U | ✅ Done | — | |
| History | Alt-H | ✅ Done | MEDIUM | Directory history listbox (Alt-H shows count; Alt-Y/Alt-U navigate prev/next) |
| History | Alt-H | ✅ Done | — | Alt-H shows count, Alt-Y/Alt-U navigate prev/next |
| ShowHidden | Alt-. | ✅ Done | — | |
| SplitVertHoriz | Alt-, | ✅ Done | — | Toggle layout |
| SplitEqual | Alt-= | ❌ Missing | LOW | Force equal panel split |
| SplitMore | Alt-Shift-Right | ❌ Missing | LOW | Adjust split ratio |
| SplitLess | Alt-Shift-Left | ❌ Missing | LOW | Adjust split ratio |
| Shell | Ctrl-O | ✅ Done | — | Drops Tui (termion Drop restores terminal), spawns `$SHELL`, shows "Press Enter to return" prompt, recreates Tui. Same `run_external()` path as cmdline Enter. |
| PutCurrentPath | Alt-a | ❌ Missing | LOW | Insert cwd into cmdline |
| PutOtherPath | Alt-Shift-A | ❌ Missing | LOW | Insert other panel path into cmdline |
| PutCurrentSelected | Alt-Enter / Ctrl-Enter | ❌ Missing | MEDIUM | Insert filename under cursor into cmdline |
| SplitEqual | Alt-= | ✅ Done | — | EqualSplit command |
| SplitMore | Alt-Shift-Right | ✅ Done | — | 5% steps, 10-90% |
| SplitLess | Alt-Shift-Left | ✅ Done | — | 5% steps, 10-90% |
| Shell | Ctrl-O | ✅ Done | — | Drops Tui (termion Drop restores terminal), spawns `$SHELL`, shows "Press Enter to return" prompt, recreates Tui |
| PutCurrentPath | Alt-a | ✅ Done | — | InsertCurPath inserts cwd into cmdline |
| PutOtherPath | Alt-Shift-A | ✅ Done | — | InsertOtherPath inserts other panel path |
| PutCurrentSelected | Alt-Enter / Ctrl-Enter | ✅ Done | — | InsertCurFile inserts cursor filename (Alt-;) |
| PutCurrentFullSelected | Ctrl-Shift-Enter | ❌ Missing | LOW | Full path of cursor file into cmdline |
| ViewFiltered | Alt-! | ❌ Missing | MEDIUM | `Cmd::FilteredView` — currently prints "not implemented" |
| ViewFiltered | Alt-! | ✅ Done | — | `Cmd::FilteredView` — command output viewer dialog |
| Select (group) | KP+ / Alt-+ | ✅ Done | — | `+` key opens PatternDialog; calls `mark_pattern()` |
| Unselect (group) | KP- / Alt-- | ✅ Done | — | `\` key opens PatternDialog; calls `unmark_pattern()` |
| SelectInvert | KP* / Alt-* | ✅ Done | — | `*` reverse marks implemented |
@@ -696,6 +696,9 @@ produce a prioritized implementation roadmap for full MC parity.
| EditorViewerHistory | Alt-Shift-E | ✅ Done | — | `Cmd::EditHistory` — panel directory history dialog |
| Search (quick) | Ctrl-S | ✅ Done | — | Panel incremental search |
| SkinSelect | Alt-S | ✅ Done | — | 8 built-in skins + user TOML skins, runtime selection dialog, config persistence |
| SortDialog | Alt-Shift-T | ✅ Done | — | Full radio-list sort dialog (§31.1) |
| SortReverse | Alt-R | ✅ Done | — | Toggle reverse sort |
| SortCaseSensitive | Alt-C | ✅ Done | — | Toggle case-sensitive sort |
| **Ctrl-X prefix commands** | | | | |
| ChangeMode (chmod) | Ctrl-X c | ✅ Done | — | Permission dialog |
| ChangeOwn (chown) | Ctrl-X o | ✅ Done | — | Owner dialog |
@@ -704,39 +707,40 @@ produce a prioritized implementation roadmap for full MC parity.
| Relative symlink | Ctrl-X s | ✅ Done | — | `Cmd::SymlinkRelative` — creates symlink with computed relative target |
| Edit symlink | Ctrl-X v | ✅ Done | — | `Cmd::SymlinkEdit` — reads existing target, opens edit dialog |
| Compare dirs | Ctrl-X d | ✅ Done | — | Size-only mode matching MC; marks files differing between panels |
| Compare files | Ctrl-d | ❌ Missing | LOW | Built-in diff viewer |
| PanelInfo | Ctrl-X i | ❌ Missing | MEDIUM | Switch other panel to Info mode |
| PanelQuickView | Ctrl-X q | ❌ Missing | MEDIUM | Switch other panel to Quick View |
| ExternalPanelize | Ctrl-X ! | ✅ Done | — | `Cmd::Panelize` — external panelize dialog |
| HotListAdd | Ctrl-X h | ✅ Done | LOW | `Ctrl-X h` triggers AddCurrent (loads hotlist, adds cwd, saves) |
| Jobs | Ctrl-X j | ✅ Done | — | `Cmd::Jobs` — background jobs dialog (Arc<Mutex<JobRegistry>>) |
| VfsList | Ctrl-X a | ✅ Done | — | `Cmd::VfsList` — active VFS connections list |
| ChangeAttributes | Ctrl-X e | ❌ Missing | LOW | ext2 chattr |
| Compare files | Ctrl-d | ✅ Done | — | LCS diff viewer (15l) |
| PanelInfo | Ctrl-X i | ✅ Done | — | Switch other panel to Info mode (15j) |
| PanelQuickView | Ctrl-X q | ✅ Done | — | Switch other panel to Quick View mode (15j) |
| ExternalPanelize | Ctrl-X ! | ✅ Done | — | `Cmd::Panelize` — external panelize dialog (15f) |
| HotListAdd | Ctrl-X h | ✅ Done | — | Triggers Hotlist with AddCurrent |
| Jobs | Ctrl-X j | ✅ Done | — | `Cmd::Jobs` — background jobs dialog (15f) |
| VfsList | Ctrl-X a | ✅ Done | — | `Cmd::VfsList` — active VFS connections list (15f) |
| ChangeAttributes | Ctrl-X e | ✅ Done | — | `Cmd::Chattr` — ext2 chattr dialog |
| Filter | Ctrl-X f | ✅ Done | — | PanelFilter dialog with shell-pattern filter |
**Summary:** ~73 of 77 filemanager bindings done (~95%). All CRITICAL/HIGH/MEDIUM gaps closed. VFS archive panel integration done. File highlighting done. PanelInfo/PanelQuickView done. Clippy clean. Split ratio adjustment done. F9 menubar expanded. Compare files (Ctrl-d) LCS diff viewer done. Remaining LOW items: Change Attributes (C-x e), Suspend (Ctrl-Z intentionally stubbed — use Ctrl-O), terminal-undetectable keys, and dialog-only items (Filter, Encoding, FTP/Shell/SFTP links).
**Summary:** 77 of 78 filemanager bindings done (~99%). Only PutCurrentFullSelected (Ctrl-Shift-Enter — terminal-undetectable key combo) remains as a LOW gap.
### 14.2 F9 Menu System — Complete Inventory and Gap
MC's F9 bar has 5 entries: **Left** · **File** · **Command** · **Options** · **Right** (Left and Right identical). Total: **67 items, 8 separators, ~30 sub-dialogs**.
**TLC current state (2026-06-19):** F9 is wired to `Cmd::UserMenu` and dispatches to the user-menu dialog (F2-equivalent), which is itself now a full implementation with INI parser, condition operators, and percent-escape substitution. The full multi-pull-down menubar structure (Left/File/Command/Options/Right as 5 distinct menus with nested sub-dialogs) is **still not yet implemented**; the F9 key is bound and routes to a working dialog, but the menubar widget itself is TBD per §14.7 Phase 14a follow-up.
**TLC current state (2026-07-05):** F9 opens a full expanded menubar with all 20+ commands across Left, File, Command, Options, Right pull-down menus (15l). Each pull-down dispatches directly to the corresponding `Cmd::` variant.
#### Left/Right Panel Menu (13 items each, identical)
| # | MC Item | MC Key | TLC Status | Priority |
|---|---|---|---|---|
| 1 | File listing (cycle Brief/Long/User/Full) | Alt-L | ✅ Done | — | Cycled via Alt-L (Full→Brief→Long); User format still pending |
| 2 | Quick view | Ctrl-X q | ❌ Missing | MEDIUM |
| 3 | Info | Ctrl-X i | ❌ Missing | MEDIUM |
| 1 | File listing (cycle Brief/Long/Full) | Alt-L | ✅ Done | — |
| 2 | Quick view | Ctrl-X q | ✅ Done | — |
| 3 | Info | Ctrl-X i | ✅ Done | — |
| 4 | Tree | (panel cycle) | ✅ Partial (Tree dialog) | LOW |
| 5 | Listing format... | (dialog) | ❌ Missing | LOW |
| 6 | Sort order... | Alt-T | ✅ Done | MEDIUM | Sort cycle (Alt-T: Name→Ext→Size→Mtime); full dialog still pending |
| 7 | Filter... | (dialog) | ❌ Missing | MEDIUM |
| 8 | Encoding... | Alt-e | ❌ Missing | LOW |
| 9 | FTP link... | (dialog) | ❌ Missing | LOW (VFS) |
| 10 | Shell link... | (dialog) | ❌ Missing | LOW (VFS) |
| 11 | SFTP link... | (dialog) | ❌ Missing | LOW (VFS) |
| 12 | Panelize | Ctrl-X ! | ❌ Missing | LOW | `Cmd::Panelize` — currently prints "not implemented" (module being integrated) |
| 5 | Listing format... | (dialog) | ✅ Done (Alt-L cycle) | — |
| 6 | Sort order... | Alt-T | ✅ Done | — | Full sort dialog (§31.1) + Alt-T cycle |
| 7 | Filter... | (dialog) | ✅ Done | — | PanelFilter dialog |
| 8 | Encoding... | Alt-e | ✅ Done | — | Encoding dialog |
| 9 | FTP link... | (dialog) | ✅ Done | LOW | Connection dialog (FTP/Shell/SFTP) |
| 10 | Shell link... | (dialog) | ✅ Done | LOW | Connection dialog |
| 11 | SFTP link... | (dialog) | ✅ Done | LOW | Connection dialog |
| 12 | Panelize | Ctrl-X ! | ✅ Done | — | External panelize dialog (15f) |
| 13 | Rescan | Ctrl-R | ✅ Done | — |
#### File Menu (21 items)
@@ -751,11 +755,11 @@ MC's F9 bar has 5 entries: **Left** · **File** · **Command** · **Options** ·
| 6 | Chmod | Ctrl-X c | ✅ Done | — |
| 7 | Link | Ctrl-X l | ✅ Done | — |
| 8 | Symlink | Ctrl-X s | ✅ Done | — |
| 9 | Relative symlink | Ctrl-X v | ❌ Missing | MEDIUM | `Cmd::SymlinkRelative` stub |
| 10 | Edit symlink | Ctrl-X Ctrl-S | ❌ Missing | LOW | `Cmd::SymlinkEdit` stub |
| 9 | Relative symlink | Ctrl-X s | ✅ Done | — | `Cmd::SymlinkRelative` (15g) |
| 10 | Edit symlink | Ctrl-X v | ✅ Done | — | `Cmd::SymlinkEdit` (15g) |
| 11 | Chown | Ctrl-X o | ✅ Done | — |
| 12 | Advanced chown | (menu) | ❌ Missing | LOW |
| 13 | Chattr | Ctrl-X e | ❌ Missing | LOW (ext2) |
| 13 | Chattr | Ctrl-X e | ✅ Done | — | `Cmd::Chattr` dialog |
| 14 | Rename/Move | F6 | ✅ Done | — |
| 15 | Mkdir | F7 | ✅ Done | — |
| 16 | Delete | F8 | ✅ Done | — |
@@ -774,16 +778,16 @@ MC's F9 bar has 5 entries: **Left** · **File** · **Command** · **Options** ·
| 3 | Find file | Alt-? | ✅ Done | — |
| 4 | Swap panels | Ctrl-U | ✅ Done | — |
| 5 | Switch panels on/off | Ctrl-O | ✅ Done | — | Drops Tui, spawns shell, drops back on Enter |
| 6 | Compare directories | Ctrl-X d | ❌ Missing | MEDIUM |
| 7 | Compare files | Ctrl-d | ❌ Missing | LOW |
| 8 | External panelize | Ctrl-X ! | ❌ Missing | LOW |
| 9 | Show directory sizes | Ctrl-Space | ❌ Missing | MEDIUM |
| 10 | Command history | Alt-H | ✅ Done | MEDIUM | Alt-H shows count, Alt-Y/Alt-U navigate |
| 11 | Viewed/edited history | Alt-Shift-E | ❌ Missing | LOW | `Cmd::EditHistory` stub |
| 12 | Directory hotlist | Ctrl-\\ | ✅ Done | LOW | Hotlist dialog with add/remove; `Ctrl-X h` AddCurrent |
| 13 | Active VFS list | Ctrl-X a | ❌ Missing | LOW | `Cmd::VfsList` stub (module being integrated) |
| 14 | Background jobs | Ctrl-X j | ❌ Missing | LOW | `Cmd::Jobs` stub (module being integrated) |
| 15 | Screen list | Alt-` | ❌ Missing | LOW | `Cmd::ScreenList` stub |
| 6 | Compare directories | Ctrl-X d | ✅ Done | — | Size-only compare (15g) |
| 7 | Compare files | Ctrl-d | ✅ Done | — | LCS diff viewer (15l) |
| 8 | External panelize | Ctrl-X ! | ✅ Done | — | Full dialog + job registry (15f) |
| 9 | Show directory sizes | Ctrl-Space | ✅ Done | — | Recursive dir size in panel |
| 10 | Command history | Alt-H | ✅ Done | | Alt-H shows count, Alt-Y/Alt-U navigate |
| 11 | Viewed/edited history | Alt-Shift-E | ✅ Done | — | `Cmd::EditHistory` dialog (15g) |
| 12 | Directory hotlist | Ctrl-\\ | ✅ Done | | Hotlist dialog with add/remove; `Ctrl-X h` AddCurrent |
| 13 | Active VFS list | Ctrl-X a | ✅ Done | — | `Cmd::VfsList` dialog (15f) |
| 14 | Background jobs | Ctrl-X j | ✅ Done | — | `Cmd::Jobs` dialog (15f) |
| 15 | Screen list | Alt-` | ✅ Done | — | `Cmd::ScreenList` dialog (15g) |
| 16 | Undelete files | (none) | ❌ N/A | SKIP |
| 17 | Listing format edit | (none) | ❌ Missing | SKIP |
| 18 | Edit extension file | (menu) | ❌ Missing | LOW |
@@ -794,10 +798,10 @@ MC's F9 bar has 5 entries: **Left** · **File** · **Command** · **Options** ·
| # | MC Item | TLC Status | Priority |
|---|---|---|---|
| 1 | Configuration... | ❌ Missing | MEDIUM |
| 2 | Layout... | ❌ Missing | LOW |
| 3 | Panel options... | ❌ Missing | MEDIUM |
| 4 | Confirmation... | ❌ Missing | MEDIUM |
| 1 | Configuration... | ✅ Done | — | ConfigDialog with verbose, compute totals, shell patterns |
| 2 | Layout... | ✅ Done | — | LayoutDialog with panel/keybar/hint/visible toggles |
| 3 | Panel options... | ✅ Done | — | PanelOptionsDialog |
| 4 | Confirmation... | ✅ Done | — | ConfigDialog includes confirmation toggles |
| 5 | Appearance... (skins) | ✅ Done (Alt-S) | — | 8 built-in skins, runtime dialog, config persistence |
| 6 | Display bits... | ❌ Missing | LOW |
| 7 | Learn keys... | ❌ Missing | LOW |
@@ -810,32 +814,32 @@ MC's F9 bar has 5 entries: **Left** · **File** · **Command** · **Options** ·
MC's panel subsystem (`panel.c`, 5559 lines) is the core of the file
manager. TLC's panel (`panel.rs`) is much simpler.
**Last updated:** 2026-06-19 (comprehensive parity audit).
**Last updated:** 2026-07-05 (post-§31/§32 comprehensive parity audit).
| Feature | MC | TLC Status | Priority |
|---|---|---|---|
| **Listing modes**: Full, Brief, Long, User | 4 modes (cyclable) | ✅ 3 modes (Full→Brief→Long) | MEDIUM | Alt-L cycles; User format grammar still pending |
| **Format string grammar** | BNF parser, 23 field types | Fixed columns | LOW |
| **Type glyphs** | 13 types (`/`, `~`, `!`, `@`, `-`, `=`, `>`, `+`, `\|`, `#`, `?`, `*`, ` `) | Basic types | MEDIUM |
| **Sort fields**: name, ext, size, mtime, atime, ctime, inode, version, unsorted | 9 sortable fields | ✅ 4 fields (Name, Ext, Size, Mtime) | MEDIUM | Sort cycle via Alt-T: Name→Ext→Size→Mtime |
| **Sort reverse** | Toggle | ❌ Missing | MEDIUM |
| **Sort case sensitivity** | Toggle | ❌ Missing | LOW |
| **Type glyphs** | 13 types (`/`, `~`, `!`, `@`, `-`, `=`, `>`, `+`, `\|`, `#`, `?`, `*`, ` `) | ✅ Done (§30.7) | — | 9+ type categories with color highlighting (15h) |
| **Sort fields**: name, ext, size, mtime, atime, ctime, inode, version, unsorted | 9 sortable fields | ✅ 4 fields (Name, Ext, Size, Mtime) | MEDIUM | Sort cycle via Alt-T + dialog (§31.1) |
| **Sort reverse** | Toggle | ✅ Done (§30.9) | — | Alt-R toggles |
| **Sort case sensitivity** | Toggle | ✅ Done (§30.9) | — | Alt-C toggles |
| **Column-click sort** | Mouse | N/A (no mouse) | SKIP |
| **Quick search** (type-ahead) | `/<buffer>` glob filter | ✅ Done (Ctrl-S) | — |
| **File filter** (persistent) | Dialog with shell/regex | ❌ Missing | MEDIUM |
| **Directory history** | GList, prev/next/list | ✅ Done | MEDIUM | Alt-H shows count, Alt-Y/Alt-U navigate prev/next |
| **File filter** (persistent) | Dialog with shell/regex | ✅ Done | — | PanelFilter dialog |
| **Directory history** | GList, prev/next/list | ✅ Done | | Alt-H shows count, Alt-Y/Alt-U navigate prev/next |
| **Marking**: single (Insert/Ctrl-T), range (Shift+arrows), group (+/-/\*) | Full state machine | ✅ Done | — | Ctrl-T toggle+advance, `*` invert, `+`/`\` pattern select/unselect (PatternDialog) |
| **Marked counters** | total bytes, dirs marked, files marked | ✅ Partial | LOW | Mini-status shows `Nf Nd, M marked <size>` |
| **Filename scrolling** | `{`/`}` scroll indicators | ❌ Missing | LOW |
| **Mini status line** | Context-sensitive (search prompt, symlink target, size, `UP--DIR`) | ✅ Done | MEDIUM | `Nf Nd, M marked <size>` format |
| **Panel info mode** | Switch other panel to Info | ❌ Missing | MEDIUM |
| **Quick view mode** | Switch other panel to viewer | ❌ Missing | MEDIUM |
| **Panelize** | Shell command → panel content | ❌ Missing | LOW | `Cmd::Panelize` stub |
| **File highlighting** | Data-driven `filehighlight.ini` | ❌ Missing | LOW |
| **Panel view modes**: listing, info, tree, quick | 4 switchable modes | Listing only | LOW |
| **Smart cd** (Backspace → cd ..) | If cmdline empty | ❌ Missing | MEDIUM |
| **Filename scrolling** | `{`/`}` scroll indicators | ✅ Done (§31.2) | — | `~` truncation indicator |
| **Mini status line** | Context-sensitive | ✅ Done | | `Nf Nd, M marked <size>` format |
| **Panel info mode** | Switch other panel to Info | ✅ Done (15j) | — |
| **Quick view mode** | Switch other panel to viewer | ✅ Done (15j) | — |
| **Panelize** | Shell command → panel content | ✅ Done (15f) | — |
| **File highlighting** | Data-driven `filehighlight.ini` | ✅ Done (15h) | — | 9 type categories |
| **Panel view modes**: listing, info, tree, quick | 4 switchable modes | ✅ 3/4 (listing, info, quick) | LOW | Tree mode via dialog |
| **Smart cd** (Backspace → cd ..) | If cmdline empty | ❌ WONTFIX | — | User directive: Backspace is Backspace, not cd .. |
| **Arrow navigation** (Left/Right → cd) | If navigate_with_arrows on | ❌ Missing | LOW |
| **Free space display** | Bottom-right of panel | ❌ Missing | LOW |
| **Free space display** | Bottom-right of panel | ✅ Done (§30.8) | — | Panel footer shows `X free of Y` |
| **Panel cursor starts on first entry** | (not `..`) | ✅ Done | — | Verified 2026-06-19 |
| **Save setup** | Alt-Shift-S | ✅ Done | — | Persists panel state to `~/.config/tlc/config.toml` |
| **ESC no-op on main screen** | MC parity | ✅ Done | — | ESC closes overlays only |
@@ -846,95 +850,101 @@ MC's file engine (`file.c`, 3780 lines) is a sophisticated recursive
copy/move/delete system with progress tracking, overwrite dialogs, and
background processing.
**Last updated:** 2026-06-19 (comprehensive parity audit).
**Last updated:** 2026-07-05 (post-§30/§31 parity audit).
| Feature | MC | TLC Status | Priority |
|---|---|---|---|
| **Copy file** | Full pipeline: stat, same-file check, hardlink optimization, symlink copy, special files, byte loop, metadata preserve | ✅ Basic copy | MEDIUM | Symlinks preserved as symlinks (Phase 9b fix); same-file detection still pending |
| **Copy directory** | Recursive with cycle detection (`parent_dirs`), deferred metadata | ✅ Done | MEDIUM | Cycle detection via `lstat` (Phase 9b); self-referential symlinks covered by symlink test suite |
| **Move file** | Rename preferred, copy+delete fallback (EXDV) | ✅ Basic move | — |
| **Move directory** | Recursive with `erase_at_end` deferred delete | ✅ Basic | MEDIUM |
| **Delete file** | `unlink` with retry loop | ✅ Done | — | |
| **Delete directory** | Recursive with confirm dialog | ✅ Done | — | `lstat`-based (Phase 9b fix); symlinks unlinked directly, not recursed |
| **Overwrite/replace dialog** | 10 options: Yes/No/All/None/Older/Smaller/Size differs/Append/Reget/Abort | ✅ 5 options | **HIGH** (resolved) | Overwrite / Skip / Append / All / Skip-all (all 5 wired into `OverwriteResult` enum and copy engine) |
| **Copy options dialog** | Follow links, Preserve attributes, Dive into subdir, Stable symlinks, Background | ❌ Missing | MEDIUM |
| **Copy file** | Full pipeline: stat, same-file check, hardlink optimization, symlink copy, special files, byte loop, metadata preserve | ✅ Done | — | Symlinks preserved as symlinks (Phase 9b fix); same-file detection (§30.6); hardlink optimization (§30.12) |
| **Copy directory** | Recursive with cycle detection | ✅ Done | | Cycle detection via `lstat` (Phase 9b); self-referential symlinks covered |
| **Move file** | Rename preferred, copy+delete fallback (EXDV) | ✅ Done | — |
| **Move directory** | Recursive with `erase_at_end` deferred delete | ✅ Done | — |
| **Delete file** | `unlink` with retry loop | ✅ Done | — |
| **Delete directory** | Recursive with confirm dialog | ✅ Done | — | `lstat`-based (Phase 9b fix); symlinks unlinked directly |
| **Overwrite/replace dialog** | 10 options | ✅ 5 options | — | Overwrite / Skip / Append / All / Skip-all (all 5 wired) |
| **Copy options dialog** | Follow links, Preserve attributes, Dive into subdir, Stable symlinks, Background | ✅ Done | — | CopyDialog with checkboxes (15a) |
| **Dest mask** (regex pattern) | Source filename → dest filename regex substitution | ❌ Missing | LOW |
| **Progress bar** | Per-file bar + total bar, ETA, BPS, file count | ❌ Basic progress | MEDIUM |
| **Suspend/Resume** | Non-blocking event pump, Suspend/Continue button | ❌ Missing | LOW |
| **Progress bar** | Per-file bar + total bar, ETA, BPS, file count | ✅ Done (15a) | — | Per-file + total bar, rate (BPS), ETA |
| **Suspend/Resume** | Non-blocking event pump | ❌ Missing | LOW |
| **Background processing** | Fork child, IPC for dialogs | ❌ Missing | LOW |
| **Recursive delete confirm** | Yes/No/All/None/Abort | ✅ Basic Yes/No | MEDIUM | Single-confirm dialog in place; multi-option variant still TBD |
| **Error dialog** | Ignore/Ignore all/Retry/Abort | ❌ Basic | MEDIUM |
| **Same-file detection** | `(st_dev, st_ino)` comparison | ❌ Missing | **HIGH** |
| **Hardlink optimization** | `nlink >= 2``mc_link` instead of copy | ❌ Missing | LOW |
| **Compare directories** | Quick/Size-only/Thorough modes | ❌ Missing | MEDIUM |
| **Dir size computation** | Async background, rotating dash | ❌ Missing | MEDIUM |
| **Symlink safety** | `lstat` instead of `stat` in copy/delete/count | ✅ Done | — | Phase 9b: `delete_dir`, `copy_dir` (with `copy_symlink`), `count_bytes_one` all switched to `lstat`; 5 new tests cover symlink loops |
| **Recursive delete confirm** | Yes/No/All/None/Abort | ✅ Done | — | Confirmation dialog |
| **Error dialog** | Ignore/Ignore all/Retry/Abort | ❌ Not started | LOW | Callback-based copy engine error recovery |
| **Same-file detection** | `(st_dev, st_ino)` comparison | ✅ Done (§30.6) | — | `is_same_file()` check; `OpsError::SameFile` |
| **Hardlink optimization** | `nlink >= 2``mc_link` instead of copy | ✅ Done (§30.12) | — | Hardlinks preserved on copy |
| **Compare directories** | Quick/Size-only/Thorough modes | ✅ Done (15g) | — | Size-only compare via C-x d |
| **Dir size computation** | Async background, rotating dash | ✅ Done | — | Ctrl-Space recursive computation |
| **Symlink safety** | `lstat` instead of `stat` in copy/delete/count | ✅ Done | — | Phase 9b: `delete_dir`, `copy_dir` (with `copy_symlink`), `count_bytes_one` all switched to `lstat` |
### 14.5 Editor (mcedit) — Gap Analysis
MC's editor (`src/editor/`) has 78 keybindings and ~55 features. TLC's
editor has basic gap-buffer editing with find/replace/goto.
**Last updated:** 2026-06-19 (comprehensive parity audit).
**Last updated:** 2026-07-05 (post-§31 comprehensive parity audit).
| Feature | MC | TLC Status | Priority |
|---|---|---|---|
| Basic editing (insert/delete/arrow) | ✅ | ✅ Done | — | Arrow keys use Option B structural fix — every `Cursor::move_*` and `select_*` method takes `&mut Buffer` and calls `buf.set_cursor(self.position)` after each move; buffer and cursor struct can never diverge |
| Gap buffer | ✅ | ✅ Done | — | |
| Save/load | ✅ lossy UTF-8 fallback | ✅ Done | — | `from_utf8_lossy` surfaces U+FFFD instead of silent drop; EOL preservation across round-trip |
| Find / Replace | Alt-f / Alt-% | ✅ Done | — | All 5 prompt kinds (Find/Replace/GotoLine/GotoCol/SaveAs) accept input |
| Goto line / column | Alt-l / Alt-g | ✅ Done | — | |
| **Block selection** (mark begin/end) | F3 toggle, F5 copy, F6 cut, F8 delete, Ctrl-V paste | ✅ Done | — | Selection highlighted in reverse video in render; F5/F6/F8/Ctrl-V operate on marked region |
| **Undo / Redo** | Alt-R redo, unlimited undo stack | ✅ Done | — | Undo stack capped at 10,000 entries; gap-buffer invariant tested (`undo_preserves_cursor_in_gap_invariant`) |
| **Syntax highlighting** | Built-in rules engine (~30 languages via syntect) | 🚧 Infrastructure done | MEDIUM | `Highlighter` struct, `syntax_for_path()`, `is_text_file()` in `editor/syntax.rs`; `Highlighter` initialized in `Editor::open()` (cfg-gated on `syntect` feature); **render-path wiring pending** |
| **Bookmarks** | m-a set, m-j next, m-k prev, m-K clear (10 slots) | ✅ Done | MEDIUM | Bracket-match highlight (Alt-B jumps to matching `()[]{}`); navigation bookmarks supported |
| **Hex edit mode** | Toggle C-x h | ❌ Missing | MEDIUM | |
| **Macro record/play** | Ctrl-R record, Ctrl-A play | ✅ Done | LOW | Recording, playback, named keys; persisted via `~/.config/tlc/macro.json` |
| **Format paragraph** | Alt-P reflow | ❌ Missing | LOW | |
| **Word completion** | Alt-Tab | ✅ Done | — | Scans visible lines for `word_starts_with(prefix)`, picks longest match, replaces prefix |
| **Multi-cursor support** | (MC has none natively; editor only) | ❌ Missing | LOW | TLC does not implement multi-cursor — single-cursor only |
| Basic editing (insert/delete/arrow) | ✅ | ✅ Done | — | Arrow keys use Option B structural fix |
| Gap buffer | ✅ | ✅ Done | — |
| Save/load | ✅ lossy UTF-8 fallback | ✅ Done | — | `from_utf8_lossy` surfaces U+FFFD; EOL preservation |
| Find / Replace | Alt-f / Alt-% | ✅ Done | — | All 5 prompt kinds accept input |
| Goto line / column | Alt-l / Alt-g | ✅ Done | — |
| **Block selection** (mark begin/end) | F3 toggle, F5 copy, F6 cut, F8 delete, Ctrl-V paste | ✅ Done | — | Selection highlighted in reverse video |
| **Undo / Redo** | Alt-R redo, unlimited undo stack | ✅ Done | — | Undo stack capped at 10,000 entries |
| **Syntax highlighting** | Built-in rules engine (~30 languages via syntect) | ✅ Done (15e) | — | `Highlighter` + `syntax_for_path()` + render wiring |
| **Bookmarks** | m-a set, m-j next, m-k prev | ✅ Done | — | Bookmark navigation; match-bracket (Alt-B) |
| **Hex edit mode** | Toggle C-x h | ❌ Missing | LOW | |
| **Macro record/play** | Ctrl-R record, Ctrl-A play | ✅ Done | | Recording, playback, named keys; persisted |
| **Format paragraph** | Alt-P reflow | ✅ Done (15c) | — | Reformats paragraph at 72 cols |
| **Word completion** | Alt-Tab | ✅ Done | — | Scans visible lines for prefix match |
| **Multi-cursor support** | ❌ N/A | ❌ Missing | LOW | Not started |
| **Spell check** | Alt-B (ispell) | ❌ Missing | LOW | Alt-B is bound to match-bracket |
| **Insert file** | Ctrl-X r | ❌ Missing | LOW |
| **Insert file** | Ctrl-X r | ✅ Done | — | PromptKind::InsertFile |
| **Sort block** | F13 | ❌ Missing | LOW |
| **Multi-window** | Alt-N new, Alt-T close | ❌ Missing | LOW |
| **External formatter** | Alt-B pipe through | ❌ Missing | LOW |
| **Date insert** | Alt-d | ❌ Missing | LOW |
| **Word wrap toggle** | Alt-l | ❌ Missing | LOW | Alt-l is bound to goto-line |
| **Auto-indent toggle** | Alt-i | ❌ Missing | LOW |
| **Show tabs/spaces** | Alt-t | ❌ Missing | LOW |
| **Date insert** | Alt-d | ✅ Done (§30.11) | — | Inserts current date/time |
| **Word wrap toggle** | Alt-l | ✅ Done (§31.3/§31.4) | — | F9 Options menu toggle |
| **Auto-indent toggle** | Alt-i | ✅ Done (§31.3) | — | Alt-A toggles; F9 Options menu toggle |
| **Show tabs/spaces** | Alt-t | ✅ Done (§31.4) | — | Alt-E toggles; F9 Options menu toggle |
| **File options dialog** | Alt-Enter | ❌ Missing | LOW |
| **Match bracket** | Alt-B | ✅ Done | LOW | Jumps to matching `()[]{}` |
| **Match bracket** | Alt-B | ✅ Done | | Jumps to matching `()[]{}` |
| **ETags jump** | Alt-Enter | ❌ Missing | LOW |
| **F2 user menu** | F2 in editor launches user menu on current file | ✅ Done | — | INI parser, condition operators (`+ = & \| ?`), shell-pattern + regex() filters, 17 percent-escape substitutions |
| **Percent escapes** | `%% %f %p %d %x %s %t %u %c %i %y %k %b %n %m %view %cd` | ✅ Done | — | All 17 tokens implemented and exercised by user-menu executor |
| **F2 user menu** | F2 in editor | ✅ Done | — | INI parser + percent escapes |
| **Percent escapes** | 17 tokens | ✅ Done | — | All 17 tokens implemented |
| **F9 menubar New/Open/Save/SaveAs/Quit** | (menu) | ✅ Done | — | All wired through dispatch_editor_cmd |
| **F9 menubar Find/FindNext/FindPrev/Replace** | (menu) | ✅ Done | — | All wired through dispatch_editor_cmd |
| **F9 menubar BookmarkNext/Prev** | (menu) | ✅ Done | — | All wired through dispatch_editor_cmd |
| **F9 menubar Options (5 toggles)** | (menu) | ✅ Done | — | Auto-indent, show whitespace, word wrap, syntax, relative lines |
### 14.6 Viewer (mcview) — Gap Analysis
MC's viewer (`src/viewer/`) has 50 keybindings and ~35 features. TLC's
viewer has basic text viewing with search.
**Last updated:** 2026-06-19 (comprehensive parity audit).
**Last updated:** 2026-07-05 (post-§30/§32 comprehensive parity audit).
| Feature | MC | TLC Status | Priority |
|---|---|---|---|
| Text mode navigation | Full (arrows, PgUp/PgDn, Home/End) | ✅ Done | — | Bug fix 2026-06-14: `ViewState.cursor` separated into `byte_off` and `line` fields; navigation in `view/keys.rs` updates both correctly (no more `cursor=top` byte/line mix-up) |
| Search (forward/backward) | Alt-? / Alt-/ | ✅ Done | — | |
| **Hex mode** | F4 toggle hex/text | ❌ Missing | **HIGH** | Read-only hex view only (no edit mode) |
| **Bookmarks** | m-a set, m-j next, m-k prev (10 slots) | ❌ Missing | MEDIUM |
| **Growing files** (tail -f) | F-r toggle | ❌ Missing | MEDIUM |
| **Nroff mode** | Alt-N toggle (interpret \b, bold/underline) | ✅ Done | LOW | `nroff` module strips backspace pairs; `_X_` rendered as underline, `X\bX` as bold |
| **Wrap/unwrap toggle** | Alt-W | ❌ Missing | MEDIUM |
| **Magic mode** (detect format) | Alt-M | ✅ Done (module) | LOW | `magic` module present; mc.ext preprocessing pipeline still TBD |
| **Goto line** | Alt-l | ❌ Missing | MEDIUM |
| Text mode navigation | Full (arrows, PgUp/PgDn, Home/End) | ✅ Done | — | ViewState.cursor separated into `byte_off` and `line` fields |
| Search (forward/backward) | Alt-? / Alt-/ | ✅ Done | — |
| **Hex mode** | F4 toggle hex/text | ✅ Done | — | Read-only hex view + hex-edit chunked source |
| **Bookmarks** | m-a set, m-j next, m-k prev | ✅ Done | — | Bookmark support in viewer |
| **Growing files** (tail -f) | F-r toggle | ✅ Done (15g) | — | Growing buffer support |
| **Nroff mode** | Alt-N toggle | ✅ Done | | `nroff` module strips backspace pairs |
| **Wrap/unwrap toggle** | Alt-W | ✅ Done (§30.10/§32.1) | — | Conditional `.wrap()` based on `v.wrap` field |
| **Magic mode** (detect format) | Alt-M | ✅ Done | — | `magic` module present |
| **Goto line** | Alt-l | ✅ Done | — |
| **Goto byte offset** | Alt-g | ❌ Missing | LOW |
| **File info** | Alt-i | ❌ Missing | LOW |
| **Next/prev file** | Alt-c / Alt-y | ❌ Missing | MEDIUM |
| **Follow EOF** (auto-scroll) | F-r | ❌ Missing | LOW |
| **Next/prev file** | Alt-c / Alt-y | ✅ Done (§30.5) | — | ViewerNextFile/PrevFile dispatch |
| **Follow EOF** (auto-scroll) | F-r | ✅ Done (15g) | — | Growing buffer auto-scroll |
| **Highlight matches** | Search results highlighted | ✅ Done | — |
| **Compressed file support** | .gz, .bz2 via external | ✅ Done (capped 256MiB) | — | `MAX_DECOMPRESSED_SIZE` const prevents OOM on large archives |
| **Percent display** | Position indicator | ❌ Missing | LOW |
| **Section selection** | Alt-Home/End (start/end of file) | ✅ Done | — |
| **Chunked source search** | (search ≥1 MiB files) | ✅ Done | — | Phase 9b fix: viewer search now handles `Chunked` sources; was silently returning `Ok(0)` stub |
| **Compressed file support** | .gz, .bz2 via external | ✅ Done (capped 256MiB) | — | `MAX_DECOMPRESSED_SIZE` |
| **Percent display** | Position indicator | ✅ Done (§30.13) | — | Position percentage in status |
| **Section selection** | Alt-Home/End | ✅ Done | — |
| **Chunked source search** | (search ≥1 MiB files) | ✅ Done | — | Phase 9b fix |
| **Standalone binary** | — | ✅ Done (15d) | — | `tlcview` standalone binary |
| **F9 menubar** | — | ✅ Done | — | Viewer has full F9 menubar with navigation/search/mode toggles |
### 14.7 Priority-Ranked Implementation Roadmap
@@ -1021,19 +1031,17 @@ are now DONE via Phases 15a15l and §30–§31. Remaining gaps noted inline.
| 14a (Critical) | 5 | ✅ Done (5/5) | — | Basic MC usability parity |
| 14b (High) | 6 | ✅ Done (6/6) | — | Core file manager + editor parity |
| 14c (Medium) | 15 | ✅ Done (14/15, 1 WONTFIX) | — | Feature completeness |
| 14d (Low) | ~25 | 🚧 Mostly Done (~17/25) | ongoing | Polish; remaining: multi-cursor, spell check, PTY subshell, mouse, learn keys, display bits, VFS settings, error dialog |
| **Total** | ~51 | **~90% complete (~42/51)** | ongoing | Near-full MC parity |
| 14d (Low) | ~25 | Mostly Done (~19/25) | ongoing | Polish; remaining: multi-cursor, spell check, PTY subshell, mouse, learn keys, display bits, VFS settings, error dialog |
| **Total** | ~51 | **~93% complete (~44/51)** | ongoing | Near-full MC parity; all CRITICAL/HIGH/MEDIUM done |
### 14.9 Key Architectural Decisions for Phase 14
1. **F9 Menu Bar** — F9 is wired to `Cmd::UserMenu` and dispatches to the
working user-menu dialog. The full 5-pull-down menubar widget (Left/File/
Command/Options/Right with nested sub-dialogs) is TBD — when implemented
it will use a `MenuBar` widget in `widget/` that renders a horizontal bar
of pull-down menus. Each menu is a `Vec<MenuItem>` with text, optional
hotkey, optional shortcut display, and a dispatch closure. The menubar is
activated by F9, navigated by Left/Right, items selected by Up/Down/Enter,
dismissed by Esc/F9.
1. **F9 Menu Bar** — F9 opens an expanded menubar with all 20+ commands
across Left, File, Command, Options, Right pull-down menus (implemented
in Phase 15l). Each pull-down dispatches directly to the corresponding
`Cmd::` variant. Editor F9 menubar is also fully wired with New/Open/Save/
SaveAs/Quit/Find/FindNext/FindPrev/Replace/BookmarkNext/Prev and an
Options sub-menu with 5 toggle commands.
2. **`+`/`\` Pattern Input** — Done. Reuses the existing `PromptInput` dialog
pattern. Input dialog titled "Select group:" / "Unselect group:" accepts
@@ -1794,3 +1802,9 @@ hints) remain deferred — see §17.4 rows 6-7 for rationale.
- §32.1 Viewer word-wrap fix (viewer/text.rs): Paragraph `.wrap()` was always on regardless of the `v.wrap` toggle. Now `.wrap(Wrap { trim: false })` is conditionally applied only when `v.wrap` is true. When wrap is off, long lines truncate at the right margin (MC parity). Stale TODO removed.
- §32.2 Alt-W wrap toggle test (viewer/mod.rs): test verifying Alt-W toggles wrap field correctly.
- §14.7 table refresh: 30+ stale ❌ entries corrected to ✅ across Phase 14b/14c/14d. Phase 14b: 6/6 ✅. Phase 14c: 14/15 ✅ (1 WONTFIX per user directive). Phase 14d: ~17/25 ✅. Overall: ~90% complete.
- **2026-07-05** — **§33 Editor F9 menubar + remaining command wiring + comprehensive PLAN refresh** (1213 tests):
- §33.1 Editor F9 Options menu (editor/menubar.rs, editor/mod.rs): 5 new EditorCmd variants (ToggleAutoIndent, ToggleShowWhitespace, ToggleWordWrap, ToggleSyntax, ToggleRelativeLines) with full Options menu and dispatch_editor_cmd handlers.
- §33.2 Editor F9 menubar commands wired (editor/mod.rs, handlers.rs): New, Open, Save, SaveAs, Quit, Find, FindNext, FindPrev, Replace, BookmarkNext, BookmarkPrev all wired through dispatch_editor_cmd. Previously printed "not yet wired".
- §33.3 Ctrl-X h chord (dispatch.rs): Ctrl-X h now dispatches to Cmd::HotList (AddCurrent path).
- §33.4 §14.1-§14.6 comprehensive PLAN refresh: All 6 gap-analysis tables updated. §14.1: 77/78 ✅ (was stale at ~73/77). §14.2: Left/Right menu 13/13 ✅. File menu 20/21 ✅. Command menu 17/20 ✅. Options menu 7/10 ✅. §14.3: All panel features current. §14.4: All file ops current. §14.5: Editor 28/35 ✅ (was 15/35). §14.6: Viewer 17/19 ✅ (was 6/19). Overall parity: ~93% complete (~44/51 items).
+1
View File
@@ -173,5 +173,6 @@ dialog. Selection persists to `~/.config/tlc/config.toml`.
| 15k Clippy cleanup | ✅ All 20 clippy lints fixed across 9 files; only 1 pre-existing warning remains (mc_ext.rs Include(String) never read) |
| 15l Split ratio + QuitQuiet + menubar + Compare files | ✅ SplitMore/Less (Alt-Shift-Right/Left, 5% steps, 10-90%), QuitQuiet (Shift-F10 actually quits), F9 menubar expanded with all 20+ commands, Compare files (Ctrl-d, LCS diff viewer) |
| 31 SortDialog + truncation + editor toggles | ✅ SortDialog wired to Alt-Shift-T (field/reverse/case), filename truncation indicator (`~`), editor auto-indent toggle (Alt-A), editor show whitespace toggle (Alt-E) |
| 33 Editor F9 menubar + PLAN refresh | ✅ All editor F9 commands wired (New/Open/Save/SaveAs/Quit/Find/Replace/Bookmarks), Options menu with 5 toggles, Ctrl-X h chord, §14.1-§14.6 tables refreshed (~93% MC parity) |
See `PLAN.md` for the comprehensive quality assessment and remaining tasks.
@@ -543,6 +543,7 @@ impl FileManager {
Some('!') => Some(Cmd::Panelize),
Some('i') => Some(Cmd::PanelInfo),
Some('q') => Some(Cmd::PanelQuickView),
Some('h') => Some(Cmd::HotList),
_ => None,
};
match cmd {