add filter

This commit is contained in:
knqyf263 2019-12-23 15:31:44 +02:00
parent 2970b1c912
commit 12b395ae2a
2 changed files with 92 additions and 37 deletions

View File

@ -123,12 +123,12 @@ func (bd *BoltDB) getVisibleItemCount(path []string) (int, error) {
return vis, retErr return vis, retErr
} }
func (bd *BoltDB) buildVisiblePathSlice() ([][]string, error) { func (bd *BoltDB) buildVisiblePathSlice(filter 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{}) bktS, bktErr := bd.buckets[i].buildVisiblePathSlice([]string{}, filter)
if bktErr == nil { if bktErr == nil {
retSlice = append(retSlice, bktS...) retSlice = append(retSlice, bktS...)
} else { } else {
@ -139,8 +139,30 @@ func (bd *BoltDB) buildVisiblePathSlice() ([][]string, error) {
return retSlice, retErr return retSlice, retErr
} }
func (bd *BoltDB) getPrevVisiblePath(path []string) []string { func (bd *BoltDB) isVisiblePath(path []string, filter string) bool {
visPaths, err := bd.buildVisiblePathSlice() visPaths, err := bd.buildVisiblePathSlice(filter)
if err != nil {
return false
}
for _, pth := range visPaths {
if len(pth) != len(path) {
continue
}
isVisible := true
for i := range path {
if path[i] != pth[i] {
isVisible = false
break
}
}
if isVisible {
return true
}
}
return false
}
func (bd *BoltDB) getPrevVisiblePath(path []string, filter string) []string {
visPaths, err := bd.buildVisiblePathSlice(filter)
if path == nil { if path == nil {
if len(visPaths) > 0 { if len(visPaths) > 0 {
return visPaths[len(visPaths)-1] return visPaths[len(visPaths)-1]
@ -163,8 +185,8 @@ func (bd *BoltDB) getPrevVisiblePath(path []string) []string {
} }
return nil return nil
} }
func (bd *BoltDB) getNextVisiblePath(path []string) []string { func (bd *BoltDB) getNextVisiblePath(path []string, filter string) []string {
visPaths, err := bd.buildVisiblePathSlice() visPaths, err := bd.buildVisiblePathSlice(filter)
if path == nil { if path == nil {
if len(visPaths) > 0 { if len(visPaths) > 0 {
return visPaths[0] return visPaths[0]
@ -274,14 +296,14 @@ 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) ([][]string, error) { func (b *BoltBucket) buildVisiblePathSlice(prefix []string, filter string) ([][]string, error) {
var retSlice [][]string var retSlice [][]string
var retErr error var retErr error
retSlice = append(retSlice, append(prefix, b.name)) retSlice = append(retSlice, append(prefix, b.name))
if b.expanded { if b.expanded {
// Add subbuckets // Add subbuckets
for i := range b.buckets { for i := range b.buckets {
bktS, bktErr := b.buckets[i].buildVisiblePathSlice(append(prefix, b.name)) bktS, bktErr := b.buckets[i].buildVisiblePathSlice(append(prefix, b.name), filter)
if bktErr != nil { if bktErr != nil {
return retSlice, bktErr return retSlice, bktErr
} }
@ -289,6 +311,9 @@ func (b *BoltBucket) buildVisiblePathSlice(prefix []string) ([][]string, error)
} }
// Add pairs // Add pairs
for i := range b.pairs { for i := range b.pairs {
if filter != "" && !strings.Contains(b.pairs[i].key, filter) {
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

@ -31,6 +31,7 @@ type BrowserScreen struct {
currentPath []string currentPath []string
currentType int currentType int
message string message string
filter string
mode BrowserMode mode BrowserMode
inputModal *termboxUtil.InputModal inputModal *termboxUtil.InputModal
confirmModal *termboxUtil.ConfirmModal confirmModal *termboxUtil.ConfirmModal
@ -51,6 +52,7 @@ const (
modeChange = 32 // 0000 0010 0000 modeChange = 32 // 0000 0010 0000
modeChangeKey = 33 // 0000 0010 0001 modeChangeKey = 33 // 0000 0010 0001
modeChangeVal = 34 // 0000 0010 0010 modeChangeVal = 34 // 0000 0010 0010
modeFilter = 35 // 0100 0010 0011
modeInsert = 64 // 0000 0100 0000 modeInsert = 64 // 0000 0100 0000
modeInsertBucket = 65 // 0000 0100 0001 modeInsertBucket = 65 // 0000 0100 0001
modeInsertPair = 68 // 0000 0100 0100 modeInsertPair = 68 // 0000 0100 0100
@ -102,11 +104,11 @@ func (screen *BrowserScreen) handleBrowseKeyEvent(event termbox.Event) int {
} else if event.Ch == 'g' { } else if event.Ch == 'g' {
// Jump to Beginning // Jump to Beginning
screen.currentPath = screen.db.getNextVisiblePath(nil) screen.currentPath = screen.db.getNextVisiblePath(nil, screen.filter)
} else if event.Ch == 'G' { } else if event.Ch == 'G' {
// Jump to End // Jump to End
screen.currentPath = screen.db.getPrevVisiblePath(nil) screen.currentPath = screen.db.getPrevVisiblePath(nil, screen.filter)
} else if event.Key == termbox.KeyCtrlR { } else if event.Key == termbox.KeyCtrlR {
screen.refreshDatabase() screen.refreshDatabase()
@ -155,6 +157,8 @@ func (screen *BrowserScreen) handleBrowseKeyEvent(event termbox.Event) int {
} else if p != nil { } else if p != nil {
screen.startEditItem() screen.startEditItem()
} }
} else if event.Ch == '/' {
screen.startFilter()
} else if event.Ch == 'r' { } else if event.Ch == 'r' {
screen.startRenameItem() screen.startRenameItem()
@ -216,6 +220,12 @@ func (screen *BrowserScreen) handleInputKeyEvent(event termbox.Event) int {
screen.inputModal.HandleEvent(event) screen.inputModal.HandleEvent(event)
if screen.inputModal.IsDone() { if screen.inputModal.IsDone() {
b, p, _ := screen.db.getGenericFromPath(screen.currentPath) b, p, _ := screen.db.getGenericFromPath(screen.currentPath)
if screen.mode == modeFilter {
screen.filter = screen.inputModal.GetValue()
if !screen.db.isVisiblePath(screen.currentPath, screen.filter) {
screen.currentPath = screen.currentPath[:len(screen.currentPath)-1]
}
}
if b != nil { if b != nil {
if screen.mode == modeChangeKey { if screen.mode == modeChangeKey {
newName := screen.inputModal.GetValue() newName := screen.inputModal.GetValue()
@ -261,8 +271,8 @@ func (screen *BrowserScreen) handleDeleteKeyEvent(event termbox.Event) int {
screen.confirmModal.HandleEvent(event) screen.confirmModal.HandleEvent(event)
if screen.confirmModal.IsDone() { if screen.confirmModal.IsDone() {
if screen.confirmModal.IsAccepted() { if screen.confirmModal.IsAccepted() {
holdNextPath := screen.db.getNextVisiblePath(screen.currentPath) holdNextPath := screen.db.getNextVisiblePath(screen.currentPath, screen.filter)
holdPrevPath := screen.db.getPrevVisiblePath(screen.currentPath) holdPrevPath := screen.db.getPrevVisiblePath(screen.currentPath, screen.filter)
if deleteKey(screen.currentPath) == nil { if deleteKey(screen.currentPath) == nil {
screen.refreshDatabase() screen.refreshDatabase()
// Move the current path endpoint appropriately // Move the current path endpoint appropriately
@ -400,7 +410,7 @@ func (screen *BrowserScreen) handleExportKeyEvent(event termbox.Event) int {
func (screen *BrowserScreen) jumpCursorUp(distance int) bool { func (screen *BrowserScreen) jumpCursorUp(distance int) bool {
// Jump up 'distance' lines // Jump up 'distance' lines
visPaths, err := screen.db.buildVisiblePathSlice() visPaths, err := screen.db.buildVisiblePathSlice(screen.filter)
if err == nil { if err == nil {
findPath := screen.currentPath findPath := screen.currentPath
for idx, pth := range visPaths { for idx, pth := range visPaths {
@ -426,13 +436,13 @@ func (screen *BrowserScreen) jumpCursorUp(distance int) bool {
} }
} }
if isCurPath { if isCurPath {
screen.currentPath = screen.db.getNextVisiblePath(nil) screen.currentPath = screen.db.getNextVisiblePath(nil, screen.filter)
} }
} }
return true return true
} }
func (screen *BrowserScreen) jumpCursorDown(distance int) bool { func (screen *BrowserScreen) jumpCursorDown(distance int) bool {
visPaths, err := screen.db.buildVisiblePathSlice() visPaths, err := screen.db.buildVisiblePathSlice(screen.filter)
if err == nil { if err == nil {
findPath := screen.currentPath findPath := screen.currentPath
for idx, pth := range visPaths { for idx, pth := range visPaths {
@ -459,14 +469,14 @@ func (screen *BrowserScreen) jumpCursorDown(distance int) bool {
} }
} }
if isCurPath { if isCurPath {
screen.currentPath = screen.db.getNextVisiblePath(nil) screen.currentPath = screen.db.getNextVisiblePath(nil, screen.filter)
} }
} }
return true return true
} }
func (screen *BrowserScreen) moveCursorUp() bool { func (screen *BrowserScreen) moveCursorUp() bool {
newPath := screen.db.getPrevVisiblePath(screen.currentPath) newPath := screen.db.getPrevVisiblePath(screen.currentPath, screen.filter)
if newPath != nil { if newPath != nil {
screen.currentPath = newPath screen.currentPath = newPath
return true return true
@ -474,7 +484,7 @@ func (screen *BrowserScreen) moveCursorUp() bool {
return false return false
} }
func (screen *BrowserScreen) moveCursorDown() bool { func (screen *BrowserScreen) moveCursorDown() bool {
newPath := screen.db.getNextVisiblePath(screen.currentPath) newPath := screen.db.getNextVisiblePath(screen.currentPath, screen.filter)
if newPath != nil { if newPath != nil {
screen.currentPath = newPath screen.currentPath = newPath
return true return true
@ -539,18 +549,18 @@ func (screen *BrowserScreen) drawFooter(style Style) {
func (screen *BrowserScreen) buildLeftPane(style Style) { func (screen *BrowserScreen) buildLeftPane(style Style) {
screen.leftPaneBuffer = nil screen.leftPaneBuffer = nil
if len(screen.currentPath) == 0 { if len(screen.currentPath) == 0 {
screen.currentPath = screen.db.getNextVisiblePath(nil) screen.currentPath = screen.db.getNextVisiblePath(nil, screen.filter)
} }
for i := range screen.db.buckets { for i := range screen.db.buckets {
screen.leftPaneBuffer = append(screen.leftPaneBuffer, screen.bucketToLines(&screen.db.buckets[i], style)...) screen.leftPaneBuffer = append(screen.leftPaneBuffer, screen.bucketToLines(&screen.db.buckets[i], style)...)
} }
// Find the cursor in the leftPane // Find the cursor in the leftPane
for k, v := range screen.leftPaneBuffer { for k, v := range screen.leftPaneBuffer {
if v.Fg == style.cursorFg { if v.Fg == style.cursorFg {
screen.leftViewPort.scrollRow = k screen.leftViewPort.scrollRow = k
break break
} }
} }
} }
func (screen *BrowserScreen) drawLeftPane(style Style) { func (screen *BrowserScreen) drawLeftPane(style Style) {
@ -562,19 +572,19 @@ func (screen *BrowserScreen) drawLeftPane(style Style) {
screen.leftViewPort.bytesPerRow = w screen.leftViewPort.bytesPerRow = w
screen.leftViewPort.numberOfRows = h - 2 screen.leftViewPort.numberOfRows = h - 2
termboxUtil.FillWithChar('=', 0, 1, w, 1, style.defaultFg, style.defaultBg) termboxUtil.FillWithChar('=', 0, 1, w, 1, style.defaultFg, style.defaultBg)
startX, startY := 0, 3 startX, startY := 0, 3
screen.leftViewPort.firstRow = startY screen.leftViewPort.firstRow = startY
treeOffset := 0 treeOffset := 0
maxCursor := screen.leftViewPort.numberOfRows * 2 / 3 maxCursor := screen.leftViewPort.numberOfRows * 2 / 3
if screen.leftViewPort.scrollRow > maxCursor { if screen.leftViewPort.scrollRow > maxCursor {
treeOffset = screen.leftViewPort.scrollRow - maxCursor treeOffset = screen.leftViewPort.scrollRow - maxCursor
} }
if len(screen.leftPaneBuffer) > 0 { if len(screen.leftPaneBuffer) > 0 {
for k, v := range screen.leftPaneBuffer[treeOffset:] { for k, v := range screen.leftPaneBuffer[treeOffset:] {
termboxUtil.DrawStringAtPoint(v.Text, startX, (startY + k - 1), v.Fg, v.Bg) termboxUtil.DrawStringAtPoint(v.Text, startX, (startY + k - 1), v.Fg, v.Bg)
} }
} }
} }
func (screen *BrowserScreen) buildRightPane(style Style) { func (screen *BrowserScreen) buildRightPane(style Style) {
@ -679,6 +689,9 @@ func (screen *BrowserScreen) bucketToLines(bkt *BoltBucket, style Style) []Line
ret = append(ret, screen.bucketToLines(&bkt.buckets[i], style)...) ret = append(ret, screen.bucketToLines(&bkt.buckets[i], style)...)
} }
for _, bp := range bkt.pairs { for _, bp := range bkt.pairs {
if screen.filter != "" && !strings.Contains(bp.key, screen.filter) {
continue
}
pfg, pbg := style.defaultFg, style.defaultBg pfg, pbg := style.defaultFg, style.defaultBg
if comparePaths(screen.currentPath, bp.GetPath()) { if comparePaths(screen.currentPath, bp.GetPath()) {
pfg, pbg = style.cursorFg, style.cursorBg pfg, pbg = style.cursorFg, style.cursorBg
@ -714,6 +727,23 @@ func (screen *BrowserScreen) startDeleteItem() bool {
return false return false
} }
func (screen *BrowserScreen) startFilter() bool {
_, _, e := screen.db.getGenericFromPath(screen.currentPath)
if e == nil {
w, h := termbox.Size()
inpW, inpH := (w / 2), 6
inpX, inpY := ((w / 2) - (inpW / 2)), ((h / 2) - inpH)
mod := termboxUtil.CreateInputModal("", inpX, inpY, inpW, inpH, termbox.ColorWhite, termbox.ColorBlack)
mod.SetTitle(termboxUtil.AlignText("Filter", inpW, termboxUtil.AlignCenter))
mod.SetValue(screen.filter)
mod.Show()
screen.inputModal = mod
screen.mode = modeFilter
return true
}
return false
}
func (screen *BrowserScreen) startEditItem() bool { func (screen *BrowserScreen) startEditItem() bool {
_, p, e := screen.db.getGenericFromPath(screen.currentPath) _, p, e := screen.db.getGenericFromPath(screen.currentPath)
if e == nil { if e == nil {