ability to hide files based on difftype

This commit is contained in:
Alex Goodman 2018-06-10 16:40:54 -04:00
parent 093f648cc2
commit 3602d7de31
No known key found for this signature in database
GPG Key ID: 05328C611D8A520E
7 changed files with 131 additions and 29 deletions

View File

@ -10,6 +10,7 @@ type FileNode struct {
Parent *FileNode Parent *FileNode
Name string Name string
Collapsed bool Collapsed bool
Hidden bool
Data *FileChangeInfo Data *FileChangeInfo
Children map[string]*FileNode Children map[string]*FileNode
} }

View File

@ -69,6 +69,9 @@ func (tree *FileTree) String() string {
sort.Strings(keys) sort.Strings(keys)
for idx, name := range keys { for idx, name := range keys {
child := node.Children[name] child := node.Children[name]
if child.Hidden {
continue
}
last := idx == (len(node.Children) - 1) last := idx == (len(node.Children) - 1)
showCollapsed := child.Collapsed && len(child.Children) > 0 showCollapsed := child.Collapsed && len(child.Children) > 0
result += renderLine(child.String(), spaces, last, showCollapsed) result += renderLine(child.String(), spaces, last, showCollapsed)

View File

@ -1,6 +1,7 @@
package ui package ui
import ( import (
"errors"
"fmt" "fmt"
"github.com/jroimartin/gocui" "github.com/jroimartin/gocui"
@ -14,6 +15,7 @@ type FileTreeView struct {
TreeIndex int TreeIndex int
Tree *filetree.FileTree Tree *filetree.FileTree
RefTrees []*filetree.FileTree RefTrees []*filetree.FileTree
HiddenDiffTypes []bool
} }
func NewFileTreeView(name string, gui *gocui.Gui, tree *filetree.FileTree, refTrees []*filetree.FileTree) (treeview *FileTreeView) { func NewFileTreeView(name string, gui *gocui.Gui, tree *filetree.FileTree, refTrees []*filetree.FileTree) (treeview *FileTreeView) {
@ -24,6 +26,7 @@ func NewFileTreeView(name string, gui *gocui.Gui, tree *filetree.FileTree, refTr
treeview.gui = gui treeview.gui = gui
treeview.Tree = tree treeview.Tree = tree
treeview.RefTrees = refTrees treeview.RefTrees = refTrees
treeview.HiddenDiffTypes = make([]bool, 4)
return treeview return treeview
} }
@ -37,6 +40,7 @@ func (view *FileTreeView) Setup(v *gocui.View) error {
view.view.Highlight = true view.view.Highlight = true
view.view.SelBgColor = gocui.ColorGreen view.view.SelBgColor = gocui.ColorGreen
view.view.SelFgColor = gocui.ColorBlack view.view.SelFgColor = gocui.ColorBlack
view.view.Frame = true
// set keybindings // set keybindings
if err := view.gui.SetKeybinding(view.Name, gocui.KeyArrowDown, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.CursorDown() }); err != nil { if err := view.gui.SetKeybinding(view.Name, gocui.KeyArrowDown, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.CursorDown() }); err != nil {
@ -48,6 +52,18 @@ func (view *FileTreeView) Setup(v *gocui.View) error {
if err := view.gui.SetKeybinding(view.Name, gocui.KeySpace, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.toggleCollapse() }); err != nil { if err := view.gui.SetKeybinding(view.Name, gocui.KeySpace, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.toggleCollapse() }); err != nil {
return err return err
} }
if err := view.gui.SetKeybinding(view.Name, gocui.KeyCtrlA, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.toggleShowDiffType(filetree.Added) }); err != nil {
return err
}
if err := view.gui.SetKeybinding(view.Name, gocui.KeyCtrlR, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.toggleShowDiffType(filetree.Removed) }); err != nil {
return err
}
if err := view.gui.SetKeybinding(view.Name, gocui.KeyCtrlM, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.toggleShowDiffType(filetree.Changed) }); err != nil {
return err
}
if err := view.gui.SetKeybinding(view.Name, gocui.KeyCtrlU, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.toggleShowDiffType(filetree.Unchanged) }); err != nil {
return err
}
view.Render() view.Render()
@ -55,20 +71,25 @@ func (view *FileTreeView) Setup(v *gocui.View) error {
} }
func (view *FileTreeView) setLayer(layerIndex int) error { func (view *FileTreeView) setLayer(layerIndex int) error {
if layerIndex > len(view.RefTrees)-1 {
return errors.New(fmt.Sprintf("Invalid layer index given: %d of %d", layerIndex, len(view.RefTrees)-1))
}
newTree := filetree.StackRange(view.RefTrees, layerIndex-1) newTree := filetree.StackRange(view.RefTrees, layerIndex-1)
newTree.Compare(view.RefTrees[layerIndex]) newTree.Compare(view.RefTrees[layerIndex])
// preserve view state on copy
visitor := func(node *filetree.FileNode) error { visitor := func(node *filetree.FileNode) error {
if node.Collapsed {
newNode, err := newTree.GetNode(node.Path()) newNode, err := newTree.GetNode(node.Path())
if err == nil { if err == nil {
newNode.Collapsed = true newNode.Collapsed = node.Collapsed
}
} }
return nil return nil
} }
view.Tree.Visit(visitor) view.Tree.Visit(visitor)
// now that the tree has been rebuilt, keep the view seleciton in parity with the previous selection
view.setHiddenFromDiffTypes()
// v, _ := view.gui.View("debug") // v, _ := view.gui.View("debug")
// v.Clear() // v.Clear()
// _, _ = fmt.Fprintln(v, view.RefTrees[layerIndex]) // _, _ = fmt.Fprintln(v, view.RefTrees[layerIndex])
@ -108,7 +129,7 @@ func (view *FileTreeView) getAbsPositionNode() (node *filetree.FileNode) {
} }
evaluator = func(curNode *filetree.FileNode) bool { evaluator = func(curNode *filetree.FileNode) bool {
return !curNode.Collapsed return !curNode.Collapsed && !curNode.Hidden
} }
err := view.Tree.VisitDepthParentFirst(visiter, evaluator) err := view.Tree.VisitDepthParentFirst(visiter, evaluator)
@ -125,6 +146,20 @@ func (view *FileTreeView) toggleCollapse() error {
return view.Render() return view.Render()
} }
func (view *FileTreeView) setHiddenFromDiffTypes() error {
visitor := func(node *filetree.FileNode) error {
node.Hidden = view.HiddenDiffTypes[node.Data.DiffType]
return nil
}
view.Tree.Visit(visitor)
return view.Render()
}
func (view *FileTreeView) toggleShowDiffType(diffType filetree.DiffType) error {
view.HiddenDiffTypes[diffType] = !view.HiddenDiffTypes[diffType]
return view.setHiddenFromDiffTypes()
}
func (view *FileTreeView) Render() error { func (view *FileTreeView) Render() error {
renderString := view.Tree.String() renderString := view.Tree.String()
view.gui.Update(func(g *gocui.Gui) error { view.gui.Update(func(g *gocui.Gui) error {

View File

@ -34,6 +34,7 @@ func (view *LayerView) Setup(v *gocui.View) error {
view.view.Highlight = true view.view.Highlight = true
view.view.SelBgColor = gocui.ColorGreen view.view.SelBgColor = gocui.ColorGreen
view.view.SelFgColor = gocui.ColorBlack view.view.SelFgColor = gocui.ColorBlack
view.view.Frame = false
// set keybindings // set keybindings
if err := view.gui.SetKeybinding(view.Name, gocui.KeyArrowDown, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.CursorDown() }); err != nil { if err := view.gui.SetKeybinding(view.Name, gocui.KeyArrowDown, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.CursorDown() }); err != nil {

54
ui/statusview.go Normal file
View File

@ -0,0 +1,54 @@
package ui
import (
"fmt"
"github.com/jroimartin/gocui"
)
type StatusView struct {
Name string
gui *gocui.Gui
view *gocui.View
}
func NewStatusView(name string, gui *gocui.Gui) (statusview *StatusView) {
statusview = new(StatusView)
// populate main fields
statusview.Name = name
statusview.gui = gui
return statusview
}
func (view *StatusView) Setup(v *gocui.View) error {
// set view options
view.view = v
view.view.Frame = false
view.view.BgColor = gocui.ColorDefault + gocui.AttrReverse
// set keybindings
// if err := view.gui.SetKeybinding(view.Name, gocui.KeyArrowDown, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.CursorDown() }); err != nil {
// return err
// }
// if err := view.gui.SetKeybinding(view.Name, gocui.KeyArrowUp, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.CursorUp() }); err != nil {
// return err
// }
view.Render()
return nil
}
func (view *StatusView) Render() error {
view.gui.Update(func(g *gocui.Gui) error {
view.view.Clear()
fmt.Fprintln(view.view, "[Ctrl+C]: Quit [Ctrl+Space]: Switch View | [Space]: Toggle dir collapse [A]: Added files [R]: Removed files [M]: Modified files [U]: Unmodified files")
return nil
})
// todo: blerg
return nil
}

View File

@ -11,6 +11,14 @@ import (
var Views struct { var Views struct {
Tree *FileTreeView Tree *FileTreeView
Layer *LayerView Layer *LayerView
Status *StatusView
}
type View interface {
Setup(*gocui.View) error
CursorDown() error
CursorUp() error
Render() error
} }
func nextView(g *gocui.Gui, v *gocui.View) error { func nextView(g *gocui.Gui, v *gocui.View) error {
@ -76,16 +84,17 @@ func keybindings(g *gocui.Gui) error {
func layout(g *gocui.Gui) error { func layout(g *gocui.Gui) error {
maxX, maxY := g.Size() maxX, maxY := g.Size()
splitCol := maxX / 2 splitCols := maxX / 2
debugCol := maxX - 0 debugCols := maxX - 0
if view, err := g.SetView(Views.Layer.Name, -1, -1, splitCol, maxY); err != nil { bottomRows := 1
if view, err := g.SetView(Views.Layer.Name, -1, -1, splitCols, maxY-bottomRows); err != nil {
if err != gocui.ErrUnknownView { if err != gocui.ErrUnknownView {
return err return err
} }
Views.Layer.Setup(view) Views.Layer.Setup(view)
} }
if view, err := g.SetView(Views.Tree.Name, splitCol, -1, debugCol, maxY); err != nil { if view, err := g.SetView(Views.Tree.Name, splitCols, -1, debugCols, maxY-bottomRows); err != nil {
if err != gocui.ErrUnknownView { if err != gocui.ErrUnknownView {
return err return err
} }
@ -96,7 +105,15 @@ func layout(g *gocui.Gui) error {
return err return err
} }
} }
// if _, err := g.SetView("debug", debugCol, -1, maxX, maxY); err != nil { if view, err := g.SetView(Views.Status.Name, -1, maxY-bottomRows-1, maxX, maxY); err != nil {
if err != gocui.ErrUnknownView {
return err
}
Views.Status.Setup(view)
}
// if _, err := g.SetView("debug", debugCol, -1, maxX, maxY-bottomRows); err != nil {
// if err != gocui.ErrUnknownView { // if err != gocui.ErrUnknownView {
// return err // return err
// } // }
@ -115,6 +132,7 @@ func Run(layers []*image.Layer, refTrees []*filetree.FileTree) {
Views.Layer = NewLayerView("side", g, layers) Views.Layer = NewLayerView("side", g, layers)
Views.Tree = NewFileTreeView("main", g, filetree.StackRange(refTrees, 0), refTrees) Views.Tree = NewFileTreeView("main", g, filetree.StackRange(refTrees, 0), refTrees)
Views.Status = NewStatusView("status", g)
g.Cursor = false g.Cursor = false
//g.Mouse = true //g.Mouse = true

View File

@ -1,10 +0,0 @@
package ui
import "github.com/jroimartin/gocui"
type View interface {
Setup(*gocui.View) error
CursorDown() error
CursorUp() error
Render() error
}