Refactor to use separate path vars

pull/186/head
Anton Medvedev 2 years ago
parent d682c0b49f
commit 841eb4f1b5

@ -1,20 +1,14 @@
package main package main
type dict struct { type dict struct {
keys []string keys []string
indexes map[string]int values map[string]interface{}
values map[string]interface{}
} }
func newDict() *dict { func newDict() *dict {
return newDictOfCapacity(0)
}
func newDictOfCapacity(capacity int) *dict {
return &dict{ return &dict{
keys: make([]string, 0, capacity), keys: make([]string, 0),
indexes: make(map[string]int, capacity), values: make(map[string]interface{}),
values: make(map[string]interface{}, capacity),
} }
} }
@ -23,15 +17,9 @@ func (d *dict) get(key string) (interface{}, bool) {
return val, exists return val, exists
} }
func (d *dict) index(key string) (int, bool) {
index, exists := d.indexes[key]
return index, exists
}
func (d *dict) set(key string, value interface{}) { func (d *dict) set(key string, value interface{}) {
_, exists := d.values[key] _, exists := d.values[key]
if !exists { if !exists {
d.indexes[key] = len(d.keys)
d.keys = append(d.keys, key) d.keys = append(d.keys, key)
} }
d.values[key] = value d.values[key] = value

@ -9,20 +9,12 @@ func Test_dict(t *testing.T) {
if v.(int) != 3 { if v.(int) != 3 {
t.Error("Set number") t.Error("Set number")
} }
i, _ := d.index("number")
if i != 0 {
t.Error("Index error")
}
// string // string
d.set("string", "x") d.set("string", "x")
v, _ = d.get("string") v, _ = d.get("string")
if v.(string) != "x" { if v.(string) != "x" {
t.Error("Set string") t.Error("Set string")
} }
i, _ = d.index("string")
if i != 1 {
t.Error("Index error")
}
// string slice // string slice
d.set("strings", []string{ d.set("strings", []string{
"t", "t",
@ -35,10 +27,6 @@ func Test_dict(t *testing.T) {
if v.([]string)[1] != "u" { if v.([]string)[1] != "u" {
t.Error("Set strings second index") t.Error("Set strings second index")
} }
i, _ = d.index("strings")
if i != 2 {
t.Error("Index error")
}
// mixed slice // mixed slice
d.set("mixed", []interface{}{ d.set("mixed", []interface{}{
1, 1,

@ -137,14 +137,16 @@ type model struct {
keyMap KeyMap keyMap KeyMap
showHelp bool showHelp bool
expandedPaths map[string]bool // a set with expanded paths expandedPaths map[string]bool // set of expanded paths
canBeExpanded map[string]bool // a set for path => can be expanded (i.e. dict or array) canBeExpanded map[string]bool // set of path => can be expanded (i.e. dict or array)
pathToLineNumber *dict // dict with path => line number paths []string // array of paths on screen
pathToLineNumber map[string]int // map of path => line number
pathToIndex map[string]int // map of path => index in m.paths
lineNumberToPath map[int]string // map of line number => path lineNumberToPath map[int]string // map of line number => path
parents map[string]string // map of subpath => parent path parents map[string]string // map of subpath => parent path
children map[string][]string // map of path => child paths children map[string][]string // map of path => child paths
nextSiblings, prevSiblings map[string]string // map of path => sibling path nextSiblings, prevSiblings map[string]string // map of path => sibling path
cursor int // cursor in range of m.pathToLineNumber.keys slice cursor int // cursor in [0, len(m.paths)]
showCursor bool showCursor bool
searchInput textinput.Model searchInput textinput.Model
@ -253,9 +255,8 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case key.Matches(msg, m.keyMap.NextSibling): case key.Matches(msg, m.keyMap.NextSibling):
nextSiblingPath, ok := m.nextSiblings[m.cursorPath()] nextSiblingPath, ok := m.nextSiblings[m.cursorPath()]
if ok { if ok {
index, _ := m.pathToLineNumber.indexes[nextSiblingPath]
m.showCursor = true m.showCursor = true
m.cursor = index m.cursor = m.pathToIndex[nextSiblingPath]
} else { } else {
m.down() m.down()
} }
@ -265,9 +266,8 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case key.Matches(msg, m.keyMap.PrevSibling): case key.Matches(msg, m.keyMap.PrevSibling):
prevSiblingPath, ok := m.prevSiblings[m.cursorPath()] prevSiblingPath, ok := m.prevSiblings[m.cursorPath()]
if ok { if ok {
index, _ := m.pathToLineNumber.indexes[prevSiblingPath]
m.showCursor = true m.showCursor = true
m.cursor = index m.cursor = m.pathToIndex[prevSiblingPath]
} else { } else {
m.up() m.up()
} }
@ -296,8 +296,7 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
parentPath, ok := m.parents[m.cursorPath()] parentPath, ok := m.parents[m.cursorPath()]
if ok { if ok {
m.expandedPaths[parentPath] = false m.expandedPaths[parentPath] = false
index, _ := m.pathToLineNumber.index(parentPath) m.cursor = m.pathToIndex[parentPath]
m.cursor = index
} }
} }
m.render() m.render()
@ -311,8 +310,7 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
parentPath, ok := m.parents[m.cursorPath()] parentPath, ok := m.parents[m.cursorPath()]
if ok { if ok {
m.collapseRecursively(parentPath) m.collapseRecursively(parentPath)
index, _ := m.pathToLineNumber.index(parentPath) m.cursor = m.pathToIndex[parentPath]
m.cursor = index
} }
} }
m.render() m.render()
@ -363,8 +361,7 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if m.canBeExpanded[clickedPath] { if m.canBeExpanded[clickedPath] {
m.expandedPaths[clickedPath] = !m.expandedPaths[clickedPath] m.expandedPaths[clickedPath] = !m.expandedPaths[clickedPath]
} }
index, _ := m.pathToLineNumber.index(clickedPath) m.cursor = m.pathToIndex[clickedPath]
m.cursor = index
m.render() m.render()
} }
} }
@ -429,10 +426,12 @@ func (m *model) render() {
return return
} }
m.paths = make([]string, 0)
m.pathToIndex = make(map[string]int, 0)
if m.pathToLineNumber == nil { if m.pathToLineNumber == nil {
m.pathToLineNumber = newDict() m.pathToLineNumber = make(map[string]int, 0)
} else { } else {
m.pathToLineNumber = newDictOfCapacity(cap(m.pathToLineNumber.keys)) m.pathToLineNumber = make(map[string]int, len(m.pathToLineNumber))
} }
if m.lineNumberToPath == nil { if m.lineNumberToPath == nil {
m.lineNumberToPath = make(map[int]string, 0) m.lineNumberToPath = make(map[int]string, 0)
@ -450,15 +449,15 @@ func (m *model) cursorPath() string {
if m.cursor == 0 { if m.cursor == 0 {
return "" return ""
} }
if 0 <= m.cursor && m.cursor < len(m.pathToLineNumber.keys) { if 0 <= m.cursor && m.cursor < len(m.paths) {
return m.pathToLineNumber.keys[m.cursor] return m.paths[m.cursor]
} }
return "?" return "?"
} }
func (m *model) cursorLineNumber() int { func (m *model) cursorLineNumber() int {
if 0 <= m.cursor && m.cursor < len(m.pathToLineNumber.keys) { if 0 <= m.cursor && m.cursor < len(m.paths) {
return m.pathToLineNumber.values[m.pathToLineNumber.keys[m.cursor]].(int) return m.pathToLineNumber[m.paths[m.cursor]]
} }
return -1 return -1
} }
@ -514,7 +513,7 @@ func (m *model) collectSiblings(v interface{}, path string) {
func (m *model) down() { func (m *model) down() {
m.showCursor = true m.showCursor = true
if m.cursor < len(m.pathToLineNumber.keys)-1 { // scroll till last element in m.pathToLineNumber if m.cursor < len(m.paths)-1 { // scroll till last element in m.paths
m.cursor++ m.cursor++
} else { } else {
// at the bottom of viewport maybe some hidden brackets, lets scroll to see them // at the bottom of viewport maybe some hidden brackets, lets scroll to see them
@ -522,8 +521,8 @@ func (m *model) down() {
m.LineDown(1) m.LineDown(1)
} }
} }
if m.cursor >= len(m.pathToLineNumber.keys) { if m.cursor >= len(m.paths) {
m.cursor = len(m.pathToLineNumber.keys) - 1 m.cursor = len(m.paths) - 1
} }
} }
@ -532,7 +531,7 @@ func (m *model) up() {
if m.cursor > 0 { if m.cursor > 0 {
m.cursor-- m.cursor--
} }
if m.cursor >= len(m.pathToLineNumber.keys) { if m.cursor >= len(m.paths) {
m.cursor = len(m.pathToLineNumber.keys) - 1 m.cursor = len(m.paths) - 1
} }
} }

@ -6,13 +6,20 @@ import (
"strings" "strings"
) )
func (m *model) connect(path string, lineNumber int) {
if _, exist := m.pathToLineNumber[path]; exist {
return
}
m.paths = append(m.paths, path)
m.pathToIndex[path] = len(m.paths) - 1
m.pathToLineNumber[path] = lineNumber
m.lineNumberToPath[lineNumber] = path
}
func (m *model) print(v interface{}, level, lineNumber, keyEndPos int, path string, selectableValues bool) []string { func (m *model) print(v interface{}, level, lineNumber, keyEndPos int, path string, selectableValues bool) []string {
m.connect(path, lineNumber)
ident := strings.Repeat(" ", level) ident := strings.Repeat(" ", level)
subident := strings.Repeat(" ", level-1) subident := strings.Repeat(" ", level-1)
connect := func(path string, lineNumber int) {
m.pathToLineNumber.set(path, lineNumber)
m.lineNumberToPath[lineNumber] = path
}
sri := m.searchResultsIndex[path] sri := m.searchResultsIndex[path]
switch v.(type) { switch v.(type) {
@ -39,7 +46,6 @@ func (m *model) print(v interface{}, level, lineNumber, keyEndPos int, path stri
return []string{merge(chunks)} return []string{merge(chunks)}
case *dict: case *dict:
connect(path, lineNumber)
if !m.expandedPaths[path] { if !m.expandedPaths[path] {
return []string{m.preview(v, path, selectableValues)} return []string{m.preview(v, path, selectableValues)}
} }
@ -49,7 +55,7 @@ func (m *model) print(v interface{}, level, lineNumber, keyEndPos int, path stri
for i, k := range keys { for i, k := range keys {
subpath := path + "." + k subpath := path + "." + k
s := m.searchResultsIndex[subpath] s := m.searchResultsIndex[subpath]
connect(subpath, lineNumber) m.connect(subpath, lineNumber)
key := fmt.Sprintf("%q", k) key := fmt.Sprintf("%q", k)
key = merge(m.explode(key, s.key, colors.key, subpath, true)) key = merge(m.explode(key, s.key, colors.key, subpath, true))
value, _ := v.(*dict).get(k) value, _ := v.(*dict).get(k)
@ -67,7 +73,6 @@ func (m *model) print(v interface{}, level, lineNumber, keyEndPos int, path stri
return output return output
case array: case array:
connect(path, lineNumber)
if !m.expandedPaths[path] { if !m.expandedPaths[path] {
return []string{m.preview(v, path, selectableValues)} return []string{m.preview(v, path, selectableValues)}
} }
@ -77,7 +82,7 @@ func (m *model) print(v interface{}, level, lineNumber, keyEndPos int, path stri
for i, value := range slice { for i, value := range slice {
subpath := fmt.Sprintf("%v[%v]", path, i) subpath := fmt.Sprintf("%v[%v]", path, i)
s := m.searchResultsIndex[subpath] s := m.searchResultsIndex[subpath]
connect(subpath, lineNumber) m.connect(subpath, lineNumber)
lines := m.print(value, level+1, lineNumber, width(ident), subpath, true) lines := m.print(value, level+1, lineNumber, width(ident), subpath, true)
lines[0] = ident + lines[0] lines[0] = ident + lines[0]
if i < len(slice)-1 { if i < len(slice)-1 {

Loading…
Cancel
Save