mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-11 12:25:47 +02:00
Support filtering files
This commit is contained in:
parent
84870d4503
commit
13326344f0
9 changed files with 72 additions and 19 deletions
|
@ -23,3 +23,7 @@ func (f *CommitFile) Added() bool {
|
|||
func (f *CommitFile) Deleted() bool {
|
||||
return f.ChangeStatus == "D"
|
||||
}
|
||||
|
||||
func (f *CommitFile) GetPath() string {
|
||||
return f.Name
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
)
|
||||
|
||||
type CommitFilesContext struct {
|
||||
*FilteredList[*models.CommitFile]
|
||||
*filetree.CommitFileTreeViewModel
|
||||
*ListContextTrait
|
||||
*DynamicTitleBuilder
|
||||
|
@ -21,8 +22,13 @@ var (
|
|||
)
|
||||
|
||||
func NewCommitFilesContext(c *ContextCommon) *CommitFilesContext {
|
||||
viewModel := filetree.NewCommitFileTreeViewModel(
|
||||
filteredList := NewFilteredList(
|
||||
func() []*models.CommitFile { return c.Model().CommitFiles },
|
||||
func(file *models.CommitFile) []string { return []string{file.GetPath()} },
|
||||
)
|
||||
|
||||
viewModel := filetree.NewCommitFileTreeViewModel(
|
||||
func() []*models.CommitFile { return filteredList.GetFilteredList() },
|
||||
c.Log,
|
||||
c.UserConfig.Gui.ShowFileTree,
|
||||
)
|
||||
|
@ -39,6 +45,7 @@ func NewCommitFilesContext(c *ContextCommon) *CommitFilesContext {
|
|||
}
|
||||
|
||||
return &CommitFilesContext{
|
||||
FilteredList: filteredList,
|
||||
CommitFileTreeViewModel: viewModel,
|
||||
DynamicTitleBuilder: NewDynamicTitleBuilder(c.Tr.CommitFilesDynamicTitle),
|
||||
ListContextTrait: &ListContextTrait{
|
||||
|
@ -71,3 +78,17 @@ func (self *CommitFilesContext) GetSelectedItemId() string {
|
|||
func (self *CommitFilesContext) GetDiffTerminals() []string {
|
||||
return []string{self.GetRef().RefName()}
|
||||
}
|
||||
|
||||
// used for type switch
|
||||
func (self *CommitFilesContext) IsFilterableContext() {}
|
||||
|
||||
// TODO: see if we can just call SetTree() within HandleRender(). It doesn't seem
|
||||
// right that we need to imperatively refresh the view model like this
|
||||
func (self *CommitFilesContext) SetFilter(filter string) {
|
||||
self.FilteredList.SetFilter(filter)
|
||||
self.SetTree()
|
||||
}
|
||||
|
||||
func (self *CommitFilesContext) ClearFilter() {
|
||||
self.SetFilter("")
|
||||
}
|
||||
|
|
|
@ -14,6 +14,13 @@ type FilteredList[T any] struct {
|
|||
filter string
|
||||
}
|
||||
|
||||
func NewFilteredList[T any](getList func() []T, getFilterFields func(T) []string) *FilteredList[T] {
|
||||
return &FilteredList[T]{
|
||||
getList: getList,
|
||||
getFilterFields: getFilterFields,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *FilteredList[T]) GetFilter() string {
|
||||
return self.filter
|
||||
}
|
||||
|
@ -28,13 +35,14 @@ func (self *FilteredList[T]) ClearFilter() {
|
|||
self.SetFilter("")
|
||||
}
|
||||
|
||||
func (self *FilteredList[T]) GetList() []T {
|
||||
func (self *FilteredList[T]) GetFilteredList() []T {
|
||||
if self.filteredIndices == nil {
|
||||
return self.getList()
|
||||
}
|
||||
return utils.ValuesAtIndices(self.getList(), self.filteredIndices)
|
||||
}
|
||||
|
||||
// TODO: update to just 'Len'
|
||||
func (self *FilteredList[T]) UnfilteredLen() int {
|
||||
return len(self.getList())
|
||||
}
|
||||
|
|
|
@ -6,16 +6,13 @@ type FilteredListViewModel[T any] struct {
|
|||
}
|
||||
|
||||
func NewFilteredListViewModel[T any](getList func() []T, getFilterFields func(T) []string) *FilteredListViewModel[T] {
|
||||
filteredList := &FilteredList[T]{
|
||||
getList: getList,
|
||||
getFilterFields: getFilterFields,
|
||||
}
|
||||
filteredList := NewFilteredList(getList, getFilterFields)
|
||||
|
||||
self := &FilteredListViewModel[T]{
|
||||
FilteredList: filteredList,
|
||||
}
|
||||
|
||||
listViewModel := NewListViewModel(filteredList.GetList)
|
||||
listViewModel := NewListViewModel(filteredList.GetFilteredList)
|
||||
|
||||
self.ListViewModel = listViewModel
|
||||
|
||||
|
|
|
@ -9,20 +9,30 @@ import (
|
|||
)
|
||||
|
||||
type WorkingTreeContext struct {
|
||||
*FilteredList[*models.File]
|
||||
*filetree.FileTreeViewModel
|
||||
*ListContextTrait
|
||||
}
|
||||
|
||||
var _ types.IListContext = (*WorkingTreeContext)(nil)
|
||||
var (
|
||||
_ types.IListContext = (*WorkingTreeContext)(nil)
|
||||
_ types.IFilterableContext = (*WorkingTreeContext)(nil)
|
||||
)
|
||||
|
||||
func NewWorkingTreeContext(c *ContextCommon) *WorkingTreeContext {
|
||||
viewModel := filetree.NewFileTreeViewModel(
|
||||
filteredList := NewFilteredList(
|
||||
func() []*models.File { return c.Model().Files },
|
||||
func(file *models.File) []string { return []string{file.GetPath()} },
|
||||
)
|
||||
|
||||
viewModel := filetree.NewFileTreeViewModel(
|
||||
func() []*models.File { return filteredList.GetFilteredList() },
|
||||
c.Log,
|
||||
c.UserConfig.Gui.ShowFileTree,
|
||||
)
|
||||
|
||||
getDisplayStrings := func(startIdx int, length int) [][]string {
|
||||
c.Log.Warn("in get display strings")
|
||||
lines := presentation.RenderFileTree(viewModel, c.Modes().Diffing.Ref, c.Model().Submodules)
|
||||
return slices.Map(lines, func(line string) []string {
|
||||
return []string{line}
|
||||
|
@ -30,6 +40,7 @@ func NewWorkingTreeContext(c *ContextCommon) *WorkingTreeContext {
|
|||
}
|
||||
|
||||
return &WorkingTreeContext{
|
||||
FilteredList: filteredList,
|
||||
FileTreeViewModel: viewModel,
|
||||
ListContextTrait: &ListContextTrait{
|
||||
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
||||
|
@ -54,3 +65,17 @@ func (self *WorkingTreeContext) GetSelectedItemId() string {
|
|||
|
||||
return item.ID()
|
||||
}
|
||||
|
||||
// used for type switch
|
||||
func (self *WorkingTreeContext) IsFilterableContext() {}
|
||||
|
||||
// TODO: see if we can just call SetTree() within HandleRender(). It doesn't seem
|
||||
// right that we need to imperatively refresh the view model like this
|
||||
func (self *WorkingTreeContext) SetFilter(filter string) {
|
||||
self.FilteredList.SetFilter(filter)
|
||||
self.SetTree()
|
||||
}
|
||||
|
||||
func (self *WorkingTreeContext) ClearFilter() {
|
||||
self.SetFilter("")
|
||||
}
|
||||
|
|
|
@ -658,7 +658,7 @@ func (self *FilesController) handleStatusFilterPressed() error {
|
|||
}
|
||||
|
||||
func (self *FilesController) setStatusFiltering(filter filetree.FileTreeDisplayFilter) error {
|
||||
self.context().FileTreeViewModel.SetFilter(filter)
|
||||
self.context().FileTreeViewModel.SetStatusFilter(filter)
|
||||
return self.c.PostRefreshUpdate(self.context())
|
||||
}
|
||||
|
||||
|
|
|
@ -464,10 +464,10 @@ func (self *RefreshHelper) refreshStateFiles() error {
|
|||
// I'd prefer to maintain as little state as possible.
|
||||
if conflictFileCount > 0 {
|
||||
if fileTreeViewModel.GetFilter() == filetree.DisplayAll {
|
||||
fileTreeViewModel.SetFilter(filetree.DisplayConflicted)
|
||||
fileTreeViewModel.SetStatusFilter(filetree.DisplayConflicted)
|
||||
}
|
||||
} else if fileTreeViewModel.GetFilter() == filetree.DisplayConflicted {
|
||||
fileTreeViewModel.SetFilter(filetree.DisplayAll)
|
||||
fileTreeViewModel.SetStatusFilter(filetree.DisplayAll)
|
||||
}
|
||||
|
||||
self.c.Model().Files = files
|
||||
|
|
|
@ -34,7 +34,7 @@ type IFileTree interface {
|
|||
ITree[models.File]
|
||||
|
||||
FilterFiles(test func(*models.File) bool) []*models.File
|
||||
SetFilter(filter FileTreeDisplayFilter)
|
||||
SetStatusFilter(filter FileTreeDisplayFilter)
|
||||
Get(index int) *FileNode
|
||||
GetFile(path string) *models.File
|
||||
GetAllItems() []*FileNode
|
||||
|
@ -91,7 +91,7 @@ func (self *FileTree) FilterFiles(test func(*models.File) bool) []*models.File {
|
|||
return slices.Filter(self.getFiles(), test)
|
||||
}
|
||||
|
||||
func (self *FileTree) SetFilter(filter FileTreeDisplayFilter) {
|
||||
func (self *FileTree) SetStatusFilter(filter FileTreeDisplayFilter) {
|
||||
self.filter = filter
|
||||
self.SetTree()
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ func (self *FileTree) ToggleShowTree() {
|
|||
}
|
||||
|
||||
func (self *FileTree) Get(index int) *FileNode {
|
||||
// need to traverse the three depth first until we get to the index.
|
||||
// need to traverse the tree depth first until we get to the index.
|
||||
return NewFileNode(self.tree.GetNodeAtIndex(index+1, self.collapsedPaths)) // ignoring root
|
||||
}
|
||||
|
||||
|
|
|
@ -26,8 +26,6 @@ type FileTreeViewModel struct {
|
|||
|
||||
var _ IFileTreeViewModel = &FileTreeViewModel{}
|
||||
|
||||
// how to tackle this? We could just filter down the list of files at a high point and then the rest will take care of itself.
|
||||
|
||||
func NewFileTreeViewModel(getFiles func() []*models.File, log *logrus.Entry, showTree bool) *FileTreeViewModel {
|
||||
fileTree := NewFileTree(getFiles, log, showTree)
|
||||
listCursor := traits.NewListCursor(fileTree)
|
||||
|
@ -128,8 +126,8 @@ func (self *FileTreeViewModel) findNewSelectedIdx(prevNodes []*FileNode, currNod
|
|||
return -1
|
||||
}
|
||||
|
||||
func (self *FileTreeViewModel) SetFilter(filter FileTreeDisplayFilter) {
|
||||
self.IFileTree.SetFilter(filter)
|
||||
func (self *FileTreeViewModel) SetStatusFilter(filter FileTreeDisplayFilter) {
|
||||
self.IFileTree.SetStatusFilter(filter)
|
||||
self.IListCursor.SetSelectedLineIdx(0)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue