Skip to content

feat(analyze): incremental filter (/) for Top files and tree views#1107

Open
iuhoay wants to merge 1 commit into
tw93:mainfrom
iuhoay:feat/analyze-incremental-filter
Open

feat(analyze): incremental filter (/) for Top files and tree views#1107
iuhoay wants to merge 1 commit into
tw93:mainfrom
iuhoay:feat/analyze-incremental-filter

Conversation

@iuhoay

@iuhoay iuhoay commented Jun 11, 2026

Copy link
Copy Markdown

What

Adds an incremental, type-to-filter to the analyze disk explorer. Press / to filter the current list as you type, Enter to apply, Esc to clear. Works in both:

  • the Top files (T) view, and
  • the directory drill-down view.

Matching is case-insensitive substring over the entry name and its display path. This makes a deep scan navigable when you already know what you are looking for (e.g. node_modules, .mp4), instead of only scrolling a size-ranked list.

Usage

mo analyze
#   drill into a directory  → / → type "node" → Enter      (tree filter)
#   press t                 → / → type "mp4"  → Enter      (Top files filter)
#   Esc clears the filter; a second Esc leaves the view

The footer and a Filter: <query> (N matches) line show the active state.

Implementation notes

  • The full list is kept in largeFilesAll / entriesAll; largeFiles / entries hold the rendered view. Every existing reader (render, navigation, delete, open) is unchanged because it already reads the view slice.
  • Match semantics are single-sourced (filterMatches, generic filterByQuery / removeByPath) so the two views cannot drift.
  • Changing the query clears multi-selection, so a delete/open can never touch a row hidden by the filter. The single-item delete targets the visible match.
  • Drilling into a filtered directory snapshots the parent in full and remaps the selection, so going back restores the unfiltered siblings with the entered directory still highlighted.
  • Filtering is disabled in overview mode and is ephemeral per view (reset on refresh, view toggle, and navigation).

Safety fix included

While wiring the shared removeByPath, this also fixes a list-corruption bug: when no filter is active the view aliases its backing list, and removing from both shifted the shared array twice, leaving a duplicated, stale entry after a delete. removePathFromView now trims the backing list once and rebuilds each view through the filters.

Testing

  • 15 new tests in cmd/analyze/analyze_filter_test.go (Top-files + tree filters, drill-in round-trip, multi-select safety, backing-list integrity).
  • go test ./cmd/... green, gofmt clean, go vet clean, make build passes.

No new dependencies; matching is plain substring (fuzzy ranking left as a follow-up).

Press / in the disk explorer to filter the current list as you type;
Enter applies, Esc clears. Works in both the Top files (T) view and the
directory drill-down view. Matching is case-insensitive substring over
the entry name and display path.

The full list is kept in largeFilesAll / entriesAll while largeFiles /
entries hold the rendered view, so every existing reader (render,
navigation, delete, open) stays unchanged. Changing the query clears
multi-selection so an action can never touch a row hidden by the filter.
Drilling into a filtered directory snapshots the parent in full and
remaps the selection, so going back restores the unfiltered siblings
with the entered directory still highlighted.

Shared helpers (filterMatches, generic filterByQuery and removeByPath)
back both views so their match semantics cannot drift. removePathFromView
now trims the backing list once and rebuilds each view through the
filters, fixing a corruption where deleting with no active filter shifted
an aliased backing array twice and left a duplicated, stale entry.
@iuhoay iuhoay requested a review from tw93 as a code owner June 11, 2026 05:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant