feat: write a list or heading the editor creates in the prevailing form - #405
Merged
Conversation
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.
Summary
A construct the editor creates has no authored form, so it was written with a fixed default —
*for a bullet list,.for an ordered one, and an ATX heading opened by one space and closed by nothing — whatever the document around it was written in. A list inserted into a file whose lists are all-was written*, and a heading added to a file of setext headings##. Each was correct by the rules and the file ended up mixed, which is the unrequested rewrite #251 exists to prevent, arriving one construct at a time rather than all at once on first save.Such a construct now takes the form the document prevails in. Prevailing is settled per axis rather than per construct, because a heading holds three that move independently, and over the whole document. Only the constructs an axis reaches answer for it, so a setext heading spells neither of an ATX heading's runs and an empty heading spells neither a separator nor an underline. One answer is agreement however few constructs give it, and two leave the default, because choosing between them would settle for the author a question the document does not.
docs/decisions.mdanddocs/specification.mdcarry the rule in full.A run whose length answers to the construct holding it carries only its presence across: a created heading is closed at the length of its own opening sequence and underlined at the width of its own content, because a length carried from another heading would be a form no file wrote. That is also why the underline is recorded as a form without a run — the length belongs to content a created heading does not have yet and an edit changes under it.
The survey settles over the assembled document rather than reaching each command that creates one of these constructs, which is where the issue expected the answer to arrive. The form attributes now default to
null, which is what separates a construct the editor made from one a file wrote in the very form the default names, and a construct still carrying no record is settled on the next transaction. One mechanism therefore reaches every site that can open one, whether a formatting command, an input rule, or a structural edit such as Tab-indent. Settling onto the construct rather than at the save is what makes the answer that construct's own form, so a document that later disagrees with itself does not move a construct already written in it.The classes settled are a list's marker and a heading's three axes, which are the defaults the issue names. A thematic break, a hard break, a table's outer pipes, and a task marker keep fixed defaults, and both documents record that boundary so the general rule does not read as governing the classes stated below it.
Two existing expectations move with the rule rather than against it.
Heading 2over a selection holding a paragraph beside one closed ATX heading now closes the heading the paragraph becomes, and Tab-indenting an item in a-document nests it under a-list rather than a*one.Related Issue
Closes #360
Verification
pnpm check:frontendpasses, the corpus round trip included. Nothing here touches Rust or Tauri code, sopnpm check:backendwas not run.Focused coverage in
markdownCompatibility.test.tsgains aPrevailing formgroup asserting the written bytes for each axis in both directions: agreement carried, disagreement left to the default, and a document that names no form of its own or holds nothing at all. It reaches a formatting command and an input rule, andkeyboardBehavior.test.tsreaches the structural edit. The inheritance rows were confirmed to discriminate rather than restate the implementation by running the group against the pre-change source, where they fail while the guard rows still pass. A convergence row asserts each created form reopens as the document that wrote it, which is what covers the heading whose record names no underline length.Measured by throwaway probe, not kept: undoing a created construct is one step, so the settling transaction does not land in history as an event of its own; and a created setext heading raised past level two writes ATX and returns to setext when lowered, so the record survives a level change on the rule #359 settled.
Not verified: no manual pass of Leafdown in the assembled application, and the desktop E2E suite was not run locally. Its fixtures hold no list or heading command.
Notes
Whether the characters typed into an input rule name a form is left open. Typing
+in a document that prevails in*still writes*, as it wrote*before this change. The question is whether what the author types names a form or only a construct, it reaches the ordered delimiter the same way, and this issue does not answer it.