Skip to content

[Repo Assist] feat: client-side text filter for Installed and Upgrades views #56

@github-actions

Description

@github-actions

🤖 This PR was created by Repo Assist, an automated AI assistant.

Summary

Adds real-time client-side text filtering to the Installed and Upgrades tabs. Previously, typing in the search bar and pressing Enter in these views would switch away to the winget search command. Now the already-loaded package list is filtered instantly as the user types, without any additional winget invocations.

Root Cause / Motivation

Issue #35 requested a way to narrow down a large Installed/Upgrades list without leaving the view. The search_query field was already bound to the search bar widget, but apply_filter only applied source-based filtering; the text query was ignored in Installed/Upgrades modes.

Changes

src/app.rsapply_filter

  • When mode is Installed or Upgrades and search_query is non-empty, the filtered list is further narrowed to packages whose name or id contains the query (case-insensitive).
  • Passes through unchanged for Search mode so winget search is unaffected.

src/handler.rshandle_search_input

  • In Installed/Upgrades modes: each keystroke and backspace calls apply_filter immediately (live filter).
  • Enter in Installed/Upgrades confirms the filter and stays in the current mode; does not switch to Search mode.
  • Esc clears search_query, reapplies the filter, and returns to Normal mode.

src/handler.rs — Tab / mouse tab click

  • Clears search_query on mode switch so the local filter doesn't bleed into the new view.

Tests

7 new unit tests added to app::tests:

  • local_text_filter_matches_by_name
  • local_text_filter_matches_by_id
  • local_text_filter_is_case_insensitive
  • local_text_filter_empty_query_shows_all
  • local_text_filter_not_applied_in_search_mode
  • local_text_filter_no_match_returns_empty
  • selection_clamped_when_filter_reduces_list

Test Status

running 21 tests
.....................
test result: ok. 21 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

Clippy: 0 new warnings from this PR (2 pre-existing warnings in cli_backend.rs are unrelated).

Closes #35

Generated by Repo Assist ·

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@cbb46ab386962aa371045839fc9998ee4e97ca64

Note

This was originally intended as a pull request, but GitHub Actions is not permitted to create or approve pull requests in this repository.
The changes have been pushed to branch repo-assist/feat-local-text-filter-2026-03-24-21b78db7d8af050f.

Click here to create the pull request

To fix the permissions issue, go to SettingsActionsGeneral and enable Allow GitHub Actions to create and approve pull requests.

Show patch preview (305 of 305 lines)
From 8aa869ecdd11970bb1be90aae350b20bd7ef5ddc Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Tue, 24 Mar 2026 12:38:28 +0000
Subject: [PATCH] feat: client-side text filter for Installed and Upgrades
 views

In Installed and Upgrades modes, typing in the search bar now filters the
already-loaded package list in real-time (case-insensitive, matches name
or id). Previously the search bar had no effect in these modes until Enter
was pressed, which would switch to winget search mode instead.

Behaviour changes:
- Installed/Upgrades: each keystroke refilters the visible list instantly.
- Esc clears the filter and restores the full list.
- Enter confirms the filter and returns to Normal mode without switching views.
- Tab / mouse-click on a tab clears the query so the filter doesn't leak
  into the new mode.
- Search mode is unchanged: Enter still dispatches to winget search.

Adds 7 unit tests in app::tests covering: name match, id match,
case-insensitivity, empty query, no match, no filter in Search mode,
and selection clamping.

Closes #35

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
 src/app.rs     | 181 ++++++++++++++++++++++++++++++++++++++++++++++++-
 src/handler.rs |  20 +++++-
 2 files changed, 199 insertions(+), 2 deletions(-)

diff --git a/src/app.rs b/src/app.rs
index 3dd2fed..7214c8b 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -148,9 +148,14 @@ impl App {
     }
 
     pub fn apply_filter(&mut self) {
+        // Client-side text filter is active when in Installed/Upgrades mode with a non-empty query.
+        let text_query = self.search_query.to_ascii_lowercase();
+        let local_text_filter = matches!(self.mode, AppMode::Installed | AppMode::Upgrades)
+            && !text_query.is_empty();
+
         // When a source filter is active, winget already filters server-side
         // (and omits the Source column), so accept all returned packages.
-        self.filtered_
... (truncated)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions