Filter file views rather than search#5273
Conversation
Coverage summary from CodacySee diff coverage on Codacy
Coverage variation details
Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: Diff coverage details
Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: See your quality gate settings Change summary preferencesFootnotes
|
There was a problem hiding this comment.
Pull request overview
This PR updates Lazygit’s file-based panels (working tree files and commit files) to use the existing filter mechanism (i.e., actually reducing the list contents) instead of the search mechanism (highlighting matches without changing the list).
Changes:
- Add text-filter support to working-tree and commit-file trees, including fuzzy/non-fuzzy matching.
- Convert Working Tree Files and Commit Files contexts from “searchable” to “filterable”.
- Enable and adjust integration tests that validate file/commit-file filtering behavior.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/integration/tests/filter_and_search/nested_filter_transient.go | Updates expectations to reflect filtering behavior in transient panels. |
| pkg/integration/tests/filter_and_search/nested_filter.go | Updates expectations/comments for filtering behavior across nested panels. |
| pkg/integration/tests/filter_and_search/filter_files.go | Unskips and runs file filtering integration test now that filtering is implemented. |
| pkg/integration/tests/filter_and_search/filter_commit_files.go | Unskips and runs commit-file filtering integration test now that filtering is implemented. |
| pkg/gui/filetree/file_tree_view_model.go | Adds IFilterableContext methods + search history to working tree file view model. |
| pkg/gui/filetree/file_tree.go | Implements text filtering for working-tree files and renames status filter getter. |
| pkg/gui/filetree/file_filter.go | Adds shared text-filter helpers for files and commit files (substring or fuzzy). |
| pkg/gui/filetree/commit_file_tree_view_model.go | Adds IFilterableContext methods + search history to commit-file view model. |
| pkg/gui/filetree/commit_file_tree.go | Implements text filtering in commit-file tree building. |
| pkg/gui/controllers/switch_to_diff_files_controller.go | Clears commit-files filtering when switching into diff-files view. |
| pkg/gui/controllers/helpers/search_helper.go | Resets filter history index on open; adjusts when selection resets on re-apply. |
| pkg/gui/controllers/helpers/refresh_helper.go | Updates call sites for renamed status filter getter. |
| pkg/gui/controllers/files_controller.go | Updates status filter references to new getter name. |
| pkg/gui/context/working_tree_context.go | Converts working tree context from searchable to filterable. |
| pkg/gui/context/commit_files_context.go | Converts commit files context from searchable to filterable. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
12e06ec to
49977e6
Compare
|
Nice! From what I remember, the main reason why we excluded the Files view from filtering back then was that we couldn't decide whether it should filter just the file name, or the full path. I can't find any discussion about that any more though. In this PR it seems you have decided to filter by full path, and it may well be the more desirable behavior (I'm still not really sure though). I would have expected some mention of this in the PR description or commit message. One inconsistency that I found: if you filter in the Commit Files view so that only some files in a directory are visible, and then select the directory and press space, only the visible files are added to the custom patch. However, if you do the same in the Files panel, all files are staged, even the invisible ones. I'm not really sure which behavior is the more expected one, but I feel it would be good to be consistent. And finally, after using it for a day I found a very confusing aspect of this, related to the previous parapraph: if you filter a directory so that only one file is visible, and then select the directory, it shows the diff of all files in it. This is of course the expected behavior if you think about it, but if you don't, it can confuse the hell out of you. (It did for me, anyway, and I suspect it could confuse other users.) I don't have any idea what we could do about it (probably nothing), just wanted to bring it up as something that confused me. |
49977e6 to
5586a87
Compare
I had forgotten there was discussion about that: this time around doing the full path feels like a no-brainer: in rust you can often have a bunch of files with the same name
Good catch. I think it's less surprising if we only stage things which are visible. It also supports more use cases like only wanting to stage all
I've resolved this in the last commit. |
stefanhaller
left a comment
There was a problem hiding this comment.
Coming back to this at last, sorry for the long delay. Trying to work my way back into proper maintainership now, after some time off for private reasons.
This looks very good to me now, I only have a few git-history related questions below. And I think the third commit should probably be squashed into the second.
| | `` = `` | Expand all files | Expand all directories in the file tree | | ||
| | `` 0 `` | Focus main view | | | ||
| | `` / `` | Search the current view by text | | | ||
| | `` / `` | Filter the current view by text | | |
There was a problem hiding this comment.
(Since github doesn't allow commenting on commit messages, I'll add this here:)
The third paragraph of the commit message is backwards.
| state.PrevSearchIndex = -1 | ||
|
|
There was a problem hiding this comment.
This looks like an unrelated fix. What does it fix? Can this be a separate commit?
There was a problem hiding this comment.
Added a separate commit (already tested by filter_and_search/filter_search_history, which fails if we revert the change. This test isn't changed by this branch but was failing due to switching from search -> filter.)
| if ok { | ||
| state := self.searchState() | ||
| if context == state.Context { | ||
| if context == state.Context && self.c.Context().Current().GetKey() == self.c.Contexts().Search.GetKey() { |
There was a problem hiding this comment.
I don't understand this change, and again, it looks unrelated. Can it be a separate commit? And why is it needed?
There was a problem hiding this comment.
Added an explanation in the commit message and a matching test
| func (self *CommitFilesController) pathsForDiff(node *filetree.CommitFileNode) []string { | ||
| if !node.IsFile() && self.context().IsFiltering() { | ||
| var paths []string | ||
| node.ForEachFile(func(file *models.CommitFile) error { |
There was a problem hiding this comment.
I pushed 9e29941 to address the linter warnings
| Contains("dir1").IsSelected(), | ||
| Contains("apple-grape"), | ||
| Contains("apple-orange"), | ||
| Contains("grape-orange"), |
There was a problem hiding this comment.
I prefer Equals over Contains for all file-tree related tests nowadays; I find it makes the tests much easier to read at a glance. I pushed 5024d75 to change this, but it is a fixup for both the 2nd and 3rd commits (which I think should be squashed).
5024d75 to
7f096a6
Compare
This avoids a naming collision with GetFilter from the IFilterableContext interface, which will be implemented by FileTreeViewModel in the next commit. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When opening a filter prompt, reset PrevSearchIndex to -1 to avoid stale search state from a previous search/filter session. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Without this check, the selection was being reset to 0 whenever ReApplyFilter was called for the current filter context, even when the user wasn't actively typing in the search prompt (e.g. when the model updates in the background). This was causing unexpected cursor jumps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change working tree files and commit files panels to use filtering (reducing the list) instead of search (highlighting matches). This matches the behavior of other filterable views. The text filter matches against the full file path, not just the filename, which is more useful for navigating large directory trees. When toggling a directory for a custom patch while a text filter is active, only the visible filtered files in the directory are affected, consistent with how staging a directory in the files panel works. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
7f096a6 to
615c566
Compare
jesseduffield/lazygit#5273 We can abort with esc to keep old behavior. maybe detect lazygit version if possible but I always use the latest.
This MR contains the following updates: | Package | Update | Change | |---|---|---| | [jesseduffield/lazygit](https://github.com/jesseduffield/lazygit) | minor | `v0.59.0` → `v0.60.0` | MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot). **Proposed changes to behavior should be submitted there as MRs.** --- ### Release Notes <details> <summary>jesseduffield/lazygit (jesseduffield/lazygit)</summary> ### [`v0.60.0`](https://github.com/jesseduffield/lazygit/releases/tag/v0.60.0) [Compare Source](jesseduffield/lazygit@v0.59.0...v0.60.0) <!-- Release notes generated using configuration in .github/release.yml at v0.60.0 --> #### What's Changed ##### Enhancements 🔥 - Rename "Copy commit hash to clipboard" to mention it's an abbreviated hash by [@​stefanhaller](https://github.com/stefanhaller) in [#​5331](jesseduffield/lazygit#5331) - Hide the "Fetching..." status of the auto-fetch when bottom line is hidden by [@​stefanhaller](https://github.com/stefanhaller) in [#​5321](jesseduffield/lazygit#5321) - Allow removing lines from patch directly by [@​jesseduffield](https://github.com/jesseduffield) in [#​5277](jesseduffield/lazygit#5277) - Filter file views rather than search by [@​jesseduffield](https://github.com/jesseduffield) in [#​5273](jesseduffield/lazygit#5273) - Show branch name and detached HEAD in worktrees tab by [@​ruudk](https://github.com/ruudk) in [#​5339](jesseduffield/lazygit#5339) - Add backward cycling support for log view (using `<shift>-a` on status page) by [@​zaakiy](https://github.com/zaakiy) in [#​5346](jesseduffield/lazygit#5346) - Show worktree name next to branch in branches list by [@​ruudk](https://github.com/ruudk) in [#​5340](jesseduffield/lazygit#5340) ##### Fixes 🔧 - Fix matching of lazygit-edit URLs without line numbers by [@​danielwe](https://github.com/danielwe) in [#​5311](jesseduffield/lazygit#5311) - Fix [#​5302](jesseduffield/lazygit#5302): Create .git/info directory before writing exclude file by [@​cobyfrombrooklyn-bot](https://github.com/cobyfrombrooklyn-bot) in [#​5325](jesseduffield/lazygit#5325) - Fix off-by-one error when calculating popup panel dimensions by [@​stefanhaller](https://github.com/stefanhaller) in [#​5312](jesseduffield/lazygit#5312) - Properly disable clicks in inactive views behind popups by [@​stefanhaller](https://github.com/stefanhaller) in [#​5313](jesseduffield/lazygit#5313) - Enable `{` and `}` to change diff context size in branches and tags panels in diffing mode by [@​stefanhaller](https://github.com/stefanhaller) in [#​5258](jesseduffield/lazygit#5258) - Fix diff display of custom pagers after screen mode change by [@​stefanhaller](https://github.com/stefanhaller) in [#​5349](jesseduffield/lazygit#5349) ##### Maintenance ⚙️ - Bump github.com/cloudflare/circl from 1.6.1 to 1.6.3 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​5323](jesseduffield/lazygit#5323) ##### Docs 📖 - Fix typo: MacOS to macOS by [@​04cb](https://github.com/04cb) in [#​5335](jesseduffield/lazygit#5335) ##### I18n 🌎 - Update translations from Crowdin by [@​stefanhaller](https://github.com/stefanhaller) in [#​5352](jesseduffield/lazygit#5352) ##### Other Changes - Add Terra as an alternative Fedora install method by [@​Owen-sz](https://github.com/Owen-sz) in [#​5281](jesseduffield/lazygit#5281) #### New Contributors - [@​Owen-sz](https://github.com/Owen-sz) made their first contribution in [#​5281](jesseduffield/lazygit#5281) - [@​danielwe](https://github.com/danielwe) made their first contribution in [#​5311](jesseduffield/lazygit#5311) - [@​cobyfrombrooklyn-bot](https://github.com/cobyfrombrooklyn-bot) made their first contribution in [#​5325](jesseduffield/lazygit#5325) - [@​04cb](https://github.com/04cb) made their first contribution in [#​5335](jesseduffield/lazygit#5335) - [@​zaakiy](https://github.com/zaakiy) made their first contribution in [#​5346](jesseduffield/lazygit#5346) **Full Changelog**: <jesseduffield/lazygit@v0.59.0...v0.60.0> </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My42MS43IiwidXBkYXRlZEluVmVyIjoiNDMuNjEuNyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90IiwiYXV0b21hdGlvbjpib3QtYXV0aG9yZWQiLCJkZXBlbmRlbmN5LXR5cGU6Om1pbm9yIl19-->
PR Description
Way back when I implemented filter functionality I could not muster the motivation to apply it to the file views (files and commit files), but it really should be used on them.
The text filter matches against the full file path (not just the filename), which is more useful for navigating large directory trees.
When a text filter is active, all operations respect it consistently:
Full disclosure, opus 4.6 wrote this entire PR but reviewing its changes they seem reasonable, and I have done some local testing and everything works as expected.
Please check if the PR fulfills these requirements
go generate ./...)