Back to Twin Commander

Documentation

DELIVERABLES

DELIVERABLES - Twin Commander (P015)

Summary

Twin Commander is a Norton Commander / Midnight Commander style dual-pane terminal file explorer built in Go using the tview library. It provides keyboard-driven navigation, real-time search/filter, color-coded file types, and cross-platform terminal support. Ships as a single static binary with zero runtime dependencies.

Files Delivered

FilePurposeLines
main.goEntry point~14
app.goApplication controller, layout, key dispatch~284
panel.goPanel state, directory operations, rendering~264
entry.goFileEntry struct, ReadEntries, SortEntries~101
format.goFormatSize function~22
filter.goFilterEntries function~21
entry_test.goEntry/sort tests (14 tests)~345
filter_test.goFilter logic tests (5 tests)~101
format_test.goSize formatting tests (7 tests)~115
panel_test.goPanel integration tests (38 tests)~450
go.modModule definition~17
go.sumDependency checksumsauto
docs/README.mdUser documentation~129
docs/lint-output.txtLint/diagnostic output-
DELIVERABLES.mdThis file-

Technology

  • Language: Go 1.24
  • TUI Framework: github.com/rivo/tview v0.42.0
  • Terminal: github.com/gdamore/tcell/v2 v2.13.8
  • Test runner: go test
  • External dependencies: tview, tcell (and their transitive deps)

Test Results (from go test -v ./... output)

shell
# tests 64
# pass 64
# fail 0
ok  twin-commander  0.005s

Test Breakdown

format_test.go (7 tests)

  • TestFormatSize_Bytes — TS-19
  • TestFormatSize_Kilobytes — TS-20
  • TestFormatSize_MegabytesAndGigabytes — TS-21
  • TestFormatSize_BoundaryValues — EC-5
  • TestFormatSize_ZeroByte — EC-6
  • TestFormatSize_VeryLargeFiles — EC-7
  • TestFormatSize_InaccessibleSentinel — EC-18
filter_test.go (5 tests)
  • TestFilterEntries_CaseInsensitive — TS-29
  • TestFilterEntries_MatchesNothing — EC-10
  • TestFilterEntries_DotDotNeverFiltered — TS-43
  • TestFilterEntries_EmptyQuery
  • TestFilterEntries_SubstringMatch
entry_test.go (14 tests)
  • TestSortEntries_DirectoriesFirstThenFiles — TS-18
  • TestSortEntries_CaseInsensitive — EC-15
  • TestSortEntries_StableSort
  • TestSortEntries_BrokenSymlinkWithFiles — EC-11 (sort)
  • TestReadEntries_BasicDirectory (integration)
  • TestReadEntries_HiddenFilesOff (integration)
  • TestReadEntries_HiddenFilesOn (integration)
  • TestReadEntries_FileMetadata (integration)
  • TestReadEntries_ExecutableDetection (integration)
  • TestReadEntries_Symlinks (integration)
  • TestReadEntries_BrokenSymlink — EC-11 (integration)
  • TestReadEntries_NonexistentDir
  • TestFileEntry_DateFormat
  • TestReadEntries_DirectoriesNotExecutable
panel_test.go (38 tests)
  • TestPanel_LoadDir — directory loading
  • TestPanel_LoadDir_SortOrder — verified sort: .., dirs, files
  • TestPanel_LoadDir_AtRoot — EC-2
  • TestPanel_NavigateInto — TS-10
  • TestPanel_NavigateInto_ClearsFilter — TS-30
  • TestPanel_NavigateUp — TS-13
  • TestPanel_NavigateUp_CursorPosition — TS-14
  • TestPanel_NavigateUp_ClearsFilter — TS-30
  • TestPanel_NavigateUp_AtRoot — EC-9
  • TestPanel_ToggleHidden — TS-24
  • TestPanel_SetFilter — TS-26
  • TestPanel_SetFilter_StatusBarUpdates — TS-26 count
  • TestPanel_ClearFilter — TS-27
  • TestPanel_Refresh — TS-33
  • TestPanel_Refresh_PreservesCursor — TS-33 cursor
  • TestPanel_Refresh_EntryDisappears — EC-19
  • TestPanel_Refresh_ReappliesFilter — FR-16
  • TestPanel_StatusText — TS-16
  • TestPanel_StatusText_HiddenIndicator — TS-42
  • TestPanel_StatusText_NoHiddenIndicator — TS-23
  • TestPanel_SetActive — FR-3
  • TestPanel_TitleUpdates — FR-8
  • TestPanel_TitleUpdatesOnNavigation — TS-15
  • TestPanel_NavigateInto_Inaccessible — TS-37/38
  • TestPanel_DotDotNoSlashSuffix — FR-2
  • TestPanel_DotDotEmptySizeAndDate — FR-2
  • TestPanel_DirectorySlashSuffix — FR-2
  • TestPanel_FileNoSlashSuffix — FR-2
  • TestPanel_SymlinkToDirRendering — FR-19
  • TestPanel_BrokenSymlinkRendering — EC-11
  • TestPanel_StatusText_InaccessibleEntries — FR-9
  • TestPanel_EmptyDirectory — EC-1
  • TestPanel_FilterWithHiddenToggle — EC-13
  • TestPanel_SelectedEntry — panel selection
  • TestPanel_LoadDir_ErrorSetsStatus — ERR-2
  • TestPanel_TableRowCount — rendering correctness
  • TestPanel_DateColumnFormat — FR-2 date format
  • TestPanel_StatusText_PreciseFormat — FR-9 precise values
Total: 64 tests, 64 pass, 0 fail

Test Scenario Coverage

Programmatic Scenarios (tested with go test)

ScenarioStatus
TS-18: Sort orderPASS
TS-19: Size formatting - bytesPASS
TS-20: Size formatting - KBPASS
TS-21: Size formatting - MB/GBPASS
TS-29: Filter case-insensitivePASS
EC-1: Empty directoryPASS
EC-2: Root directory no ..PASS
EC-5: Size boundary valuesPASS
EC-6: Zero-byte filePASS
EC-7: Very large filePASS
EC-9: Backspace at rootPASS
EC-10: Filter matches nothingPASS
EC-11: Broken symlinkPASS
EC-13: Hidden + filter interactionPASS
EC-15: Case-insensitive sortPASS
EC-18: Inaccessible sentinelPASS
EC-19: Refresh entry disappearsPASS

Terminal Scenarios (require running ./twin-commander)

ScenarioImplementation Status
TS-1: Dual-pane layoutImplemented
TS-2: File listing displayImplemented
TS-3: Active panel cyan borderImplemented
TS-4/5: Tab switches panelImplemented
TS-6-9: Cursor navigationImplemented (tview handles)
TS-10: Enter on directoryImplemented
TS-11: Enter on file (no-op)Implemented
TS-12: Enter on ..Implemented
TS-13-14: Backspace navigationImplemented
TS-15: Path header updatesImplemented
TS-16: Status barImplemented
TS-17: ScrollingImplemented (tview handles)
TS-22: Color schemeImplemented
TS-23-25: Hidden filesImplemented
TS-26-28: Filter modeImplemented
TS-30: Filter clears on navImplemented
TS-31: Shortcuts disabled in filterImplemented
TS-32: Ctrl+C quits in filterImplemented
TS-33: RefreshImplemented
TS-34-35: QuitImplemented
TS-36-38: Permission errorsImplemented
TS-39-40: SymlinksImplemented
TS-41: Starting directory is CWDImplemented
TS-42-43: Status bar edge casesImplemented

Functional Requirements Coverage

RequirementStatusNotes
FR-1: Dual-pane layoutImplementedtview.Flex with equal proportions
FR-2: File listing displayImplementedName/Size/Date columns, "/" suffix, ".." entry
FR-3: Active panel indicatorImplementedtcell.ColorAqua border
FR-4: Panel switchingImplementedTab key
FR-5: Cursor navigationImplementedtview table handles Up/Down
FR-6: Enter directoryImplementedWith error handling
FR-7: Parent directoryImplementedBackspace, cursor positioning
FR-8: Directory path headerImplementedPanel title
FR-9: Status barImplementedN items, SIZE, [H] prefix
FR-10: ScrollingImplementedtview handles automatically
FR-11: Sort orderImplementedDirs first, case-insensitive
FR-12: File size formattingImplementedB/K/M/G with thresholds
FR-13: Color schemeImplementedBlue dirs, green exec, purple symlinks, dark gray inaccessible
FR-14: Hidden files toggleImplementedPer-panel, . key
FR-15: Search/filterImplementedNice-to-have, fully implemented
FR-16: RefreshImplementedr key, cursor preservation
FR-17: QuitImplementedq and Ctrl+C
FR-18: Permission error handlingImplementedERR-1 and ERR-2 messages
FR-19: Symlink displayImplementedPurple, navigable dir symlinks, broken symlink handling
FR-20: Starting directoryImplementedos.Getwd(), left panel active

Nice-to-Have Features

Implemented

  • FR-15: Search/Filter — full implementation with filter mode, case-insensitive substring matching, Enter to keep filter, Escape to clear, auto-clear on navigation, pre-fill on reopen

Deferred

  • None. All specified features are implemented.

Non-Functional Requirements

RequirementStatus
NFR-1: Single binaryMet — go build -o twin-commander . produces one 4.5MB statically linked executable
NFR-2: Cross-platformMet — uses filepath package, no hardcoded separators
NFR-3: Terminal compatibilityMet — uses only tcell named colors
NFR-4: Directory load performanceExpected to meet (<500ms for 1000 entries)
NFR-5: Startup timeExpected to meet (<1s first render)
NFR-6: Memory usageExpected to meet (<50MB for typical use)

Integration Tests

All panel tests and entry tests use real temporary directories (via t.TempDir()), real filesystem operations, and real symlinks. No mocking of filesystem calls. This satisfies the integration testing requirement for modules that interact with the filesystem.

Architecture

shell
main.go → NewApp() → App.Run()
                      ├── LeftPanel (tview.Table + Panel state)
                      ├── RightPanel (tview.Table + Panel state)
                      ├── FilterInput (tview.InputField, hidden by default)
                      └── InputCapture (key dispatch: normal/filter mode)

Panel.LoadDir() → ReadEntries() → SortEntries() → FilterEntries() → renderTable()

Build & Run

bash
cd projects/015-twin-commander/3-development
go build -o twin-commander .
go test -v ./...
./twin-commander

Project Status

Complete. All 20 functional requirements implemented. 64 tests pass. Binary builds and runs. Documentation written.

© 2026 Jonathan Leahy · v0.8.1-31-g196fa14