pull/268/head
Anton Medvedev 9 months ago
parent 1f62de33bd
commit 063afa287f
No known key found for this signature in database

@ -187,6 +187,7 @@ func (p *jsonParser) parseObject() *node {
p.depth++
key := p.parseString()
key.key, key.value = key.value, nil
key.directParent = object
p.skipWhitespace()
@ -207,6 +208,7 @@ func (p *jsonParser) parseObject() *node {
key.next.prev = key
}
key.end = value.end
value.indirectParent = key
object.append(key)
p.skipWhitespace()
@ -214,6 +216,7 @@ func (p *jsonParser) parseObject() *node {
if p.lastChar == '}' {
closeBracket := &node{depth: p.depth}
closeBracket.value = []byte{'}'}
closeBracket.directParent = object
object.append(closeBracket)
p.next()
return object
@ -243,12 +246,14 @@ func (p *jsonParser) parseArray() *node {
for {
p.depth++
value := p.parseValue()
value.directParent = arr
p.depth--
arr.append(value)
p.skipWhitespace()
if p.lastChar == ']' {
closeBracket := &node{depth: p.depth}
closeBracket.value = []byte{']'}
closeBracket.directParent = arr
arr.append(closeBracket)
p.next()
return arr

@ -129,8 +129,18 @@ func (m *model) handleKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
m.cursor = m.visibleLines() - 1
case key.Matches(msg, keyMap.Collapse):
m.cursorPointsTo().collapse()
m.scrollIntoView()
node := m.cursorPointsTo().collapse()
if m.nodeInsideView(node) {
m.selectNodeInView(node)
m.scrollIntoView()
} else {
m.cursor = 0
m.head = node
m.scrollIntoView()
}
case key.Matches(msg, keyMap.Expand):
m.cursorPointsTo().expand()
}
return m, nil
@ -171,14 +181,16 @@ func (m *model) visibleLines() int {
return visibleLines
}
func (m *model) scrollIntoView() string {
func (m *model) scrollIntoView() {
visibleLines := m.visibleLines()
if m.cursor >= visibleLines {
m.cursor = visibleLines - 1
}
for visibleLines < m.viewHeight() && m.head.prev != nil {
visibleLines++
m.cursor++
m.head = m.head.prev
}
return fmt.Sprintf("visible lines: %d", visibleLines)
}
func (m *model) View() string {
@ -211,6 +223,14 @@ func (m *model) View() string {
}
screen = append(screen, colorize(head.value)...)
}
if head.isCollapsed() {
screen = append(screen, currentTheme.Preview([]byte("…"))...)
if head.value[0] == '{' {
screen = append(screen, currentTheme.Syntax([]byte{'}'})...)
} else if head.value[0] == '[' {
screen = append(screen, currentTheme.Syntax([]byte{']'})...)
}
}
if head.comma {
screen = append(screen, comma...)
}
@ -222,10 +242,11 @@ func (m *model) View() string {
n := m.cursorPointsTo()
if n == nil {
screen = append(screen, '-')
} else {
screen = append(screen, currentTheme.StatusBar(n.value)...)
} else if n.parent() != nil {
screen = append(screen, currentTheme.StatusBar(n.parent().key)...)
screen = append(screen, ':')
screen = append(screen, currentTheme.StatusBar(n.parent().value)...)
}
screen = append(screen, m.scrollIntoView()...)
return string(screen)
}
@ -256,3 +277,34 @@ func (m *model) findBottom() *node {
}
return n
}
func (m *model) nodeInsideView(n *node) bool {
if n == nil {
return false
}
head := m.head
for i := 0; i < m.viewHeight(); i++ {
if head == nil {
break
}
if head == n {
return true
}
head = head.next
}
return false
}
func (m *model) selectNodeInView(n *node) {
head := m.head
for i := 0; i < m.viewHeight(); i++ {
if head == nil {
break
}
if head == n {
m.cursor = i
return
}
head = head.next
}
}

@ -1,13 +1,31 @@
package main
import (
"fmt"
)
type node struct {
prev, next, end *node
directParent *node
indirectParent *node
collapsed *node
depth uint8
key []byte
value []byte
comma bool
}
func (n *node) parent() *node {
if n.directParent == nil {
return nil
}
parent := n.directParent
if parent.indirectParent != nil {
parent = parent.indirectParent
}
return parent
}
func (n *node) append(child *node) {
if n.end == nil {
n.end = n
@ -21,12 +39,30 @@ func (n *node) append(child *node) {
}
}
func (n *node) collapse() {
if n.end != nil {
func (n *node) collapse() *node {
if n.end == nil || n.isCollapsed() {
if n.parent() != nil {
return n.parent().collapse()
}
} else {
n.collapsed = n.next
n.next = n.end.next
if n.next != nil {
n.next.prev = n
}
return n
}
panic(fmt.Sprintf("Cannot collapse node %q", n.value))
}
func (n *node) isCollapsed() bool {
return n.collapsed != nil
}
func (n *node) expand() {
if n.collapsed != nil {
n.next = n.collapsed
n.collapsed = nil
}
}

Loading…
Cancel
Save