ability to hide files based on difftype
This commit is contained in:
parent
093f648cc2
commit
3602d7de31
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/jroimartin/gocui"
|
"github.com/jroimartin/gocui"
|
||||||
@ -8,12 +9,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type FileTreeView struct {
|
type FileTreeView struct {
|
||||||
Name string
|
Name string
|
||||||
gui *gocui.Gui
|
gui *gocui.Gui
|
||||||
view *gocui.View
|
view *gocui.View
|
||||||
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 = node.Collapsed
|
||||||
newNode.Collapsed = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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 {
|
||||||
|
@ -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
54
ui/statusview.go
Normal 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
|
||||||
|
}
|
32
ui/ui.go
32
ui/ui.go
@ -9,8 +9,16 @@ 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
|
||||||
|
10
ui/view.go
10
ui/view.go
@ -1,10 +0,0 @@
|
|||||||
package ui
|
|
||||||
|
|
||||||
import "github.com/jroimartin/gocui"
|
|
||||||
|
|
||||||
type View interface {
|
|
||||||
Setup(*gocui.View) error
|
|
||||||
CursorDown() error
|
|
||||||
CursorUp() error
|
|
||||||
Render() error
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user