Some work, I guess
This commit is contained in:
parent
dce6e6c368
commit
22ffda8d13
@ -108,12 +108,12 @@ func (bd *BoltDB) GetPairFromPath(path []string) (*BoltPair, error) {
|
||||
return p, err
|
||||
}
|
||||
|
||||
func (bd *BoltDB) GetVisibleItemCount(path []string) (int, error) {
|
||||
func (bd *BoltDB) GetVisibleItemCount(path []string, search string) (int, error) {
|
||||
vis := 0
|
||||
var retErr error
|
||||
if len(path) == 0 {
|
||||
for i := range bd.buckets {
|
||||
n, err := bd.GetVisibleItemCount(bd.buckets[i].GetPath())
|
||||
n, err := bd.GetVisibleItemCount(bd.buckets[i].GetPath(), search)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -126,13 +126,13 @@ func (bd *BoltDB) GetVisibleItemCount(path []string) (int, error) {
|
||||
}
|
||||
// 1 for the bucket
|
||||
vis++
|
||||
if b.expanded {
|
||||
// This bucket is expanded, add up it's children
|
||||
if b.expanded || search != "" {
|
||||
// This bucket is expanded (or we're searching), add up it's children
|
||||
// * 1 for each pair
|
||||
vis += len(b.pairs)
|
||||
// * recurse for buckets
|
||||
for i := range b.buckets {
|
||||
n, err := bd.GetVisibleItemCount(b.buckets[i].GetPath())
|
||||
n, err := bd.GetVisibleItemCount(b.buckets[i].GetPath(), search)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -143,12 +143,12 @@ func (bd *BoltDB) GetVisibleItemCount(path []string) (int, error) {
|
||||
return vis, retErr
|
||||
}
|
||||
|
||||
func (bd *BoltDB) BuildVisiblePathSlice(filter string) ([][]string, error) {
|
||||
func (bd *BoltDB) BuildVisiblePathSlice(search string) ([][]string, error) {
|
||||
var retSlice [][]string
|
||||
var retErr error
|
||||
// The root path, recurse for root buckets
|
||||
for i := range bd.buckets {
|
||||
bktS, bktErr := bd.buckets[i].BuildVisiblePathSlice([]string{}, filter)
|
||||
bktS, bktErr := bd.buckets[i].BuildVisiblePathSlice([]string{}, search)
|
||||
if bktErr == nil {
|
||||
retSlice = append(retSlice, bktS...)
|
||||
} else {
|
||||
@ -159,8 +159,8 @@ func (bd *BoltDB) BuildVisiblePathSlice(filter string) ([][]string, error) {
|
||||
return retSlice, retErr
|
||||
}
|
||||
|
||||
func (bd *BoltDB) IsVisiblePath(path []string, filter string) bool {
|
||||
visPaths, err := bd.BuildVisiblePathSlice(filter)
|
||||
func (bd *BoltDB) IsVisiblePath(path []string, search string) bool {
|
||||
visPaths, err := bd.BuildVisiblePathSlice(search)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@ -181,8 +181,8 @@ func (bd *BoltDB) IsVisiblePath(path []string, filter string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func (bd *BoltDB) GetPrevVisiblePath(path []string, filter string) []string {
|
||||
visPaths, err := bd.BuildVisiblePathSlice(filter)
|
||||
func (bd *BoltDB) GetPrevVisiblePath(path []string, search string) []string {
|
||||
visPaths, err := bd.BuildVisiblePathSlice(search)
|
||||
if path == nil {
|
||||
if len(visPaths) > 0 {
|
||||
return visPaths[len(visPaths)-1]
|
||||
@ -205,8 +205,8 @@ func (bd *BoltDB) GetPrevVisiblePath(path []string, filter string) []string {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (bd *BoltDB) GetNextVisiblePath(path []string, filter string) []string {
|
||||
visPaths, err := bd.BuildVisiblePathSlice(filter)
|
||||
func (bd *BoltDB) GetNextVisiblePath(path []string, search string) []string {
|
||||
visPaths, err := bd.BuildVisiblePathSlice(search)
|
||||
if path == nil {
|
||||
if len(visPaths) > 0 {
|
||||
return visPaths[0]
|
||||
|
@ -38,14 +38,16 @@ func (b *BoltBucket) GetPath() []string {
|
||||
buildVisiblePathSlice builds a slice of string slices containing all visible paths in this bucket
|
||||
The passed prefix is the path leading to the current bucket
|
||||
*/
|
||||
func (b *BoltBucket) BuildVisiblePathSlice(prefix []string, filter string) ([][]string, error) {
|
||||
func (b *BoltBucket) BuildVisiblePathSlice(prefix []string, search string) ([][]string, error) {
|
||||
var retSlice [][]string
|
||||
var retErr error
|
||||
retSlice = append(retSlice, append(prefix, b.name))
|
||||
if b.expanded {
|
||||
if search == "" || strings.Contains(b.name, search) {
|
||||
retSlice = append(retSlice, append(prefix, b.name))
|
||||
}
|
||||
if b.expanded || search != "" {
|
||||
// Add subbuckets
|
||||
for i := range b.buckets {
|
||||
bktS, bktErr := b.buckets[i].BuildVisiblePathSlice(append(prefix, b.name), filter)
|
||||
bktS, bktErr := b.buckets[i].BuildVisiblePathSlice(append(prefix, b.name), search)
|
||||
if bktErr != nil {
|
||||
return retSlice, bktErr
|
||||
}
|
||||
@ -53,7 +55,7 @@ func (b *BoltBucket) BuildVisiblePathSlice(prefix []string, filter string) ([][]
|
||||
}
|
||||
// Add pairs
|
||||
for i := range b.pairs {
|
||||
if filter != "" && !strings.Contains(b.pairs[i].key, filter) {
|
||||
if search != "" && !strings.Contains(b.pairs[i].key, search) {
|
||||
continue
|
||||
}
|
||||
retSlice = append(retSlice, append(append(prefix, b.name), b.pairs[i].key))
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"git.bullercodeworks.com/brian/boltbrowser/models"
|
||||
"git.bullercodeworks.com/brian/boltbrowser/util"
|
||||
"git.bullercodeworks.com/brian/wandle"
|
||||
"git.bullercodeworks.com/brian/widdles"
|
||||
"github.com/nsf/termbox-go"
|
||||
)
|
||||
|
||||
@ -21,8 +22,7 @@ type BoltTreePane struct {
|
||||
pathBuffer [][]string
|
||||
currentPath []string
|
||||
currentPathIdx int
|
||||
filter string
|
||||
filterMode bool
|
||||
search *widdles.Field
|
||||
|
||||
insertPairCmd func(*models.BoltBucket) wandle.Cmd
|
||||
insertBucketCmd func(*models.BoltBucket) wandle.Cmd
|
||||
@ -46,6 +46,7 @@ func NewBoltTreePane(x, y, w, h int) *BoltTreePane {
|
||||
return &BoltTreePane{
|
||||
x: x, y: y,
|
||||
width: w, height: h,
|
||||
search: widdles.NewField("Search", "", x, y+h),
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,16 +54,18 @@ func (w *BoltTreePane) Init() wandle.Cmd {
|
||||
if w.db != nil {
|
||||
w.refreshDBAndBuffer()
|
||||
}
|
||||
w.search.SetWidth(w.width)
|
||||
return nil
|
||||
}
|
||||
func (w *BoltTreePane) SetDetailPane(pane *BoltDetailPane) { w.detailPane = pane }
|
||||
func (w *BoltTreePane) Measure() {}
|
||||
func (w *BoltTreePane) Measure() {
|
||||
}
|
||||
func (w *BoltTreePane) Update(msg wandle.Msg) wandle.Cmd {
|
||||
if w.db == nil {
|
||||
return nil
|
||||
}
|
||||
if len(w.currentPath) == 0 {
|
||||
w.currentPath = w.db.GetNextVisiblePath(nil, w.filter)
|
||||
w.currentPath = w.db.GetNextVisiblePath(nil, w.search.GetValue())
|
||||
}
|
||||
switch msg := msg.(type) {
|
||||
case BrowseMsg:
|
||||
@ -88,48 +91,65 @@ func (w *BoltTreePane) Update(msg wandle.Msg) wandle.Cmd {
|
||||
return nil
|
||||
}
|
||||
func (w *BoltTreePane) handleTermboxEvent(msg termbox.Event) wandle.Cmd {
|
||||
switch msg.Type {
|
||||
case termbox.EventKey:
|
||||
if msg.Ch == 'g' {
|
||||
return w.jumpToStart
|
||||
} else if msg.Ch == 'G' {
|
||||
return w.jumpToEnd
|
||||
} else if msg.Key == termbox.KeyCtrlF {
|
||||
return w.pageDown
|
||||
} else if msg.Key == termbox.KeyCtrlB {
|
||||
return w.pageUp
|
||||
} else if msg.Ch == 'j' || msg.Key == termbox.KeyArrowDown {
|
||||
return w.moveCursorDown
|
||||
} else if msg.Ch == 'k' || msg.Key == termbox.KeyArrowUp {
|
||||
return w.moveCursorUp
|
||||
} else if msg.Key == termbox.KeyCtrlR {
|
||||
return w.refreshDBAndBuffer
|
||||
} else if msg.Ch == 'p' {
|
||||
return w.insertPairAtCurrent
|
||||
} else if msg.Ch == 'P' {
|
||||
return w.insertPairAtParent
|
||||
} else if msg.Ch == 'b' {
|
||||
return w.insertBucketAtCurrent
|
||||
} else if msg.Ch == 'B' {
|
||||
return w.insertBucketAtParent
|
||||
} else if msg.Ch == 'e' {
|
||||
return w.editPairValue
|
||||
} else if msg.Ch == 'r' {
|
||||
return w.renameBucketOrPair
|
||||
} else if msg.Key == termbox.KeyEnter {
|
||||
return w.handleEnterPressed
|
||||
} else if msg.Ch == 'l' || msg.Key == termbox.KeyArrowRight {
|
||||
return w.handleRightPressed
|
||||
} else if msg.Ch == 'h' || msg.Key == termbox.KeyArrowLeft {
|
||||
return w.handleLeftPressed
|
||||
} else if msg.Ch == 'D' {
|
||||
return w.handleDelete
|
||||
} else if msg.Ch == 'x' {
|
||||
// TODO: Export Value
|
||||
} else if msg.Ch == 'X' {
|
||||
// TODO: Export Key/Value (or Bucket) as JSON
|
||||
} else if msg.Ch == '/' {
|
||||
// TODO: Start Filtering
|
||||
if w.search.IsActive() {
|
||||
if msg.Type == termbox.EventKey {
|
||||
if msg.Key == termbox.KeyEnter {
|
||||
return func() wandle.Msg {
|
||||
w.search.SetActive(false)
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
w.setStatus(w.search.Message, time.Second)
|
||||
return w.search.Update(msg)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch msg.Type {
|
||||
case termbox.EventKey:
|
||||
if msg.Ch == 'g' {
|
||||
return w.jumpToStart
|
||||
} else if msg.Ch == 'G' {
|
||||
return w.jumpToEnd
|
||||
} else if msg.Key == termbox.KeyCtrlF {
|
||||
return w.pageDown
|
||||
} else if msg.Key == termbox.KeyCtrlB {
|
||||
return w.pageUp
|
||||
} else if msg.Ch == 'j' || msg.Key == termbox.KeyArrowDown {
|
||||
return w.moveCursorDown
|
||||
} else if msg.Ch == 'k' || msg.Key == termbox.KeyArrowUp {
|
||||
return w.moveCursorUp
|
||||
} else if msg.Key == termbox.KeyCtrlR {
|
||||
return w.refreshDBAndBuffer
|
||||
} else if msg.Ch == 'p' {
|
||||
return w.insertPairAtCurrent
|
||||
} else if msg.Ch == 'P' {
|
||||
return w.insertPairAtParent
|
||||
} else if msg.Ch == 'b' {
|
||||
return w.insertBucketAtCurrent
|
||||
} else if msg.Ch == 'B' {
|
||||
return w.insertBucketAtParent
|
||||
} else if msg.Ch == 'e' {
|
||||
return w.editPairValue
|
||||
} else if msg.Ch == 'r' {
|
||||
return w.renameBucketOrPair
|
||||
} else if msg.Key == termbox.KeyEnter {
|
||||
return w.handleEnterPressed
|
||||
} else if msg.Ch == 'l' || msg.Key == termbox.KeyArrowRight {
|
||||
return w.handleRightPressed
|
||||
} else if msg.Ch == 'h' || msg.Key == termbox.KeyArrowLeft {
|
||||
return w.handleLeftPressed
|
||||
} else if msg.Ch == 'D' {
|
||||
return w.handleDelete
|
||||
} else if msg.Ch == 'x' {
|
||||
// TODO: Export Value
|
||||
} else if msg.Ch == 'X' {
|
||||
// TODO: Export Key/Value (or Bucket) as JSON
|
||||
} else if msg.Ch == '/' {
|
||||
return func() wandle.Msg {
|
||||
w.search.SetActive(true)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -145,6 +165,9 @@ func (w *BoltTreePane) View(style wandle.Style) {
|
||||
wandle.Print(midX, midY, style, txt)
|
||||
return
|
||||
}
|
||||
if w.search.IsActive() || w.search.GetValue() != "" {
|
||||
w.search.View(style)
|
||||
}
|
||||
// Find the cursor in the pane
|
||||
for k, v := range w.pathBuffer {
|
||||
if comparePaths(w.currentPath, v) {
|
||||
@ -230,9 +253,9 @@ func (w *BoltTreePane) RefreshBuffer() {
|
||||
for i := range buckets {
|
||||
w.buffer = append(w.buffer, buckets[i].Lines()...)
|
||||
}
|
||||
w.pathBuffer, _ = w.db.BuildVisiblePathSlice(w.filter)
|
||||
w.pathBuffer, _ = w.db.BuildVisiblePathSlice(w.search.GetValue())
|
||||
if len(w.currentPath) == 0 {
|
||||
w.currentPath = w.db.GetNextVisiblePath(nil, w.filter)
|
||||
w.currentPath = w.db.GetNextVisiblePath(nil, w.search.GetValue())
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,7 +283,7 @@ func (w *BoltTreePane) jumpCursorDown(distance int) {
|
||||
}
|
||||
}
|
||||
if isCurPath {
|
||||
w.currentPath = w.db.GetNextVisiblePath(nil, w.filter)
|
||||
w.currentPath = w.db.GetNextVisiblePath(nil, w.search.GetValue())
|
||||
}
|
||||
w.UpdateDetailPane()
|
||||
}
|
||||
@ -289,17 +312,17 @@ func (w *BoltTreePane) jumpCursorUp(distance int) {
|
||||
}
|
||||
}
|
||||
if isCurPath {
|
||||
w.currentPath = w.db.GetNextVisiblePath(nil, w.filter)
|
||||
w.currentPath = w.db.GetNextVisiblePath(nil, w.search.GetValue())
|
||||
}
|
||||
w.UpdateDetailPane()
|
||||
}
|
||||
func (w *BoltTreePane) jumpToStart() wandle.Msg {
|
||||
w.currentPath = w.db.GetNextVisiblePath(nil, w.filter)
|
||||
w.currentPath = w.db.GetNextVisiblePath(nil, w.search.GetValue())
|
||||
w.UpdateDetailPane()
|
||||
return nil
|
||||
}
|
||||
func (w *BoltTreePane) jumpToEnd() wandle.Msg {
|
||||
w.currentPath = w.db.GetPrevVisiblePath(nil, w.filter)
|
||||
w.currentPath = w.db.GetPrevVisiblePath(nil, w.search.GetValue())
|
||||
w.UpdateDetailPane()
|
||||
return nil
|
||||
}
|
||||
@ -314,7 +337,7 @@ func (w *BoltTreePane) pageDown() wandle.Msg {
|
||||
return nil
|
||||
}
|
||||
func (w *BoltTreePane) moveCursorUp() wandle.Msg {
|
||||
p := w.db.GetPrevVisiblePath(w.currentPath, w.filter)
|
||||
p := w.db.GetPrevVisiblePath(w.currentPath, w.search.GetValue())
|
||||
if p != nil {
|
||||
w.currentPath = p
|
||||
}
|
||||
@ -322,7 +345,7 @@ func (w *BoltTreePane) moveCursorUp() wandle.Msg {
|
||||
return nil
|
||||
}
|
||||
func (w *BoltTreePane) moveCursorDown() wandle.Msg {
|
||||
p := w.db.GetNextVisiblePath(w.currentPath, w.filter)
|
||||
p := w.db.GetNextVisiblePath(w.currentPath, w.search.GetValue())
|
||||
if p != nil {
|
||||
w.currentPath = p
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ func (s *browseScreen) Init() wandle.Cmd {
|
||||
}
|
||||
s.dbPath = dbs[dbidx]
|
||||
s.treePane = NewBoltTreePane(0, 3, s.width/2, s.height-6)
|
||||
s.treePane.Init()
|
||||
s.treePane.SetVisible(true)
|
||||
s.treePane.SetInsertPairCommand(s.insertPair)
|
||||
s.treePane.SetInsertBucketCommand(s.insertBucket)
|
||||
@ -143,6 +144,9 @@ func (s *browseScreen) handleTermboxEvent(msg termbox.Event) wandle.Cmd {
|
||||
return cmd
|
||||
}
|
||||
|
||||
if s.treePane.search.IsActive() {
|
||||
return s.treePane.Update(msg)
|
||||
}
|
||||
var cmds []wandle.Cmd
|
||||
cmds = append(cmds, s.treePane.Update(msg))
|
||||
cmds = append(cmds, s.detailPane.Update(msg))
|
||||
|
Loading…
Reference in New Issue
Block a user