GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Cache the JSON tree per tab instead of drawing it on tab switch by leoshone · Pull Request #253 · NPP-JSONViewer/JSON-Viewer

Conversation

@leoshone

@leoshone leoshone commented Sep 3, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Problem

With Follow current tab disabled (the default), the plugin neither follows
the active tab nor clears the tree. The tree keeps showing whichever document
happened to be parsed last, with nothing indicating that it belongs to a
different tab. Reproduce:

  1. Open a.json, press Refresh JSON Tree.
  2. Switch to b.json — the tree still shows a.json.
  3. Switch back — no way to tell which document the tree belongs to.

Enabling the option instead parses on every tab switch, which is not always
wanted either (large files, and it re-parses even when the user only wanted a
look at the tree of one tab).

Change

The tree is now drawn only when the user asks for it (Refresh JSON Tree).
Switching tabs stores the tree of the tab being left and puts it back verbatim
when that tab comes back, so:

  • no re-parsing happens on tab switch, and
  • expansion state and selection survive.

The "Follow current tab" option is kept and behaves exactly as before when it
is enabled
— the document of the activated tab is parsed immediately. Only its
off path changes, from "do nothing" to "remember per tab". Users who rely on
the follow behaviour are unaffected, and no visible setting is removed.

Details:

  • Snapshots live in memory only. They are dropped when the buffer is closed,
    together with the association to the current buffer (Notepad++ does not
    guarantee whether NPPN_FILECLOSED or NPPN_BUFFERACTIVATED arrives first).
  • Auto format on open now formats the document without drawing the tree
    (FormatJsonDocument() is FormatJson() minus the redraw), so opening a file
    can no longer trigger a parse.
  • Formatting now redraws the tree while preserving its expansion state, which
    keeps it consistent with Refresh (see Keep the tree expansion state when refreshing the JSON tree #252).
  • New TreeState model (nodes + expansion + selection) next to the
    TreeExpansion helpers. TreeExpansion is the "same document, tree rebuilt"
    case; TreeState is the "whole tree carried across tabs" case.

Optional: draw the tree when a json file is opened

"Never parse on its own" is the right default, but it also means a user who
wants the tree right away has to press Refresh on every file. A new option,
Draw tree when a json file is opened (DRAW_ON_OPEN, off by default),
draws the tree once when a json document is opened.

It is deliberately built on top of the snapshot mechanism rather than next to
it: the check lives in RestoreTabState(), the single place reached when the
tree of a tab has never been drawn. So the document is parsed exactly once, and
from then on the tab behaves like any other — switching back replays the stored
snapshot and does not parse again. Opening a file, switching back to a tab and
showing the panel are all covered by that one code path.

Two details worth reviewing:

  • The tree is drawn for documents whose language is JSON, the same criterion
    the existing Follow current tab uses.
  • Drawing on open is initiated by the plugin, not by the user, so a parse
    failure must not stop the user with a dialog. DrawJsonTree() takes a
    bSilent flag for that and reports the failure as a node inside the tree
    instead. Manual Refresh is unchanged and still reports errors as before.

Note on the diff

This branch is built on top of #252 (TreeExpansion.h/.cpp), so its diff
currently includes that PR as well. The change specific to this PR is
+602/-28 over 17 files; the total against master is +1073/-31 over 20
files
. If #252 is merged first, this PR collapses to its own commits.

Verification

  • Unit tests: 167/167 (143 pre-existing, 14 from Keep the tree expansion state when refreshing the JSON tree #252, 9 TreeStateTest
    cases for snapshot capture/compare, 1 ProfileTest round-trip for the new
    setting).
  • Fork CI: all six jobs green (Debug/Release × Win32/x64/ARM64).
  • Manual end-to-end on a portable Notepad++ x64 build, driven through
    SendMessage (this host runs non-interactively, so no keyboard injection):
    • 21/21 assertions for the per-tab caching, including the decisive one —
      after rewriting the document behind the tab's back, switching away and back
      still shows the old snapshot, and only an explicit Refresh picks up the
      new text. That distinguishes "replay a snapshot" from "re-parse quietly".
    • 20/20 assertions for draw tree on open: a json file is drawn without
      pressing Refresh; a second file gets its own tree; switching back shows the
      right document; after the document is changed behind the plugin's back the
      stale snapshot is kept (no re-parse); a new non-json file is not parsed;
      Refresh still re-reads; with the option off nothing is drawn and manual
      Refresh still works; and a malformed json file reports the error inside
      the tree
      with no modal dialog, leaving Notepad++ responsive.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@leoshone leoshone mentioned this pull request Sep 3, 2026
[CI only] Integration build of all four features leoshone/JSON-Viewer#5
Draft
@leoshone
leoshone force-pushed the fix/per-tab-tree-snapshot branch from b5f684c to ed4c3d8 Compare September 5, 2026 04:15
leoshone added 3 commits September 7, 2026 18:14
@leoshone
Keep the tree expansion state when refreshing the JSON tree
8949f27
"Refresh JSON Tree" rebuilds every node, so the tree always came back
fully collapsed - even when the user only wanted to re-read a document
they were already looking at.

Capture which nodes are expanded and which one is selected before the
tree is thrown away, then re-apply that state onto the freshly built
tree, matching nodes by path. Paths that no longer exist (the document
changed in the meantime) are silently dropped, and nodes that are new
stay collapsed.

The state is keyed by node path, which is the list of keys from the
tree root down to a node. The pure path arithmetic lives in the new
TreeExpansion.h/.cpp so it can be unit tested without a window.

DrawJsonTree() gained a bPreserveExpansion parameter that defaults to
false, so every other caller (panel opening, formatting, compressing,
sorting) keeps behaving exactly as before; only the refresh button
opts in.
@leoshone
Cache the JSON tree per tab instead of drawing it on tab switch
88c6b9c
When "Follow current tab" is off (the default) the plugin never drew the
tree on its own, but it also never cleared it: the tree kept showing the
document of some earlier tab, with no indication that it belonged there.

With this change the tree is only ever drawn when the user asks for it
("Refresh JSON Tree"). Switching tabs stores the tree of the tab being
left and puts it back verbatim when the tab is activated again, so no
re-parsing happens and the expansion state and selection survive.

The "Follow current tab" option is kept and behaves exactly as before
when enabled: the document of the activated tab is parsed immediately.
Only its "off" path changes, from "do nothing" to "remember per tab".

Notes:
 - Snapshots live in memory only and are dropped when the buffer is
   closed, together with the association to the current buffer.
 - "Auto format on open" now formats the document without drawing the
   tree, so opening a file still cannot trigger a parse.
 - Formatting now redraws the tree while preserving its expansion state,
   which keeps it consistent with Refresh.
 - Built on top of the TreeExpansion helpers introduced for Refresh.
@leoshone
Draw the tree once when a json file is opened (DRAW_ON_OPEN)
cdda86c
Adds an option, off by default, that draws the tree of a json document as soon as the file is opened. It complements the per-tab snapshot caching: the document is parsed exactly once, and switching back to the tab afterwards replays the stored snapshot instead of parsing again.

The check lives in RestoreTabState(), the single place reached when the tree of a tab has never been drawn, so opening a file, switching back to a tab and showing the panel are all covered by one code path.

Drawing on open is initiated by the plugin, not by the user, so parse errors are reported as a node inside the tree rather than through a modal dialog: DrawJsonTree() takes a bSilent flag for that.

The tree is drawn for documents whose language is JSON, the same criterion the existing "follow current tab" uses.
@leoshone
leoshone force-pushed the fix/per-tab-tree-snapshot branch from ed4c3d8 to cdda86c Compare September 7, 2026 10:20
@leoshone leoshone mentioned this pull request Sep 7, 2026
Persist the tree view zoom level across Notepad++ sessions #251
Merged
leoshone added a commit to leoshone/JSON-Viewer that referenced this pull request Sep 7, 2026
@leoshone
Record the upstream round of 09-07: NPP-JSONViewer#251 merged, rebase, …
41a2206
…NPP-JSONViewer#255 opened

- NPP-JSONViewer#251 was approved and merged - the small-pure-PR strategy works.
- Upstream moved to fa8d2b9 (settings saved on exit via writeIfChanged,
  include reordering) and renamed our TREE_ZOOM key to TREE_ZOOM_LEVEL;
  documented the consequences for the next integration sync.
- NPP-JSONViewer#253/NPP-JSONViewer#254 rebased onto fa8d2b9, all three PRs mergeable again.
- NPP-JSONViewer#255 opened for the narrow jsonc recognition, with the forward pointer
  added to the NPP-JSONViewer#251 thread as planned.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@leoshone
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.