From 841eb4f1b5b78e2d1bd859463e7eb5b0563429d6 Mon Sep 17 00:00:00 2001 From: Anton Medvedev Date: Sat, 2 Apr 2022 22:59:36 +0200 Subject: [PATCH] Refactor to use separate path vars --- dict.go | 20 ++++---------------- dict_test.go | 12 ------------ main.go | 49 ++++++++++++++++++++++++------------------------- print.go | 21 +++++++++++++-------- 4 files changed, 41 insertions(+), 61 deletions(-) diff --git a/dict.go b/dict.go index efa03cd..5477eb5 100644 --- a/dict.go +++ b/dict.go @@ -1,20 +1,14 @@ package main type dict struct { - keys []string - indexes map[string]int - values map[string]interface{} + keys []string + values map[string]interface{} } func newDict() *dict { - return newDictOfCapacity(0) -} - -func newDictOfCapacity(capacity int) *dict { return &dict{ - keys: make([]string, 0, capacity), - indexes: make(map[string]int, capacity), - values: make(map[string]interface{}, capacity), + keys: make([]string, 0), + values: make(map[string]interface{}), } } @@ -23,15 +17,9 @@ func (d *dict) get(key string) (interface{}, bool) { 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{}) { _, exists := d.values[key] if !exists { - d.indexes[key] = len(d.keys) d.keys = append(d.keys, key) } d.values[key] = value diff --git a/dict_test.go b/dict_test.go index 14875fd..388cbd2 100644 --- a/dict_test.go +++ b/dict_test.go @@ -9,20 +9,12 @@ func Test_dict(t *testing.T) { if v.(int) != 3 { t.Error("Set number") } - i, _ := d.index("number") - if i != 0 { - t.Error("Index error") - } // string d.set("string", "x") v, _ = d.get("string") if v.(string) != "x" { t.Error("Set string") } - i, _ = d.index("string") - if i != 1 { - t.Error("Index error") - } // string slice d.set("strings", []string{ "t", @@ -35,10 +27,6 @@ func Test_dict(t *testing.T) { if v.([]string)[1] != "u" { t.Error("Set strings second index") } - i, _ = d.index("strings") - if i != 2 { - t.Error("Index error") - } // mixed slice d.set("mixed", []interface{}{ 1, diff --git a/main.go b/main.go index 934d235..246847f 100644 --- a/main.go +++ b/main.go @@ -137,14 +137,16 @@ type model struct { keyMap KeyMap showHelp bool - expandedPaths map[string]bool // a set with expanded paths - canBeExpanded map[string]bool // a set for path => can be expanded (i.e. dict or array) - pathToLineNumber *dict // dict with path => line number + expandedPaths map[string]bool // set of expanded paths + canBeExpanded map[string]bool // set of path => can be expanded (i.e. dict or array) + 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 parents map[string]string // map of subpath => parent path children map[string][]string // map of path => child paths 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 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): nextSiblingPath, ok := m.nextSiblings[m.cursorPath()] if ok { - index, _ := m.pathToLineNumber.indexes[nextSiblingPath] m.showCursor = true - m.cursor = index + m.cursor = m.pathToIndex[nextSiblingPath] } else { m.down() } @@ -265,9 +266,8 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case key.Matches(msg, m.keyMap.PrevSibling): prevSiblingPath, ok := m.prevSiblings[m.cursorPath()] if ok { - index, _ := m.pathToLineNumber.indexes[prevSiblingPath] m.showCursor = true - m.cursor = index + m.cursor = m.pathToIndex[prevSiblingPath] } else { m.up() } @@ -296,8 +296,7 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { parentPath, ok := m.parents[m.cursorPath()] if ok { m.expandedPaths[parentPath] = false - index, _ := m.pathToLineNumber.index(parentPath) - m.cursor = index + m.cursor = m.pathToIndex[parentPath] } } m.render() @@ -311,8 +310,7 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { parentPath, ok := m.parents[m.cursorPath()] if ok { m.collapseRecursively(parentPath) - index, _ := m.pathToLineNumber.index(parentPath) - m.cursor = index + m.cursor = m.pathToIndex[parentPath] } } m.render() @@ -363,8 +361,7 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if m.canBeExpanded[clickedPath] { m.expandedPaths[clickedPath] = !m.expandedPaths[clickedPath] } - index, _ := m.pathToLineNumber.index(clickedPath) - m.cursor = index + m.cursor = m.pathToIndex[clickedPath] m.render() } } @@ -429,10 +426,12 @@ func (m *model) render() { return } + m.paths = make([]string, 0) + m.pathToIndex = make(map[string]int, 0) if m.pathToLineNumber == nil { - m.pathToLineNumber = newDict() + m.pathToLineNumber = make(map[string]int, 0) } else { - m.pathToLineNumber = newDictOfCapacity(cap(m.pathToLineNumber.keys)) + m.pathToLineNumber = make(map[string]int, len(m.pathToLineNumber)) } if m.lineNumberToPath == nil { m.lineNumberToPath = make(map[int]string, 0) @@ -450,15 +449,15 @@ func (m *model) cursorPath() string { if m.cursor == 0 { return "" } - if 0 <= m.cursor && m.cursor < len(m.pathToLineNumber.keys) { - return m.pathToLineNumber.keys[m.cursor] + if 0 <= m.cursor && m.cursor < len(m.paths) { + return m.paths[m.cursor] } return "?" } func (m *model) cursorLineNumber() int { - if 0 <= m.cursor && m.cursor < len(m.pathToLineNumber.keys) { - return m.pathToLineNumber.values[m.pathToLineNumber.keys[m.cursor]].(int) + if 0 <= m.cursor && m.cursor < len(m.paths) { + return m.pathToLineNumber[m.paths[m.cursor]] } return -1 } @@ -514,7 +513,7 @@ func (m *model) collectSiblings(v interface{}, path string) { func (m *model) down() { 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++ } else { // 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) } } - if m.cursor >= len(m.pathToLineNumber.keys) { - m.cursor = len(m.pathToLineNumber.keys) - 1 + if m.cursor >= len(m.paths) { + m.cursor = len(m.paths) - 1 } } @@ -532,7 +531,7 @@ func (m *model) up() { if m.cursor > 0 { m.cursor-- } - if m.cursor >= len(m.pathToLineNumber.keys) { - m.cursor = len(m.pathToLineNumber.keys) - 1 + if m.cursor >= len(m.paths) { + m.cursor = len(m.paths) - 1 } } diff --git a/print.go b/print.go index 724a37e..6d0279e 100644 --- a/print.go +++ b/print.go @@ -6,13 +6,20 @@ import ( "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 { + m.connect(path, lineNumber) ident := strings.Repeat(" ", level) subident := strings.Repeat(" ", level-1) - connect := func(path string, lineNumber int) { - m.pathToLineNumber.set(path, lineNumber) - m.lineNumberToPath[lineNumber] = path - } sri := m.searchResultsIndex[path] switch v.(type) { @@ -39,7 +46,6 @@ func (m *model) print(v interface{}, level, lineNumber, keyEndPos int, path stri return []string{merge(chunks)} case *dict: - connect(path, lineNumber) if !m.expandedPaths[path] { 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 { subpath := path + "." + k s := m.searchResultsIndex[subpath] - connect(subpath, lineNumber) + m.connect(subpath, lineNumber) key := fmt.Sprintf("%q", k) key = merge(m.explode(key, s.key, colors.key, subpath, true)) value, _ := v.(*dict).get(k) @@ -67,7 +73,6 @@ func (m *model) print(v interface{}, level, lineNumber, keyEndPos int, path stri return output case array: - connect(path, lineNumber) if !m.expandedPaths[path] { 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 { subpath := fmt.Sprintf("%v[%v]", path, i) s := m.searchResultsIndex[subpath] - connect(subpath, lineNumber) + m.connect(subpath, lineNumber) lines := m.print(value, level+1, lineNumber, width(ident), subpath, true) lines[0] = ident + lines[0] if i < len(slice)-1 {