diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2022-01-22 00:13:51 +1100 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2022-01-22 10:48:51 +1100 |
commit | 5b7dd9e43ccd2b82f07f0f0ff0ee8d54d0ecba11 (patch) | |
tree | 2afa1c595dad6ae8c0503217eac3f40e2a925924 /pkg/gui | |
parent | 4ab5e5413944a92699a9540148666f0de26aa44b (diff) |
properly resolve cyclic dependency
Diffstat (limited to 'pkg/gui')
-rw-r--r-- | pkg/gui/commit_files_panel.go | 25 | ||||
-rw-r--r-- | pkg/gui/files_panel.go | 46 | ||||
-rw-r--r-- | pkg/gui/filetree/README.md | 22 | ||||
-rw-r--r-- | pkg/gui/filetree/commit_file_manager.go | 118 | ||||
-rw-r--r-- | pkg/gui/filetree/commit_file_node.go | 13 | ||||
-rw-r--r-- | pkg/gui/filetree/commit_file_tree_view_model.go | 101 | ||||
-rw-r--r-- | pkg/gui/filetree/constants.go | 9 | ||||
-rw-r--r-- | pkg/gui/filetree/file_manager.go | 140 | ||||
-rw-r--r-- | pkg/gui/filetree/file_manager_test.go | 156 | ||||
-rw-r--r-- | pkg/gui/filetree/file_node.go | 17 | ||||
-rw-r--r-- | pkg/gui/filetree/file_tree_view_model.go | 139 | ||||
-rw-r--r-- | pkg/gui/filetree/file_tree_view_model_test.go | 67 | ||||
-rw-r--r-- | pkg/gui/filetree/inode.go | 51 | ||||
-rw-r--r-- | pkg/gui/filetree/presentation.go | 96 | ||||
-rw-r--r-- | pkg/gui/gui.go | 26 | ||||
-rw-r--r-- | pkg/gui/line_by_line_panel.go | 2 | ||||
-rw-r--r-- | pkg/gui/list_context_config.go | 10 | ||||
-rw-r--r-- | pkg/gui/patch_building_panel.go | 2 | ||||
-rw-r--r-- | pkg/gui/presentation/files.go | 204 | ||||
-rw-r--r-- | pkg/gui/presentation/files_test.go | 146 | ||||
-rw-r--r-- | pkg/gui/submodules_panel.go | 2 |
21 files changed, 757 insertions, 635 deletions
diff --git a/pkg/gui/commit_files_panel.go b/pkg/gui/commit_files_panel.go index 7e1ecd130..61f3b72b8 100644 --- a/pkg/gui/commit_files_panel.go +++ b/pkg/gui/commit_files_panel.go @@ -8,11 +8,11 @@ import ( func (gui *Gui) getSelectedCommitFileNode() *filetree.CommitFileNode { selectedLine := gui.State.Panels.CommitFiles.SelectedLineIdx - if selectedLine == -1 || selectedLine > gui.State.CommitFileManager.GetItemsLength()-1 { + if selectedLine == -1 || selectedLine > gui.State.CommitFileTreeViewModel.GetItemsLength()-1 { return nil } - return gui.State.CommitFileManager.GetItemAtIndex(selectedLine) + return gui.State.CommitFileTreeViewModel.GetItemAtIndex(selectedLine) } func (gui *Gui) getSelectedCommitFile() *models.CommitFile { @@ -42,7 +42,7 @@ func (gui *Gui) commitFilesRenderToMain() error { return nil } - to := gui.State.CommitFileManager.GetParent() + to := gui.State.CommitFileTreeViewModel.GetParent() from, reverse := gui.getFromAndReverseArgsForDiff(to) cmdObj := gui.Git.WorkingTree.ShowFileDiffCmdObj(from, to, reverse, node.GetPath(), false) @@ -64,7 +64,7 @@ func (gui *Gui) handleCheckoutCommitFile() error { } gui.logAction(gui.Tr.Actions.CheckoutFile) - if err := gui.Git.WorkingTree.CheckoutFile(gui.State.CommitFileManager.GetParent(), node.GetPath()); err != nil { + if err := gui.Git.WorkingTree.CheckoutFile(gui.State.CommitFileTreeViewModel.GetParent(), node.GetPath()); err != nil { return gui.surfaceError(err) } @@ -111,7 +111,8 @@ func (gui *Gui) refreshCommitFilesView() error { if err != nil { return gui.surfaceError(err) } - gui.State.CommitFileManager.SetFiles(files, to) + gui.State.CommitFileTreeViewModel.SetParent(to) + gui.State.CommitFileTreeViewModel.SetFiles(files) return gui.postRefreshUpdate(gui.State.Contexts.CommitFiles) } @@ -154,7 +155,7 @@ func (gui *Gui) handleToggleFileForPatch() error { // if there is any file that hasn't been fully added we'll fully add everything, // otherwise we'll remove everything adding := node.AnyFile(func(file *models.CommitFile) bool { - return gui.Git.Patch.PatchManager.GetFileStatus(file.Name, gui.State.CommitFileManager.GetParent()) != patch.WHOLE + return gui.Git.Patch.PatchManager.GetFileStatus(file.Name, gui.State.CommitFileTreeViewModel.GetParent()) != patch.WHOLE }) err := node.ForEachFile(func(file *models.CommitFile) error { @@ -176,7 +177,7 @@ func (gui *Gui) handleToggleFileForPatch() error { return gui.postRefreshUpdate(gui.State.Contexts.CommitFiles) } - if gui.Git.Patch.PatchManager.Active() && gui.Git.Patch.PatchManager.To != gui.State.CommitFileManager.GetParent() { + if gui.Git.Patch.PatchManager.Active() && gui.Git.Patch.PatchManager.To != gui.State.CommitFileTreeViewModel.GetParent() { return gui.ask(askOpts{ title: gui.Tr.DiscardPatch, prompt: gui.Tr.DiscardPatchConfirm, @@ -224,7 +225,7 @@ func (gui *Gui) enterCommitFile(opts OnFocusOpts) error { return gui.pushContext(gui.State.Contexts.PatchBuilding, opts) } - if gui.Git.Patch.PatchManager.Active() && gui.Git.Patch.PatchManager.To != gui.State.CommitFileManager.GetParent() { + if gui.Git.Patch.PatchManager.Active() && gui.Git.Patch.PatchManager.To != gui.State.CommitFileTreeViewModel.GetParent() { return gui.ask(askOpts{ title: gui.Tr.DiscardPatch, prompt: gui.Tr.DiscardPatchConfirm, @@ -244,7 +245,7 @@ func (gui *Gui) handleToggleCommitFileDirCollapsed() error { return nil } - gui.State.CommitFileManager.ToggleCollapsed(node.GetPath()) + gui.State.CommitFileTreeViewModel.ToggleCollapsed(node.GetPath()) if err := gui.postRefreshUpdate(gui.State.Contexts.CommitFiles); err != nil { gui.Log.Error(err) @@ -275,12 +276,12 @@ func (gui *Gui) switchToCommitFilesContext(refName string, canRebase bool, conte func (gui *Gui) handleToggleCommitFileTreeView() error { path := gui.getSelectedCommitFilePath() - gui.State.CommitFileManager.ToggleShowTree() + gui.State.CommitFileTreeViewModel.ToggleShowTree() // find that same node in the new format and move the cursor to it if path != "" { - gui.State.CommitFileManager.ExpandToPath(path) - index, found := gui.State.CommitFileManager.GetIndexForPath(path) + gui.State.CommitFileTreeViewModel.ExpandToPath(path) + index, found := gui.State.CommitFileTreeViewModel.GetIndexForPath(path) if found { gui.State.Contexts.CommitFiles.GetPanelState().SetSelectedLineIdx(index) } diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index 4201afb11..c62da8e21 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -21,7 +21,7 @@ func (gui *Gui) getSelectedFileNode() *filetree.FileNode { return nil } - return gui.State.FileManager.GetItemAtIndex(selectedLine) + return gui.State.FileTreeViewModel.GetItemAtIndex(selectedLine) } func (gui *Gui) getSelectedFile() *models.File { @@ -129,7 +129,7 @@ func (gui *Gui) refreshFilesAndSubmodules() error { // specific functions func (gui *Gui) stagedFiles() []*models.File { - files := gui.State.FileManager.GetAllFiles() + files := gui.State.FileTreeViewModel.GetAllFiles() result := make([]*models.File, 0) for _, file := range files { if file.HasStagedChanges { @@ -140,7 +140,7 @@ func (gui *Gui) stagedFiles() []*models.File { } func (gui *Gui) trackedFiles() []*models.File { - files := gui.State.FileManager.GetAllFiles() + files := gui.State.FileTreeViewModel.GetAllFiles() result := make([]*models.File, 0, len(files)) for _, file := range files { if file.Tracked { @@ -244,7 +244,7 @@ func (gui *Gui) handleFilePress() error { } func (gui *Gui) allFilesStaged() bool { - for _, file := range gui.State.FileManager.GetAllFiles() { + for _, file := range gui.State.FileTreeViewModel.GetAllFiles() { if file.HasUnstagedChanges { return false } @@ -378,7 +378,7 @@ func (gui *Gui) handleCommitPress() error { return gui.surfaceError(err) } - if gui.State.FileManager.GetItemsLength() == 0 { + if gui.State.FileTreeViewModel.GetItemsLength() == 0 { return gui.createErrorPanel(gui.Tr.NoFilesStagedTitle) } @@ -433,7 +433,7 @@ func (gui *Gui) promptToStageAllAndRetry(retry func() error) error { } func (gui *Gui) handleAmendCommitPress() error { - if gui.State.FileManager.GetItemsLength() == 0 { + if gui.State.FileTreeViewModel.GetItemsLength() == 0 { return gui.createErrorPanel(gui.Tr.NoFilesStagedTitle) } @@ -459,7 +459,7 @@ func (gui *Gui) handleAmendCommitPress() error { // handleCommitEditorPress - handle when the user wants to commit changes via // their editor rather than via the popup panel func (gui *Gui) handleCommitEditorPress() error { - if gui.State.FileManager.GetItemsLength() == 0 { + if gui.State.FileTreeViewModel.GetItemsLength() == 0 { return gui.createErrorPanel(gui.Tr.NoFilesStagedTitle) } @@ -498,9 +498,9 @@ func (gui *Gui) handleStatusFilterPressed() error { return gui.createMenu(gui.Tr.FilteringMenuTitle, menuItems, createMenuOptions{showCancel: true}) } -func (gui *Gui) setStatusFiltering(filter filetree.FileManagerDisplayFilter) error { +func (gui *Gui) setStatusFiltering(filter filetree.FileTreeDisplayFilter) error { state := gui.State - state.FileManager.SetDisplayFilter(filter) + state.FileTreeViewModel.SetDisplayFilter(filter) return gui.handleRefreshFiles() } @@ -555,31 +555,31 @@ func (gui *Gui) refreshStateFiles() error { selectedNode := gui.getSelectedFileNode() - prevNodes := gui.State.FileManager.GetAllItems() + prevNodes := gui.State.FileTreeViewModel.GetAllItems() prevSelectedLineIdx := gui.State.Panels.Files.SelectedLineIdx files := gui.Git.Loaders.Files. GetStatusFiles(loaders.GetStatusFileOptions{}) // for when you stage the old file of a rename and the new file is in a collapsed dir - state.FileManager.RWMutex.Lock() + state.FileTreeViewModel.RWMutex.Lock() for _, file := range files { if selectedNode != nil && selectedNode.Path != "" && file.PreviousName == selectedNode.Path { - state.FileManager.ExpandToPath(file.Name) + state.FileTreeViewModel.ExpandToPath(file.Name) } } - state.FileManager.SetFiles(files) - state.FileManager.RWMutex.Unlock() + state.FileTreeViewModel.SetFiles(files) + state.FileTreeViewModel.RWMutex.Unlock() if err := gui.fileWatcher.addFilesToFileWatcher(files); err != nil { return err } if selectedNode != nil { - newIdx := gui.findNewSelectedIdx(prevNodes[prevSelectedLineIdx:], state.FileManager.GetAllItems()) + newIdx := gui.findNewSelectedIdx(prevNodes[prevSelectedLineIdx:], state.FileTreeViewModel.GetAllItems()) if newIdx != -1 && newIdx != prevSelectedLineIdx { - newNode := state.FileManager.GetItemAtIndex(newIdx) + newNode := state.FileTreeViewModel.GetItemAtIndex(newIdx) // when not in tree mode, we show merge conflict files at the top, so you // can work through them one by one without having to sift through a large // set of files. If you have just fixed the merge conflicts of a file, we @@ -588,7 +588,7 @@ func (gui *Gui) refreshStateFiles() error { // conflicts: the user in this case would rather work on the next file // with merge conflicts, which will have moved up to fill the gap left by // the last file, meaning the cursor doesn't need to move at all. - leaveCursor := !state.FileManager.InTreeMode() && newNode != nil && + leaveCursor := !state.FileTreeViewModel.InTreeMode() && newNode != nil && selectedNode.File != nil && selectedNode.File.HasMergeConflicts && newNode.File != nil && !newNode.File.HasMergeConflicts @@ -598,7 +598,7 @@ func (gui *Gui) refreshStateFiles() error { } } - gui.refreshSelectedLine(state.Panels.Files, state.FileManager.GetItemsLength()) + gui.refreshSelectedLine(state.Panels.Files, state.FileTreeViewModel.GetItemsLength()) return nil } @@ -871,7 +871,7 @@ func (gui *Gui) openFile(filename string) error { } func (gui *Gui) anyFilesWithMergeConflicts() bool { - for _, file := range gui.State.FileManager.GetAllFiles() { + for _, file := range gui.State.FileTreeViewModel.GetAllFiles() { if file.HasMergeConflicts { return true } @@ -939,7 +939,7 @@ func (gui *Gui) handleToggleDirCollapsed() error { return nil } - gui.State.FileManager.ToggleCollapsed(node.GetPath()) + gui.State.FileTreeViewModel.ToggleCollapsed(node.GetPath()) if err := gui.postRefreshUpdate(gui.State.Contexts.Files); err != nil { gui.Log.Error(err) @@ -952,12 +952,12 @@ func (gui *Gui) handleToggleFileTreeView() error { // get path of currently selected file path := gui.getSelectedPath() - gui.State.FileManager.ToggleShowTree() + gui.State.FileTreeViewModel.ToggleShowTree() // find that same node in the new format and move the cursor to it if path != "" { - gui.State.FileManager.ExpandToPath(path) - index, found := gui.State.FileManager.GetIndexForPath(path) + gui.State.FileTreeViewModel.ExpandToPath(path) + index, found := gui.State.FileTreeViewModel.GetIndexForPath(path) if found { gui.filesListContext().GetPanelState().SetSelectedLineIdx(index) } diff --git a/pkg/gui/filetree/README.md b/pkg/gui/filetree/README.md new file mode 100644 index 000000000..d2d16ace6 --- /dev/null +++ b/pkg/gui/filetree/README.md @@ -0,0 +1,22 @@ +## FileTree Package + +This package handles the representation of file trees. There are two ways to render files: one is to render them flat, so something like this: + +``` +dir1/file1 +dir1/file2 +file3 +``` + +And the other is to render them as a tree + +``` +dir1/ + file1 + file2 +file3 +``` + +Internally we represent each of the above as a tree, but with the flat approach there's just a single root node and every path is a direct child of that root. Viewing in 'tree' mode (as opposed to 'flat' mode) allows for collapsing and expanding directories, and lets you perform actions on directories e.g. staging a whole directory. But it takes up more vertical space and sometimes you just want to have a flat view where you can go flick through your files one by one to see the diff. + +This package is not concerned about rendering the tree: only representing its internal state. diff --git a/pkg/gui/filetree/commit_file_manager.go b/pkg/gui/filetree/commit_file_manager.go deleted file mode 100644 index 852a67b09..000000000 --- a/pkg/gui/filetree/commit_file_manager.go +++ /dev/null @@ -1,118 +0,0 @@ -package filetree - -import ( - "github.com/jesseduffield/lazygit/pkg/commands/models" - "github.com/jesseduffield/lazygit/pkg/commands/patch" - "github.com/sirupsen/logrus" -) - -type CommitFileManager struct { - files []*models.CommitFile - tree *CommitFileNode - showTree bool - log *logrus.Entry - collapsedPaths CollapsedPaths - // parent is the identifier of the parent object e.g. a commit SHA if this commit file is for a commit, or a stash entry ref like 'stash@{1}' - parent string -} - -func (m *CommitFileManager) GetParent() string { - return m.parent -} - -func NewCommitFileManager(files []*models.CommitFile, log *logrus.Entry, showTree bool) *CommitFileManager { - return &CommitFileManager{ - files: files, - log: log, - showTree: showTree, - collapsedPaths: CollapsedPaths{}, - } -} - -func (m *CommitFileManager) ExpandToPath(path string) { - m.collapsedPaths.ExpandToPath(path) -} - -func (m *CommitFileManager) ToggleShowTree() { - m.showTree = !m.showTree - m.SetTree() -} - -func (m *CommitFileManager) GetItemAtIndex(index int) *CommitFileNode { - // need to traverse the three depth first until we get to the index. - return m.tree.GetNodeAtIndex(index+1, m.collapsedPaths) // ignoring root -} - -func (m *CommitFileManager) GetIndexForPath(path string) (int, bool) { - index, found := m.tree.GetIndexForPath(path, m.collapsedPaths) - return index - 1, found -} - -func (m *CommitFileManager) GetAllItems() []*CommitFileNode { - if m.tree == nil { - return nil - } - - return m.tree.Flatten(m.collapsedPaths)[1:] // ignoring root -} - -func (m *CommitFileManager) GetItemsLength() int { - return m.tree.Size(m.collapsedPaths) - 1 // ignoring root -} - -func (m *CommitFileManager) GetAllFiles() []*models.CommitFile { - return m.files -} - -func (m *CommitFileManager) SetFiles(files []*models.CommitFile, parent string) { - m.files = files - m.parent = parent - - m.SetTree() -} - -func (m *CommitFileManager) SetTree() { - if m.showTree { - m.tree = BuildTreeFromCommitFiles(m.files) - } else { - m.tree = BuildFlatTreeFromCommitFiles(m.files) - } -} - -func (m *CommitFileManager) IsCollapsed(path string) bool { - return m.collapsedPaths.IsCollapsed(path) -} - -func (m *CommitFileManager) ToggleCollapsed(path string) { - m.collapsedPaths.ToggleCollapsed(path) -} - -func (m *CommitFileManager) Render(diffName string, patchManager *patch.PatchManager) []string { - // can't rely on renderAux to check for nil because an interface won't be nil if its concrete value is nil - if m.tree == nil { - return []string{} - } - - return renderAux(m.tree, m.collapsedPaths, "", -1, func(n INode, depth int) string { - castN := n.(*CommitFileNode) - - // This is a little convoluted because we're dealing with either a leaf or a non-leaf. - // But this code actually applies to both. If it's a leaf, the status will just - // be whatever status it is, but if it's a non-leaf it will determine its status - // based on the leaves of that subtree - var status patch.PatchStatus - if castN.EveryFile(func(file *models.CommitFile) bool { - return patchManager.GetFileStatus(file.Name, m.parent) == patch.WHOLE - }) { - status = patch.WHOLE - } else if castN.EveryFile(func(file *models.CommitFile) bool { - return patchManager.GetFileStatus(file.Name, m.parent) == patch.UNSELECTED - }) { - status = patch.UNSELECTED - } else { - status = patch.PART - } - - return getCommitFileLine(castN.NameAtDepth(depth), diffName, castN.File, status) - }) -} diff --git a/pkg/gui/filetree/commit_file_node.go b/pkg/gui/filetree/commit_file_node.go index 173281035..14960ee30 100644 --- a/pkg/gui/filetree/commit_file_node.go +++ b/pkg/gui/filetree/commit_file_node.go @@ -11,6 +11,8 @@ type CommitFileNode struct { CompressionLevel int // equal to the number of forward slashes you'll see in the path when it's rendered in tree mode } +var _ INode = &CommitFileNode{} + // methods satisfying ListItem interface func (s *CommitFileNode) ID() string { @@ -23,6 +25,10 @@ func (s *CommitFileNode) Description() string { // methods satisfying INode interface +func (s *CommitFileNode) IsNil() bool { + return s == nil +} + func (s *CommitFileNode) IsLeaf() bool { return s.File != nil } @@ -139,13 +145,6 @@ func (s *CommitFileNode) Compress() { compressAux(s) } -// This ignores the root -func (node *CommitFileNode) GetPathsMatching(test func(*CommitFileNode) bool) []string { - return getPathsMatching(node, func(n INode) bool { - return test(n.(*CommitFileNode)) - }) -} - func (s *CommitFileNode) GetLeaves() []*CommitFileNode { leaves := getLeaves(s) castLeaves := make([]*CommitFileNode, len(leaves)) diff --git a/pkg/gui/filetree/commit_file_tree_view_model.go b/pkg/gui/filetree/commit_file_tree_view_model.go new file mode 100644 index 000000000..301396462 --- /dev/null +++ b/pkg/gui/filetree/commit_file_tree_view_model.go @@ -0,0 +1,101 @@ +package filetree + +import ( + "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/sirupsen/logrus" +) + +type CommitFileTreeViewModel struct { + files []*models.CommitFile + tree *CommitFileNode + showTree bool + log *logrus.Entry + collapsedPaths CollapsedPaths + // parent is the identifier of the parent object e.g. a commit SHA if this commit file is for a commit, or a stash entry ref like 'stash@{1}' + parent string +} + +func (self *CommitFileTreeViewModel) GetParent() string { + return self.parent +} + +func (self *CommitFileTreeViewModel) SetParent(parent string) { + self.parent = parent +} + +func NewCommitFileTreeViewModel(files []*models.CommitFile, log *logrus.Entry, showTree bool) *CommitFileTreeViewModel { + viewModel := &CommitFileTreeViewModel{ + log: log, + showTree: showTree, + collapsedPaths: CollapsedPaths{}, + } + + viewModel.SetFiles(files) + + return viewModel +} + +func (self *CommitFileTreeViewModel) ExpandToPath(path string) { + self.collapsedPaths.ExpandToPath(path) +} + +func (self *CommitFileTreeViewModel) ToggleShowTree() { + self.showTree = !self.showTree + self.SetTree() +} + +func (self *CommitFileTreeViewModel) GetItemAtIndex(index int) *CommitFileNode { + // need to traverse the three depth first until we get to the index. + return self.tree.GetNodeAtIndex(index+1, self.collapsedPaths) // ignoring root +} + +func (self *CommitFileTreeViewModel) GetIndexForPath(path string) (int, bool) { + index, found := self.tree.GetIndexForPath(path, self.collapsedPaths) + return index - 1, found +} + +func (self *CommitFileTreeViewModel) GetAllItems() []*CommitFileNode { + if self.tree == nil { + return nil + } + + return self.tree.Flatten(self.collapsedPaths)[1:] // ignoring root +} + +func (self *CommitFileTreeViewModel) GetItemsLength() int { + return self.tree.Size(self.collapsedPaths) - 1 // ignoring root +} + +func (self *CommitFileTreeViewModel) GetAllFiles() []*models.CommitFile { + return self.files +} + +func (self *CommitFileTreeViewModel) SetFiles(files []*models.CommitFile) { + self.files = files + + self.SetTree() +} + +func (self *CommitFileTreeViewModel) SetTree() { + if self.showTree { + self.tree = BuildTreeFromCommitFiles(self.files) + } else { + self.tree = BuildFlatTreeFromCommitFiles(self.files) + } +} + +func (self *CommitFileTreeViewModel) IsCollapsed(path string) bool { + return self.collapsedPaths.IsCollapsed(path) +} + +func (self *CommitFileTreeViewModel) ToggleCollapsed(path string) { + self.collapsedPaths.ToggleCollapsed(path) +} + +func (self *CommitFileTreeViewModel) Tree() INode { + return self.tree +} + +func (self *CommitFileTreeViewModel) CollapsedPaths() CollapsedPaths { + return self.collapsedPaths +} diff --git a/pkg/gui/filetree/constants.go b/pkg/gui/filetree/constants.go deleted file mode 100644 index d510650e2..000000000 --- a/pkg/gui/filetree/constants.go +++ /dev/null @@ -1,9 +0,0 @@ -package filetree - -const EXPANDED_ARROW = "▼" -const COLLAPSED_ARROW = "►" - -const INNER_ITEM = "├─ " -const LAST_ITEM = "└─ " -const NESTED = "│ " -const NOTHING = " " diff --git a/pkg/gui/filetree/file_manager.go b/pkg/gui/filetree/file_manager.go deleted file mode 100644 index b028ef961..000000000 --- a/pkg/gui/filetree/file_manager.go +++ /dev/null @@ -1,140 +0,0 @@ -package filetree - -import ( - "sync" - - "github.com/jesseduffield/lazygit/pkg/commands/models" - "github.com/sirupsen/logrus" -) - -type FileManagerDisplayFilter int - -const ( - DisplayAll FileManagerDisplayFilter = iota - DisplayStaged - DisplayUnstaged -) - -type FileManager struct { - files []*models.File - tree *FileNode - showTree bool - log *logrus.Entry - filter FileManagerDisplayFilter - collapsedPaths CollapsedPaths - sync.RWMutex -} - -func NewFileManager(files []*models.File, log *logrus.Entry, showTree bool) *FileManager { - return &FileManager{ - files: files, - log: log, - showTree: showTree, - filter: DisplayAll, - collapsedPaths: CollapsedPaths{}, - RWMutex: sync.RWMutex{}, - } -} - -func (m *FileManager) InTreeMode() bool { - return m.showTree -} - -func (m *FileManager) ExpandToPath(path string) { - m.collapsedPaths.ExpandToPath(path) -} - -func (m *FileManager) GetFilesForDisplay() []*models.File { - files := m.files - if m.filter == DisplayAll { - return files - } - - result := make([]*models.File, 0) - if m.filter == DisplayStaged { - for _, file := range files { - if file.HasStagedChanges { - result = append(result, file) - } - } - } else { - for _, file := range files { - if !file.HasStagedChanges { - result = append(result, file) - } - } - } - - return result -} - -func (m *FileManager) SetDisplayFilter(filter FileManagerDisplayFilter) { - m.filter = filter - m.SetTree() -} - -func (m *FileManager) ToggleShowTree() { - m.showTree = !m.showTree - m.SetTree() -} - -func (m *FileManager) GetItemAtIndex(index int) *FileNode { - // need to traverse the three depth first until we get to the index. - return m.tree.GetNodeAtIndex(index+1, m.collapsedPaths) // ignoring root -} - -func (m *FileManager) GetIndexForPath(path string) (int, bool) { - index, found := m.tree.GetIndexForPath(path, m.collapsedPaths) - return index - 1, found -} - -func (m *FileManager) GetAllItems() []*FileNode { - if m.tree == nil { - return nil - } - - return m.tree.Flatten(m.collapsedPaths)[1:] // ignoring root -} - -func (m *FileManager) GetItemsLength() int { - return m.tree.Size(m.collapsedPaths) - 1 // ignoring root -} - -func (m *FileManager) GetAllFiles() []*models.File { - return m.files -} - -func (m *FileManager) SetFiles(files []*models.File) { - m.files = files - - m.SetTree() -} - -func (m *FileManager) SetTree() { - filesForDisplay := m.GetFilesForDisplay() - if m.showTree { - m.tree = BuildTreeFromFiles(filesForDisplay) - } else { - m.tree = BuildFlatTreeFromFiles(filesForDisplay) - } -} - -func (m *FileManager) IsCollapsed(path string) bool { - return m.collapsedPaths.IsCollapsed(path) -} - -func (m *FileManager) ToggleCollapsed(path string) { - m.collapsedPaths.ToggleCollapsed(path) -} - -func (m *FileManager) Render(diffName string, submoduleConfigs []*models.SubmoduleConfig) []string { - // can't rely on renderAux to check for nil because an interface won't be nil if its concrete value is nil - if m.tree == nil { - return []string{} - } - - return renderAux(m.tree, m.collapsedPaths, "", -1, func(n INode, depth int) string { - castN := n.(*FileNode) - return getFileLine(castN.GetHasUnstagedChanges(), castN.GetHasStagedChanges(), castN.NameAtDepth(depth), diffName, submoduleConfigs, castN.File) - }) -} diff --git a/pkg/gui/filetree/file_manager_test.go b/pkg/gui/filetree/file_manager_test.go deleted file mode 100644 index 83ba5b086..000000000 --- a/pkg/gui/filetree/file_manager_test.go +++ /dev/null @@ -1,156 +0,0 @@ -package filetree - -import ( - "testing" - - "github.com/gookit/color" - "github.com/jesseduffield/lazygit/pkg/commands/models" - "github.com/stretchr/testify/assert" - "github.com/xo/terminfo" -) - -func init() { - color.ForceSetColorLevel(terminfo.ColorLevelNone) -} - -func TestRender(t *testing.T) { - scenarios := []struct { - name string - root *FileNode - collapsedPaths map[string]bool - expected []string - }{ - { - name: "nil node", - root: nil, - expected: []string{}, - }, - { - name: "leaf node", - root: &FileNode{ - Path: "", - Children: []*FileNode{ - {File: &models.File{Name: "test", ShortStatus: " M", HasStagedChanges: true}, Path: "test"}, - }, - }, - expected: []string{" M test"}, - }, - { - name: "big example", - root: &FileNode{ - Path: "", - Children: []*FileNode{ - { - Path: "dir1", - Children: []*FileNode{ - { - File: &models.File{Name: "dir1/file2", ShortStatus: "M ", HasUnstagedChanges: true}, - Path: "dir1/file2", - }, - { - File: &models.File{Name: "dir1/file3", ShortStatus: "M ", HasUnstagedChanges: true}, - Path: "dir1/file3", - }, - }, - }, - { - Path: "dir2", - Children: []*FileNode{ - { - Path: "dir2/dir2", - Children: []*FileNode{ - { - File: &models.File{Name: "dir2/dir2/file3", ShortStatus: " M", HasStagedChanges: true}, - Path: "dir2/dir2/file3", - }, - { - File: &models.File{Name: "dir2/dir2/file4", ShortStatus: "M ", HasUnstagedChanges: true}, - Path: "dir2/dir2/f |