From 64eefccd4fbd6ac02866909f913c81b6e2c35f91 Mon Sep 17 00:00:00 2001 From: Alex Kunin Date: Fri, 15 Mar 2024 09:17:31 +0200 Subject: [PATCH] Add an option to show collection size (#296) --- json.go | 3 ++ main.go | 4 ++ main_test.go | 13 ++++++ node.go | 1 + .../TestCollapseRecursiveWithSizes.golden | 40 +++++++++++++++++++ theme.go | 21 ++++++++++ 6 files changed, 82 insertions(+) create mode 100644 testdata/TestCollapseRecursiveWithSizes.golden diff --git a/json.go b/json.go index 8976c49..248bad6 100644 --- a/json.go +++ b/json.go @@ -200,6 +200,7 @@ func (p *jsonParser) parseObject() *node { p.depth++ key := p.parseString() key.key, key.value = key.value, nil + object.size += 1 key.directParent = object p.skipWhitespace() @@ -216,6 +217,7 @@ func (p *jsonParser) parseObject() *node { p.depth-- key.value = value.value + key.size = value.size key.next = value.next if key.next != nil { key.next.prev = key @@ -268,6 +270,7 @@ func (p *jsonParser) parseArray() *node { p.depth++ value := p.parseValue() value.directParent = arr + arr.size += 1 value.index = i p.depth-- diff --git a/main.go b/main.go index b1b57d2..0e6c3d6 100644 --- a/main.go +++ b/main.go @@ -732,6 +732,10 @@ func (m *model) View() string { screen = append(screen, comma...) } + if showSizes && n.isCollapsed() && (n.value[0] == '{' || n.value[0] == '[') { + screen = append(screen, currentTheme.Size([]byte(fmt.Sprintf(" // %d", n.size)))...) + } + screen = append(screen, '\n') printedLines++ n = n.next diff --git a/main_test.go b/main_test.go index ea733ef..24e8049 100644 --- a/main_test.go +++ b/main_test.go @@ -101,3 +101,16 @@ func TestCollapseRecursive(t *testing.T) { tm.Send(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("q")}) tm.WaitFinished(t, teatest.WithFinalTimeout(time.Second)) } + +func TestCollapseRecursiveWithSizes(t *testing.T) { + showSizes = true + defer func() { showSizes = true }() + + tm := prepare(t) + + tm.Send(tea.KeyMsg{Type: tea.KeyShiftLeft}) + teatest.RequireEqualOutput(t, read(t, tm)) + + tm.Send(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("q")}) + tm.WaitFinished(t, teatest.WithFinalTimeout(time.Second)) +} diff --git a/node.go b/node.go index efbf58d..e96043e 100644 --- a/node.go +++ b/node.go @@ -14,6 +14,7 @@ type node struct { depth uint8 key []byte value []byte + size int chunk []byte chunkEnd *node comma bool diff --git a/testdata/TestCollapseRecursiveWithSizes.golden b/testdata/TestCollapseRecursiveWithSizes.golden new file mode 100644 index 0000000..6528cea --- /dev/null +++ b/testdata/TestCollapseRecursiveWithSizes.golden @@ -0,0 +1,40 @@ +[?25l{ + "title": "Lorem ipsum", + "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusm + od tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam + , quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo cons + equat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum d + olore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident + , sunt in culpa qui officia deserunt mollit anim id est laborum.", + "tags": […], // 3 + "year": 3000, + "funny": true, + "author": {"name":…} // 2 +} +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +  \ No newline at end of file diff --git a/theme.go b/theme.go index c298eb6..a78a6b2 100644 --- a/theme.go +++ b/theme.go @@ -6,6 +6,7 @@ import ( "os" "regexp" "sort" + "strings" "github.com/charmbracelet/lipgloss" "github.com/muesli/termenv" @@ -22,6 +23,7 @@ type theme struct { Null color Boolean color Number color + Size color } type color func(s []byte) []byte @@ -66,6 +68,12 @@ func init() { themeId = "1" } + showSizesValue, ok := os.LookupEnv("FX_SHOWSIZES") + if ok { + showSizesValue := strings.ToLower(showSizesValue) + showSizes = showSizesValue == "true" || showSizesValue == "yes" || showSizesValue == "on" || showSizesValue == "1" + } + currentTheme, ok = themes[themeId] if !ok { _, _ = fmt.Fprintf(os.Stderr, "fx: unknown theme %q, available themes: %v\n", themeId, themeNames) @@ -93,6 +101,8 @@ var ( defaultStatusBar = toColor(lipgloss.NewStyle().Background(lipgloss.Color("7")).Foreground(lipgloss.Color("0")).Render) defaultSearch = toColor(lipgloss.NewStyle().Background(lipgloss.Color("11")).Foreground(lipgloss.Color("16")).Render) defaultNull = fg("243") + defaultSize = toColor(lipgloss.NewStyle().Foreground(lipgloss.Color("8")).Render) + showSizes = false ) var ( @@ -117,6 +127,7 @@ var themes = map[string]theme{ Null: noColor, Boolean: noColor, Number: noColor, + Size: noColor, }, "1": { Cursor: defaultCursor, @@ -129,6 +140,7 @@ var themes = map[string]theme{ Null: defaultNull, Boolean: fg("5"), Number: fg("6"), + Size: defaultSize, }, "2": { Cursor: defaultCursor, @@ -141,6 +153,7 @@ var themes = map[string]theme{ Null: defaultNull, Boolean: fg("5"), Number: fg("6"), + Size: defaultSize, }, "3": { Cursor: defaultCursor, @@ -153,6 +166,7 @@ var themes = map[string]theme{ Null: defaultNull, Boolean: fg("1"), Number: fg("14"), + Size: defaultSize, }, "4": { Cursor: defaultCursor, @@ -165,6 +179,7 @@ var themes = map[string]theme{ Null: defaultNull, Boolean: fg("#F15BB5"), Number: fg("#9B5DE5"), + Size: defaultSize, }, "5": { Cursor: defaultCursor, @@ -177,6 +192,7 @@ var themes = map[string]theme{ Null: defaultNull, Boolean: fg("#ee964b"), Number: fg("#ee964b"), + Size: defaultSize, }, "6": { Cursor: defaultCursor, @@ -189,6 +205,7 @@ var themes = map[string]theme{ Null: defaultNull, Boolean: fg("#FF6B6B"), Number: fg("#FFD93D"), + Size: defaultSize, }, "7": { Cursor: defaultCursor, @@ -201,6 +218,7 @@ var themes = map[string]theme{ Null: defaultNull, Boolean: boldFg("201"), Number: boldFg("201"), + Size: defaultSize, }, "8": { Cursor: defaultCursor, @@ -213,6 +231,7 @@ var themes = map[string]theme{ Null: defaultNull, Boolean: fg("50"), Number: fg("123"), + Size: defaultSize, }, "🔵": { Cursor: toColor(lipgloss.NewStyle(). @@ -228,6 +247,7 @@ var themes = map[string]theme{ Null: noColor, Boolean: noColor, Number: noColor, + Size: defaultSize, }, "🥝": { Cursor: defaultCursor, @@ -240,6 +260,7 @@ var themes = map[string]theme{ Null: fg("230"), Boolean: fg("226"), Number: fg("226"), + Size: defaultSize, }, }