Skip to content

Conversation

@the-vampiire
Copy link

Summary

  • Fix crash when viewing JSON data containing bracket patterns (e.g., [0,23] interpreted as Rich markup tags)
  • Add interactive tree viewer for exploring nested JSON structures in Preview (v) and View (V) modes

Problem

JSON data containing bracket patterns like [0,23] was being interpreted as Rich markup tags, causing MarkupError crashes when using Preview (v) or View (V) on cells containing JSON.

Solution

Bug Fix

  • Use rich.Syntax for JSON content rendering with proper syntax highlighting
  • Set markup=False on Static widgets for non-JSON content to prevent markup parsing
  • Store raw value separately for copy functionality

Feature: Interactive JSON Tree Viewer

  • New JSONTreeView widget with collapsible tree structure for JSON data
  • Tree view is the default for valid JSON, with syntax highlighting as fallback
  • Visual indicators: {} for objects (cyan), [] for arrays (magenta) with item counts
  • Type-aware value formatting (null, boolean, number, string)

Key Bindings

Key Action
t Toggle between tree and syntax view
E / e Expand all nodes
Z Collapse all nodes

Files Changed

File Change
sqlit/shared/ui/widgets_json_tree.py New JSON tree viewer widget
sqlit/shared/ui/widgets_value_view.py Add tree/syntax toggle to inline value view
sqlit/domains/results/ui/screens/value_view.py Add tree/syntax toggle to modal value view

Validation

  • ruff check . - passes
  • ruff format --check . - passes
  • pyright - passes (0 errors)
  • pytest tests/ -k sqlite - 31 passed, 6 skipped
  • pytest tests/cli/ tests/ui/ - 127 passed, 1 pre-existing failure unrelated to this PR

…up parsing crash

JSON data containing bracket patterns like [0,23] was being interpreted as
Rich markup tags, causing MarkupError crashes in Preview (v) and View (V).

- Use rich.Syntax for JSON content with syntax highlighting
- Set markup=False on Static widgets for non-JSON content
- Store raw value separately in ValueViewScreen for copy functionality
Add collapsible tree view for JSON data in Preview (v) and View (V) modes:

- New JSONTreeView widget with expand/collapse support
- Tree view is default for valid JSON, with syntax highlighting fallback
- Key bindings: t (toggle tree/syntax), E (expand all), Z (collapse all)
- Proper focus management and scrolling in both view modes
- Simplified footer hints to avoid duplication with app bindings

The tree view makes exploring nested JSON (like Twitter API responses)
much easier than scrolling through syntax-highlighted text.
@the-vampiire
Copy link
Author

tree view

image

syntax view

image

@Maxteabag
Copy link
Owner

Nice PR.

But why isn't the keybindings in the footer?

And expanding a node isn't "e", it should have been enter.

It's just textual default.

Expanding a node shouldn't have a keybinding.

Please be careful about integrating your code with the rest of its structure and practices.

@the-vampiire
Copy link
Author

yes good points. i will fix these in the morning.

what binding should be used for collapse?

@Maxteabag
Copy link
Owner

Lower case 'z' is preferred.

@Maxteabag
Copy link
Owner

When I say integration with rest of the code base I am particularly concerned about duplicated detect json method. Also the code adds manual key handling directly in the widget. Should instead register with ValueViewActiveState._setup_actions to use the hierarchical state machine.

Please use a ValueViewActiveState and create children ValueViewTreeModeState and ValueViewSyntaxModeState.

the-vampiire and others added 2 commits January 9, 2026 15:16
Address maintainer feedback on PR Maxteabag#78:

- Remove manual key handling from InlineValueView widget
- Create ValueViewTreeModeState and ValueViewSyntaxModeState child states
- Register actions via _setup_actions() using hierarchical state machine
- Add shared parse_json_value() to eliminate duplicate JSON detection
- Display keybindings in footer via get_display_bindings()
- Use lowercase 'z' for collapse all (per maintainer preference)
- Remove 'e'/'E' expand binding (enter is textual default)
- Show contextual toggle labels: "Syntax View" / "Tree View"
- Add value_view_tree_mode and value_view_is_json to InputContext

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add contextual copy options when viewing JSON in tree mode:
- yy: Copy current node's value
- yf: Copy field as "key": value format
- ya: Copy entire JSON

Follows existing 'ry' (results yank) menu pattern. Includes visual
flash feedback on copy (cursor flash for value/field, background
flash for all).

Syntax mode retains direct copy behavior (no submenu).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@the-vampiire
Copy link
Author

i did this as a quick fix with claude locally when i encountered the error, but i should have had more respect than to open the PR without reviewing it for idiomatic adherence. thank you for your patience and direction, we have applied all the fixes you suggested.

i am not familiar with TUI development or many of the libs and frameworks in use. but i pushed claude to confirm that all changes aligned with existing patterns (had it find references to compare to).

during final manual testing i introduced a copy submenu for the tree view that makes it easy to copy a value, a field (key:value), or the whole tree. this was modeled after the result view behavior for copy table (tree), row (field) and cell (value).

tree view

image

added a copy menu (syntax view just copies all):

image

syntax view

image

Add tests for parse_json_value function and state machine guards to ensure
JSON tree view only activates for valid JSON content.

Fix bug in ValueViewSyntaxModeState.is_active() that was missing the
value_view_is_json check, which would have allowed toggle for non-JSON content.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@the-vampiire
Copy link
Author

finally, added these tests (from claude):

Test Coverage

Adds regression tests for the JSON tree viewer functionality:

tests/ui/test_json_tree.py - 7 tests for parse_json_value

  • Validates the gatekeeper function that determines whether content receives JSON treatment
  • Covers valid JSON objects/arrays, Python dict literals, and rejection of plain text/malformed JSON

tests/ui/keybindings/test_state_machine.py - 3 tests for TestValueViewStates

  • Validates that toggle_value_view_mode is blocked for non-JSON content
  • Validates that collapse_all_json_nodes only works in tree mode
  • Follows existing state machine test patterns

Bug caught during testing:

The test_toggle_blocked_for_non_json test identified a missing value_view_is_json check in ValueViewSyntaxModeState.is_active(). Without this fix, the toggle keybinding would have been incorrectly available for non-JSON content.

@the-vampiire
Copy link
Author

the only thing i'm unsure about is the uv.lock file. it has a pretty big diff which is unexpected unless recent merges didnt re-install to update it. let me know if you want me to include it or if there are any other changes youd like done.

thanks again for your patience and for the awesome tool. its been a big help for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants