Some work, I guess

This commit is contained in:
Brian Buller 2022-11-18 13:43:52 -06:00
parent dce6e6c368
commit 22ffda8d13
4 changed files with 101 additions and 72 deletions

View File

@ -108,12 +108,12 @@ func (bd *BoltDB) GetPairFromPath(path []string) (*BoltPair, error) {
return p, err return p, err
} }
func (bd *BoltDB) GetVisibleItemCount(path []string) (int, error) { func (bd *BoltDB) GetVisibleItemCount(path []string, search string) (int, error) {
vis := 0 vis := 0
var retErr error var retErr error
if len(path) == 0 { if len(path) == 0 {
for i := range bd.buckets { 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 { if err != nil {
return 0, err return 0, err
} }
@ -126,13 +126,13 @@ func (bd *BoltDB) GetVisibleItemCount(path []string) (int, error) {
} }
// 1 for the bucket // 1 for the bucket
vis++ vis++
if b.expanded { if b.expanded || search != "" {
// This bucket is expanded, add up it's children // This bucket is expanded (or we're searching), add up it's children
// * 1 for each pair // * 1 for each pair
vis += len(b.pairs) vis += len(b.pairs)
// * recurse for buckets // * recurse for buckets
for i := range b.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 { if err != nil {
return 0, err return 0, err
} }
@ -143,12 +143,12 @@ func (bd *BoltDB) GetVisibleItemCount(path []string) (int, error) {
return vis, retErr return vis, retErr
} }
func (bd *BoltDB) BuildVisiblePathSlice(filter string) ([][]string, error) { func (bd *BoltDB) BuildVisiblePathSlice(search string) ([][]string, error) {
var retSlice [][]string var retSlice [][]string
var retErr error var retErr error
// The root path, recurse for root buckets // The root path, recurse for root buckets
for i := range bd.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 { if bktErr == nil {
retSlice = append(retSlice, bktS...) retSlice = append(retSlice, bktS...)
} else { } else {
@ -159,8 +159,8 @@ func (bd *BoltDB) BuildVisiblePathSlice(filter string) ([][]string, error) {
return retSlice, retErr return retSlice, retErr
} }
func (bd *BoltDB) IsVisiblePath(path []string, filter string) bool { func (bd *BoltDB) IsVisiblePath(path []string, search string) bool {
visPaths, err := bd.BuildVisiblePathSlice(filter) visPaths, err := bd.BuildVisiblePathSlice(search)
if err != nil { if err != nil {
return false return false
} }
@ -181,8 +181,8 @@ func (bd *BoltDB) IsVisiblePath(path []string, filter string) bool {
} }
return false return false
} }
func (bd *BoltDB) GetPrevVisiblePath(path []string, filter string) []string { func (bd *BoltDB) GetPrevVisiblePath(path []string, search string) []string {
visPaths, err := bd.BuildVisiblePathSlice(filter) visPaths, err := bd.BuildVisiblePathSlice(search)
if path == nil { if path == nil {
if len(visPaths) > 0 { if len(visPaths) > 0 {
return visPaths[len(visPaths)-1] return visPaths[len(visPaths)-1]
@ -205,8 +205,8 @@ func (bd *BoltDB) GetPrevVisiblePath(path []string, filter string) []string {
} }
return nil return nil
} }
func (bd *BoltDB) GetNextVisiblePath(path []string, filter string) []string { func (bd *BoltDB) GetNextVisiblePath(path []string, search string) []string {
visPaths, err := bd.BuildVisiblePathSlice(filter) visPaths, err := bd.BuildVisiblePathSlice(search)
if path == nil { if path == nil {
if len(visPaths) > 0 { if len(visPaths) > 0 {
return visPaths[0] return visPaths[0]

View File

@ -38,14 +38,16 @@ func (b *BoltBucket) GetPath() []string {
buildVisiblePathSlice builds a slice of string slices containing all visible paths in this bucket 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 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 retSlice [][]string
var retErr error var retErr error
if search == "" || strings.Contains(b.name, search) {
retSlice = append(retSlice, append(prefix, b.name)) retSlice = append(retSlice, append(prefix, b.name))
if b.expanded { }
if b.expanded || search != "" {
// Add subbuckets // Add subbuckets
for i := range b.buckets { 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 { if bktErr != nil {
return retSlice, bktErr return retSlice, bktErr
} }
@ -53,7 +55,7 @@ func (b *BoltBucket) BuildVisiblePathSlice(prefix []string, filter string) ([][]
} }
// Add pairs // Add pairs
for i := range b.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 continue
} }
retSlice = append(retSlice, append(append(prefix, b.name), b.pairs[i].key)) retSlice = append(retSlice, append(append(prefix, b.name), b.pairs[i].key))

View File

@ -6,6 +6,7 @@ import (
"git.bullercodeworks.com/brian/boltbrowser/models" "git.bullercodeworks.com/brian/boltbrowser/models"
"git.bullercodeworks.com/brian/boltbrowser/util" "git.bullercodeworks.com/brian/boltbrowser/util"
"git.bullercodeworks.com/brian/wandle" "git.bullercodeworks.com/brian/wandle"
"git.bullercodeworks.com/brian/widdles"
"github.com/nsf/termbox-go" "github.com/nsf/termbox-go"
) )
@ -21,8 +22,7 @@ type BoltTreePane struct {
pathBuffer [][]string pathBuffer [][]string
currentPath []string currentPath []string
currentPathIdx int currentPathIdx int
filter string search *widdles.Field
filterMode bool
insertPairCmd func(*models.BoltBucket) wandle.Cmd insertPairCmd func(*models.BoltBucket) wandle.Cmd
insertBucketCmd 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{ return &BoltTreePane{
x: x, y: y, x: x, y: y,
width: w, height: h, 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 { if w.db != nil {
w.refreshDBAndBuffer() w.refreshDBAndBuffer()
} }
w.search.SetWidth(w.width)
return nil return nil
} }
func (w *BoltTreePane) SetDetailPane(pane *BoltDetailPane) { w.detailPane = pane } 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 { func (w *BoltTreePane) Update(msg wandle.Msg) wandle.Cmd {
if w.db == nil { if w.db == nil {
return nil return nil
} }
if len(w.currentPath) == 0 { 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) { switch msg := msg.(type) {
case BrowseMsg: case BrowseMsg:
@ -88,6 +91,19 @@ func (w *BoltTreePane) Update(msg wandle.Msg) wandle.Cmd {
return nil return nil
} }
func (w *BoltTreePane) handleTermboxEvent(msg termbox.Event) wandle.Cmd { func (w *BoltTreePane) handleTermboxEvent(msg termbox.Event) wandle.Cmd {
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 { switch msg.Type {
case termbox.EventKey: case termbox.EventKey:
if msg.Ch == 'g' { if msg.Ch == 'g' {
@ -129,7 +145,11 @@ func (w *BoltTreePane) handleTermboxEvent(msg termbox.Event) wandle.Cmd {
} else if msg.Ch == 'X' { } else if msg.Ch == 'X' {
// TODO: Export Key/Value (or Bucket) as JSON // TODO: Export Key/Value (or Bucket) as JSON
} else if msg.Ch == '/' { } else if msg.Ch == '/' {
// TODO: Start Filtering return func() wandle.Msg {
w.search.SetActive(true)
return nil
}
}
} }
} }
return nil return nil
@ -145,6 +165,9 @@ func (w *BoltTreePane) View(style wandle.Style) {
wandle.Print(midX, midY, style, txt) wandle.Print(midX, midY, style, txt)
return return
} }
if w.search.IsActive() || w.search.GetValue() != "" {
w.search.View(style)
}
// Find the cursor in the pane // Find the cursor in the pane
for k, v := range w.pathBuffer { for k, v := range w.pathBuffer {
if comparePaths(w.currentPath, v) { if comparePaths(w.currentPath, v) {
@ -230,9 +253,9 @@ func (w *BoltTreePane) RefreshBuffer() {
for i := range buckets { for i := range buckets {
w.buffer = append(w.buffer, buckets[i].Lines()...) 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 { 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 { if isCurPath {
w.currentPath = w.db.GetNextVisiblePath(nil, w.filter) w.currentPath = w.db.GetNextVisiblePath(nil, w.search.GetValue())
} }
w.UpdateDetailPane() w.UpdateDetailPane()
} }
@ -289,17 +312,17 @@ func (w *BoltTreePane) jumpCursorUp(distance int) {
} }
} }
if isCurPath { if isCurPath {
w.currentPath = w.db.GetNextVisiblePath(nil, w.filter) w.currentPath = w.db.GetNextVisiblePath(nil, w.search.GetValue())
} }
w.UpdateDetailPane() w.UpdateDetailPane()
} }
func (w *BoltTreePane) jumpToStart() wandle.Msg { 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() w.UpdateDetailPane()
return nil return nil
} }
func (w *BoltTreePane) jumpToEnd() wandle.Msg { 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() w.UpdateDetailPane()
return nil return nil
} }
@ -314,7 +337,7 @@ func (w *BoltTreePane) pageDown() wandle.Msg {
return nil return nil
} }
func (w *BoltTreePane) moveCursorUp() wandle.Msg { 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 { if p != nil {
w.currentPath = p w.currentPath = p
} }
@ -322,7 +345,7 @@ func (w *BoltTreePane) moveCursorUp() wandle.Msg {
return nil return nil
} }
func (w *BoltTreePane) moveCursorDown() wandle.Msg { 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 { if p != nil {
w.currentPath = p w.currentPath = p
} }

View File

@ -75,6 +75,7 @@ func (s *browseScreen) Init() wandle.Cmd {
} }
s.dbPath = dbs[dbidx] s.dbPath = dbs[dbidx]
s.treePane = NewBoltTreePane(0, 3, s.width/2, s.height-6) s.treePane = NewBoltTreePane(0, 3, s.width/2, s.height-6)
s.treePane.Init()
s.treePane.SetVisible(true) s.treePane.SetVisible(true)
s.treePane.SetInsertPairCommand(s.insertPair) s.treePane.SetInsertPairCommand(s.insertPair)
s.treePane.SetInsertBucketCommand(s.insertBucket) s.treePane.SetInsertBucketCommand(s.insertBucket)
@ -143,6 +144,9 @@ func (s *browseScreen) handleTermboxEvent(msg termbox.Event) wandle.Cmd {
return cmd return cmd
} }
if s.treePane.search.IsActive() {
return s.treePane.Update(msg)
}
var cmds []wandle.Cmd var cmds []wandle.Cmd
cmds = append(cmds, s.treePane.Update(msg)) cmds = append(cmds, s.treePane.Update(msg))
cmds = append(cmds, s.detailPane.Update(msg)) cmds = append(cmds, s.detailPane.Update(msg))