Repository navigation
Source Edit: fix the Markdown in place (v1.12.0) - #35
Merged
Merged
Conversation
DocumentFileFormat detects encoding, BOM and line-ending style from the raw bytes and re-encodes LF text so an unchanged document saves byte for byte; DocumentFileWriter overwrites an existing regular file in place (keeps inode, permissions, xattrs, creation date, links; refuses read-only and non-regular files) with read-back verification and a best-effort restore. MarkdownDocument.decode now strips the BOM on the bytes, so the text never carries U+FEFF regardless of the Foundation version. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…missing file returns SourceEditSupport: line/offset mapping on UTF-16, block lookup for a source line, literal selection lookup, and newline / indent / outdent edits returned as single undoable replacements (NSString core, one pass on large documents). FileWatcher: after the watched file disappears, poll for the path once a second and re-arm when it is back (git checkout, stash pop); a permission error stops the poll instead of retrying forever. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ce edits EditCloseGuard is a forwarding proxy in front of SwiftUI's window delegate: a dirty session turns every close path (red button, tab close, Cmd-W, quit) into a Save / Don't Save / Cancel sheet, with a synchronous last-resort prompt if a window closes without consulting the delegate. It keeps the underlying NSDocument clean on purpose, so it disables automatic termination itself while text is unsaved. No session installs a guard yet, so behaviour is unchanged. The app's Close command and the missing-file banner now go through EditCloseGuard.requestClose (plain close() for clean windows, as before). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…n geometry) SourceEditorController builds a TextKit 1 plain-text editor in the rendered document's column, with its own UndoManager (never the window's, which belongs to SwiftUI's autosaving NSDocument), CR-free buffer, indentation edits from SourceEditSupport as single undo steps, the system find bar, and caret / scroll-to-line API for the edit session. Not mounted yet. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…er on the view, bounded relayout restore Paste normalization is its own undo step; SourceTextView returns the editor's UndoManager even without its delegate; restored text takes the current style; the exact top-line restore after a relayout is skipped past 400k UTF-16 units (keeps the estimate instead of a multi-hundred-ms layout); focus requests wait for a window; Shift/Option-Return insert a plain newline. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e confirmation SourceEditSession owns one window's edit flows: fresh read with entry checks (writable, size, byte-exact round trip), in-place save in the file's own encoding and line endings with a conflict check, external-change handling (silent adopt when clean, banner when dirty), leave / discard, and the EditCloseGuard handlers. Prompts are injectable; the rendered text always equals what is on disk. SourceEditorController gains reload(_:). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Session: Save Anyway keeps the base until the write succeeded and re-checks the disk after the prompt; Keep My Version adopts the disk's format; one prompt chain at a time; literal (UTF-16) text comparison; lossless-decode entry check that also covers mixed line endings; banner-aware save and discard; delayed adopt of a momentarily empty file. Editor: base attributes are added, not set (marked text keeps its attributes); CR paste is named Paste; multi-range replacements are normalized; exact restore also bounded by lines; reload uses the relayout primitives. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… with the same bytes The session records the last text it committed to the rendered view and re-commits the saved text whenever the disk is back at the base and the two differ. Busy banner/menu actions beep; the empty-file recheck delay is injectable for tests. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Edit Source / Done Editing (Option-Cmd-E), Save (Cmd-S) and Discard Changes in the File menu via focused values; the editor mounted over the rendered list; Save / Done pills while editing, the pencil pill starts Source Edit and the external editor gets its own pill; changed-on-disk banner; Cmd-F opens the editor's find bar while editing; leaving lands the rendered view on the block that holds the caret, resolved against the parse of the saved text. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… the editor Escape leaves edit mode (or closes the find bar) whatever has focus; Don't Save no longer scrolls the rendered view to a line of the discarded buffer; Cmd-G is matched exactly; the session follows a changed document URL; the covered list leaves the accessibility tree (AppKit level); a selection in the rendered view is selected in the source when it occurs there literally. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… lazy, bounded hint The hint carries the rendered text around the selection and the source match with the best-agreeing context wins; the hint is built only after the entry checks and only for small selections. The file watcher follows a changed document URL. Landing tests no longer import a module the test target does not have (clean builds failed). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…he parser Headings, fenced / verbatim blocks and blockquotes are coloured with temporary layout-manager attributes computed from MarkdownBlockParser's blocks (no second grammar, no storage or undo changes). Parsing runs off the main thread on a snapshot, debounced 200 ms, stale results dropped; buffers above 100k UTF-16 units stay untinted. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…wait while typing The re-tint is scheduled where the generation is bumped (storage delegate), so undo / redo and any other edit path re-colour; continuous typing is re-tinted at most 1 s after the first unparsed edit. Tests exercise the stale-result check, the size-limit boundary and typing next to tinted runs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The external editor stays on Cmd-E and in the File menu; two edit buttons side by side were one too many. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e map The completed-roadmap checklist (a second changelog) becomes a pointer, the 65-line file tree a short map, Tech Stack / Key Components / Project Structure merge into Under the Hood, and the duplicate build instructions go. A stale AsyncImage claim is dropped. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.
Source Edit: fix the Markdown you are reading without leaving the window (answers #31 and #34).
What it adds
How it is built
DocumentGroup(viewing:); the session writes the file itself and an unsaved-changes guard sits in front of the window delegate.Generated with Claude Code