mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-03-31 22:22:14 +02:00
support toggling collapsed
This commit is contained in:
parent
64217a8a5b
commit
a31db3df9c
@ -59,24 +59,26 @@ func (s *StatusLineNode) GetHasStagedChanges() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StatusLineNode) GetNodeAtIndex(index int) *StatusLineNode {
|
func (s *StatusLineNode) GetNodeAtIndex(index int, collapsedPaths map[string]bool) *StatusLineNode {
|
||||||
node, _ := s.getNodeAtIndexAux(index)
|
node, _ := s.getNodeAtIndexAux(index, collapsedPaths)
|
||||||
|
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StatusLineNode) getNodeAtIndexAux(index int) (*StatusLineNode, int) {
|
func (s *StatusLineNode) getNodeAtIndexAux(index int, collapsedPaths map[string]bool) (*StatusLineNode, int) {
|
||||||
offset := 1
|
offset := 1
|
||||||
|
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
return s, offset
|
return s, offset
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, child := range s.Children {
|
if !collapsedPaths[s.GetPath()] {
|
||||||
node, offsetChange := child.getNodeAtIndexAux(index - offset)
|
for _, child := range s.Children {
|
||||||
offset += offsetChange
|
node, offsetChange := child.getNodeAtIndexAux(index-offset, collapsedPaths)
|
||||||
if node != nil {
|
offset += offsetChange
|
||||||
return node, offset
|
if node != nil {
|
||||||
|
return node, offset
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,21 +89,25 @@ func (s *StatusLineNode) IsLeaf() bool {
|
|||||||
return len(s.Children) == 0
|
return len(s.Children) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StatusLineNode) Size() int {
|
func (s *StatusLineNode) Size(collapsedPaths map[string]bool) int {
|
||||||
output := 1
|
output := 1
|
||||||
|
|
||||||
for _, child := range s.Children {
|
if !collapsedPaths[s.GetPath()] {
|
||||||
output += child.Size()
|
for _, child := range s.Children {
|
||||||
|
output += child.Size(collapsedPaths)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StatusLineNode) Flatten() []*StatusLineNode {
|
func (s *StatusLineNode) Flatten(collapsedPaths map[string]bool) []*StatusLineNode {
|
||||||
arr := []*StatusLineNode{s}
|
arr := []*StatusLineNode{s}
|
||||||
|
|
||||||
for _, child := range s.Children {
|
if !collapsedPaths[s.GetPath()] {
|
||||||
arr = append(arr, child.Flatten()...)
|
for _, child := range s.Children {
|
||||||
|
arr = append(arr, child.Flatten(collapsedPaths)...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return arr
|
return arr
|
||||||
|
@ -182,11 +182,17 @@ func (gui *Gui) handleEnterFile(g *gocui.Gui, v *gocui.View) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) enterFile(forceSecondaryFocused bool, selectedLineIdx int) error {
|
func (gui *Gui) enterFile(forceSecondaryFocused bool, selectedLineIdx int) error {
|
||||||
file := gui.getSelectedFile()
|
node := gui.getSelectedStatusNode()
|
||||||
if file == nil {
|
if node == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if node.File == nil {
|
||||||
|
return gui.handleToggleDirCollapsed()
|
||||||
|
}
|
||||||
|
|
||||||
|
file := node.File
|
||||||
|
|
||||||
submoduleConfigs := gui.State.Submodules
|
submoduleConfigs := gui.State.Submodules
|
||||||
if file.IsSubmodule(submoduleConfigs) {
|
if file.IsSubmodule(submoduleConfigs) {
|
||||||
submoduleConfig := file.SubmoduleConfig(submoduleConfigs)
|
submoduleConfig := file.SubmoduleConfig(submoduleConfigs)
|
||||||
@ -742,3 +748,18 @@ func (gui *Gui) handleStashChanges(g *gocui.Gui, v *gocui.View) error {
|
|||||||
func (gui *Gui) handleCreateResetToUpstreamMenu(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleCreateResetToUpstreamMenu(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gui.createResetMenu("@{upstream}")
|
return gui.createResetMenu("@{upstream}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) handleToggleDirCollapsed() error {
|
||||||
|
node := gui.getSelectedStatusNode()
|
||||||
|
if node == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
gui.State.StatusLineManager.ToggleCollapsed(node)
|
||||||
|
|
||||||
|
if err := gui.postRefreshUpdate(gui.Contexts.Files.Context); err != nil {
|
||||||
|
gui.Log.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -378,7 +378,7 @@ func (gui *Gui) resetState() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gui.State = &guiState{
|
gui.State = &guiState{
|
||||||
StatusLineManager: &StatusLineManager{Files: make([]*models.File, 0), Log: gui.Log, TreeMode: true},
|
StatusLineManager: NewStatusLineManager(make([]*models.File, 0), gui.Log),
|
||||||
Commits: make([]*models.Commit, 0),
|
Commits: make([]*models.Commit, 0),
|
||||||
FilteredReflogCommits: make([]*models.Commit, 0),
|
FilteredReflogCommits: make([]*models.Commit, 0),
|
||||||
ReflogCommits: make([]*models.Commit, 0),
|
ReflogCommits: make([]*models.Commit, 0),
|
||||||
|
@ -13,16 +13,26 @@ const EXPANDED_ARROW = "▼"
|
|||||||
const COLLAPSED_ARROW = "►"
|
const COLLAPSED_ARROW = "►"
|
||||||
|
|
||||||
type StatusLineManager struct {
|
type StatusLineManager struct {
|
||||||
Files []*models.File
|
Files []*models.File
|
||||||
Tree *models.StatusLineNode
|
Tree *models.StatusLineNode
|
||||||
TreeMode bool
|
TreeMode bool
|
||||||
Log *logrus.Entry
|
Log *logrus.Entry
|
||||||
|
CollapsedPaths map[string]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStatusLineManager(files []*models.File, log *logrus.Entry) *StatusLineManager {
|
||||||
|
return &StatusLineManager{
|
||||||
|
Files: files,
|
||||||
|
Log: log,
|
||||||
|
TreeMode: true, // always true for now
|
||||||
|
CollapsedPaths: map[string]bool{},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *StatusLineManager) GetItemAtIndex(index int) *models.StatusLineNode {
|
func (m *StatusLineManager) GetItemAtIndex(index int) *models.StatusLineNode {
|
||||||
if m.TreeMode {
|
if m.TreeMode {
|
||||||
// need to traverse the three depth first until we get to the index.
|
// need to traverse the three depth first until we get to the index.
|
||||||
return m.Tree.GetNodeAtIndex(index + 1) // ignoring root
|
return m.Tree.GetNodeAtIndex(index+1, m.CollapsedPaths) // ignoring root
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Log.Warn(index)
|
m.Log.Warn(index)
|
||||||
@ -34,11 +44,11 @@ func (m *StatusLineManager) GetItemAtIndex(index int) *models.StatusLineNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *StatusLineManager) GetAllItems() []*models.StatusLineNode {
|
func (m *StatusLineManager) GetAllItems() []*models.StatusLineNode {
|
||||||
return m.Tree.Flatten()[1:] // ignoring root
|
return m.Tree.Flatten(m.CollapsedPaths)[1:] // ignoring root
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *StatusLineManager) GetItemsLength() int {
|
func (m *StatusLineManager) GetItemsLength() int {
|
||||||
return m.Tree.Size() - 1 // ignoring root
|
return m.Tree.Size(m.CollapsedPaths) - 1 // ignoring root
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *StatusLineManager) GetAllFiles() []*models.File {
|
func (m *StatusLineManager) GetAllFiles() []*models.File {
|
||||||
@ -59,6 +69,14 @@ const LAST_ITEM = "└─ "
|
|||||||
const NESTED = "│ "
|
const NESTED = "│ "
|
||||||
const NOTHING = " "
|
const NOTHING = " "
|
||||||
|
|
||||||
|
func (m *StatusLineManager) IsCollapsed(s *models.StatusLineNode) bool {
|
||||||
|
return m.CollapsedPaths[s.GetPath()]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *StatusLineManager) ToggleCollapsed(s *models.StatusLineNode) {
|
||||||
|
m.CollapsedPaths[s.GetPath()] = !m.CollapsedPaths[s.GetPath()]
|
||||||
|
}
|
||||||
|
|
||||||
func (m *StatusLineManager) renderAux(s *models.StatusLineNode, prefix string, depth int, diffName string, submoduleConfigs []*models.SubmoduleConfig) []string {
|
func (m *StatusLineManager) renderAux(s *models.StatusLineNode, prefix string, depth int, diffName string, submoduleConfigs []*models.SubmoduleConfig) []string {
|
||||||
isRoot := depth == -1
|
isRoot := depth == -1
|
||||||
if s == nil {
|
if s == nil {
|
||||||
@ -76,7 +94,7 @@ func (m *StatusLineManager) renderAux(s *models.StatusLineNode, prefix string, d
|
|||||||
return []string{getLine()}
|
return []string{getLine()}
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Collapsed {
|
if m.IsCollapsed(s) {
|
||||||
return []string{fmt.Sprintf("%s %s", getLine(), COLLAPSED_ARROW)}
|
return []string{fmt.Sprintf("%s %s", getLine(), COLLAPSED_ARROW)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -862,7 +862,7 @@ func englishTranslationSet() TranslationSet {
|
|||||||
ViewPatchOptions: "view custom patch options",
|
ViewPatchOptions: "view custom patch options",
|
||||||
PatchOptionsTitle: "Patch Options",
|
PatchOptionsTitle: "Patch Options",
|
||||||
NoPatchError: "No patch created yet. To start building a patch, use 'space' on a commit file or enter to add specific lines",
|
NoPatchError: "No patch created yet. To start building a patch, use 'space' on a commit file or enter to add specific lines",
|
||||||
LcEnterFile: "enter file to add selected lines to the patch",
|
LcEnterFile: "enter file to add selected lines to the patch (or toggle directory collapsed)",
|
||||||
ExitLineByLineMode: `exit line-by-line mode`,
|
ExitLineByLineMode: `exit line-by-line mode`,
|
||||||
EnterUpstream: `Enter upstream as '<remote> <branchname>'`,
|
EnterUpstream: `Enter upstream as '<remote> <branchname>'`,
|
||||||
EnterUpstreamWithSlash: `Enter upstream as '<remote>/<branchname>'`,
|
EnterUpstreamWithSlash: `Enter upstream as '<remote>/<branchname>'`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user