Merge pull request #41 from knqyf263/filter

add filter
This commit is contained in:
Brian Buller 2020-03-30 16:24:09 -05:00 committed by GitHub
commit 19bf4d25d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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
}
func (bd *BoltDB) buildVisiblePathSlice() ([][]string, error) {
func (bd *BoltDB) buildVisiblePathSlice(filter 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{})
bktS, bktErr := bd.buckets[i].buildVisiblePathSlice([]string{}, filter)
if bktErr == nil {
retSlice = append(retSlice, bktS...)
} else {
@ -139,8 +139,30 @@ func (bd *BoltDB) buildVisiblePathSlice() ([][]string, error) {
return retSlice, retErr
}
func (bd *BoltDB) getPrevVisiblePath(path []string) []string {
visPaths, err := bd.buildVisiblePathSlice()
func (bd *BoltDB) isVisiblePath(path []string, filter string) bool {
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 len(visPaths) > 0 {
return visPaths[len(visPaths)-1]
@ -163,8 +185,8 @@ func (bd *BoltDB) getPrevVisiblePath(path []string) []string {
}
return nil
}
func (bd *BoltDB) getNextVisiblePath(path []string) []string {
visPaths, err := bd.buildVisiblePathSlice()
func (bd *BoltDB) getNextVisiblePath(path []string, filter string) []string {
visPaths, err := bd.buildVisiblePathSlice(filter)
if path == nil {
if len(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
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 retErr error
retSlice = append(retSlice, append(prefix, b.name))
if b.expanded {
// Add subbuckets
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 {
return retSlice, bktErr
}
@ -289,6 +311,9 @@ func (b *BoltBucket) buildVisiblePathSlice(prefix []string) ([][]string, error)
}
// Add 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))
}
}

View File

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