Repository navigation
Keep the JSON dictionary table in step with its text after re-reads, renames, reloads and closes - #110
Merged
Conversation
…its write A delete, paste, drop or add paints before it writes, and the change event its write fires was skipped as an echo of rows already on screen. A save, a webview asking for its rows, or a clipboard broadcast over rows out of step repaints the whole table without waiting for that write, and reads the text from before it: the screen went back to the old rows, the tree was rebuilt from the old text, and the skipped echo was the one change that would have repaired both. The table and the tree then said an entry existed that the file no longer had. Each view now counts the wide repaints it has begun, and a painted write and a cell edit's hint carry the count from when they were painted. An echo is skipped, and a hint used, only while no wide repaint has begun since; otherwise the event is planned like any other change.
…the answer A full repaint parses the text, then waits for the workspace usage graph before it posts, which is seconds when the graph is cold. It declared the rows in step with the text the moment it had parsed, so an edit made in that window took the narrow path and painted, and the rows that landed after it were built before it: the edit was taken back off the screen, and the narrow repaints that followed spliced into a table the text did not describe. Two full repaints in flight landed in whichever order their waits ended, so the older text could be the one left showing. The rows are now in step only once they land, and they land only if theirs is still the newest repaint, the document version is unchanged, and the view has not painted or put its tree out of step since; a newer repaint replaces them, and anything else reads the text again. The count is kept per view, because two tabs of one document share its tree and re-read each other for ever when the rule asked whether the tree was still their own.
… repaint A rename re-keys the entry's run of rows, and the edit paints that run under the new name before it writes. The echo of the write still spliced its confirmation over the OLD id, from when the echo was the paint: the table no longer held that id, answered the miss by asking for the whole payload, and every rename ended in a full re-parse and repaint (about 1.4 s on a 47.8 MB dictionary). A rename the document refused was taken back over the old id too, with the same round trip. The hint now carries the one id the model and the painted rows share, and taking a paint back finds the entry by the id the file still spells and splices it over the run the paint left; once a full repaint has begun since the paint, its rows are already the file's answer and only the banner follows them.
…gn-namespace entry The catalog names the definitions of Design Data and Architectural Data, and a name is unique only within a namespace. The host's gate carried a rename of any top-level entry of a definition's name, so renaming an Other Data or Configurations entry that shared it rewrote the definition in the file, in a text dictionary and a binary one alike, and the architectural entry that really holds the name read back unclassified. The gate now asks the entry's section for its namespace through core's own section table, the rule core applies when it classifies an entry and when it renames one. A test holds the host and core to one answer, entry by entry, over a catalog with entries of a definition's name inside and outside the namespace; the half outside is marked failing until the pinned core has the scope, and passes against a build that does.
…after a reload, a revert or a dirty open A mark says an entry differs from what the file holds, but the baseline was taken once, from the document's text the first time it painted, and replaced only by a save. A file changed by another tool and reloaded was marked Modified in a document with nothing to save; a revert left the marks measured against the old text; and a document already dirty when the table opened, such as a window restored with unsaved changes, was measured against its own edits and marked nothing. The document now records each version known to read what the file says: clean when a view opens, the dirty-state event that clears it on a save or a revert, and a reload, which VS Code reports with no dirty-state event and is told by comparing the text with the file. The next full repaint of that version takes the baseline from the text it parsed, and every tab repaints its marks. A document opened dirty takes its baseline from the file's own bytes. An undo or redo back to a clean document needs neither, since its text is the one the baseline was taken from.
…for the usage graph Clearing the in-step flag when a full repaint began sent every keystroke in the text view, and every undo, down the full re-parse for as long as the repaint waited for a cold usage graph, which is after every save of a workspace file. The rows on screen are still the old ones in that window, and a narrow repaint keeps them in step exactly as it did before; what must not happen is the full repaint landing its older rows over it, and the landing rule already reads the text again when the view has painted since it began. So the flag is left as it was until the rows land. Also corrects the note on the held-back usage repost: its echo is no longer skipped after a full repaint, so holding it back now saves a second full repaint rather than a lost edit.
…othing A full repaint waits for the usage graph before it posts, and one whose text moved meanwhile reads the document again. After the last tab had closed, that re-read registered a fresh tree of the dictionary, tens of MB on a real one, which the close had just released and no tab was left to release again; and a repaint that landed instead posted to the closed panel. The view now knows it is closed, first thing on dispose, and a repaint begun or landing after that does nothing, as do its narrow repaints and the check of its text against the file. The disk read of a document opened dirty belongs to the document and still serves the tabs left open, but stops before its parse once the last one has closed.
…as its baseline A document opened with unsaved changes takes its baseline from the file's bytes, read asynchronously. A save landing during that read was not baselined, because no repaint captures while the read is pending, and the bytes that arrived afterwards, possibly from before the save, then became the baseline: entries the save had just written showed as Modified in a clean document. A repaint now captures a saved text even while the read is pending, and the read's bytes count only if the document has not turned clean since it began; if it has and nothing was baselined, the file is read again. Also brings the baseline notes in slddBaseline.ts and the document state's note up to date.
…g the whole file A reload of a clean document says itself only by leaving the text equal to the file, so the first change to a clean document was checked against the file, and the check read all of it, in every tab, on the first edit after every save and every autosave. Measured in the test host on a generated 48.7 MB dictionary: 14 to 45 ms and a buffer the size of the file per read, against 0.5 to 4 ms for a stat. The document now keeps the file's size and modification time from the last moment it was known to read what the file says, and the file is read only when they have moved since. A reload follows a change on disk, so it is still found, and an edit leaves the stat where it was.
A new baseline now repaints every tab, and a change nothing narrow can plan repaints wide; either could reach a tab whose webview was still loading and had no listener yet, so the full parse and row build were thrown away ahead of the one its `ready` asks for anyway. A full repaint now waits for the webview's first `ready`.
…nt is owed as a repair A full repaint no longer clears the in-step flag when it begins, which is right for one that repaints rows already in step (a save, a webview asking for its rows). It was not for one that repairs rows known to be wrong: a change nothing narrow could plan, a narrow repaint that threw, a paint the file never took. Until that repair landed, a following change could still be spliced narrowly into the rows it was about to replace. The landing rule then read the text again, so nothing wrong was left on screen, but the narrow claim was false in the meantime. Those four repairs now put the view out of step before they begin.
# Conflicts: # src/host/SlddTextEditorProvider.ts
… core has it The pinned core now classifies and renames by the System Composer catalog only in the Design namespace, so the agreement over entries outside it is a plain test rather than one marked as failing until the pin moved.
… from the table or the text The panel is handed a node when a row is selected and builds its rows from it once. A JSON dictionary's tree changes under it at every table edit, undo and redo, keystroke in the text view, save, revert and reload, and the panel went on showing the node it was handed until another row was clicked. The other two editors already said when their tree changed, and the panel's one refresh answered them. The JSON editor now says so too, after every repaint it posts, wide or narrow, and extension.ts answers it with the same refresh. That is keystroke rate; the panel sends its page a node only when it changes what the page shows, and a test pins that a keystroke in another entry sends it nothing. Also stops a closed table being posted the banner that follows a failed edit's repair.
…one clean-at test The reload check and the dirty open's disk baseline each wrapped the file read in their own try/catch; readDisk now answers null on failure the way statDisk already did. The "still clean at this version" test was spelled out three times (stampDisk and both checkAgainstDisk guards); stillCleanAt names it once. Also: latestPost is declared ahead of the post() that assigns it, noteClean's tail is one if, the dirty-open branch gets braces like its neighbour, and the hintFor test drops the rowId field HostEdit no longer has. No behaviour change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Fixes from a review of the JSON text dictionary editor's text-to-table sync, plus a host catalog fix. The table and the plain-text view show the same document; the provider repaints narrowly when it can prove that is right and re-reads otherwise. These close the gaps where it trusted a narrow path it should not have.
ready.Tests: unit 4322 passed; integration 420 passing / 2 pending, 0 failing, on this branch merged with main.