feat: bear-style text editor parity#35
Merged
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
Enrich the Marcdown text editor to feel as close to Bear's editor as possible — the goal being a daily-driver markdown editor good enough to replace Raycast Notes.
Built via a 4-agent workflow: PM functional spec → Thomas design review → oonolive-swift tests-first → guy implementation.
What lands
Styling helpers (each as its own commit):
MarcdownListMarkerKind(bullets cycle filled/hollow circle → filled/hollow diamond by depth; ordered carries its depth)ListIndentation— Tab / Shift+Tab indent/outdent on list lines (2-space step)OrderedListRenumber— renumbers contiguous ordered run at the anchor's depth, skipping deeper nested childrenBlockquoteContinuation— Enter continues>; Enter on empty>exits (strips one level for nested)HeadingContinuation— Backspace on empty#strips the marker atomicallyFocusLine+MarkdownStyler.restyle(storage:source:focusLine:)— concealed syntax (**, link](url), list markers, etc.) reveals on the line the cursor is on, re-conceals on leaveListContinuationrefinements — empty-marker exit emits blank-line separator after content; backspace at marker-start triggers atomic joinEditor wiring (
NoteEditorView.Coordinator):insertTab:,insertBacktab:,insertNewlineIgnoringFieldEditor:,moveLeft:,moveRight:to the new helpersOrderedListRenumberafter every list-affecting editFocusLineon selection change and feeds it to restyleCheckboxIconLayoutManagerdraws depth-aware bullet glyphs and uses body color for both bullets and ordered numbersTest plan
Automated (all green locally):
swift test --package-path Packages/MarcdownStyling— 293/293 passingswift test --package-path Packages/MarcdownEditor— 31/31 passingswift test --package-path Packages/MarcdownCore— 27/27 passingxcodebuild -scheme Marcdown -configuration Debug build— SUCCEEDEDManual (please verify in the running app):
**bold**/[label](url)/ list markers reveals the syntax, leaves re-conceal it> hellocontinues the blockquote; Enter on empty>exits#strips the marker- bar(after- foo) joins lines and strips the markerDeferred (out of scope for this PR)
Cmd+B/Cmd+Iformatting shortcuts (separate workstream)Known cost
OrderedListRenumber.renumberRunreturns a full-buffer rewrite that the coordinator applies as a singlereplaceCharacters— each renumber is one fat undo step. Worth optimizing later to(range, replacement)for just the changed sub-run.