Sapling will use native platform text systems for the editor prototype:
- NSTextView on macOS
- UITextView on iOS
These views will be wrapped behind a Sapling editor abstraction.
SwiftUI TextEditor will not be used as the primary editor implementation.
## Rationale
Sapling's hybrid Markdown editor requires advanced control over cursor movement, selection state, layout, attributed rendering, and editing behavior.
SwiftUI TextEditor is useful for simple text entry, but it does not expose enough low-level editing hooks to validate the active-line source and inactive-line rendered model cleanly.
NSTextView and UITextView provide direct access to TextKit, attributed text storage, selection ranges, delegates, layout managers, and platform editing behaviors. That makes them better foundations for Milestone 1 validation.
## Consequences
Positive:
- The prototype can inspect and control selection ranges directly.
- Line-level styling and rendering experiments can be performed in-place.
- The app can preserve native editing behavior while testing hybrid Markdown concepts.
- The implementation can remain SwiftUI at the application layer.
Negative:
- AppKit and UIKit bridging adds platform-specific code.
- The editor abstraction must prevent the rest of the app from depending directly on NSTextView or UITextView.
- A future custom editor engine may still be required if line replacement or overlay rendering cannot preserve cursor correctness.
Sapling's core user experience depends on a hybrid editing model:
* active content is displayed as Markdown source
* inactive content is displayed as rendered output
This model combines advantages of:
* plain-text Markdown editors
* live preview editors
* rendered document editors
However, early in development there was uncertainty regarding:
* editor performance
* large-document scalability
* rendering determinism
* active-line tracking
* viewport stability
* TextKit suitability
* code block rendering
* interactive rendered elements
A significant portion of Milestones 1–3 was dedicated to validating the feasibility of this architecture before proceeding with workspace and Git functionality.
## Decision
Sapling adopts a hybrid rendered/source editing architecture as its primary editing model.
The architecture is considered validated and will remain the foundation of the application.
The editor will not be rewritten and no custom text engine is planned at this time.
## Validated Properties
The following properties have been demonstrated through implementation, profiling, and real-world testing.
### Large Document Scalability
Documents exceeding:
* 50,000 lines
* 5 MB of Markdown content
remain usable.
Profiling identified document-wide operations and replaced them with incremental approaches.
### Incremental Editing
Sapling maintains:
* incremental line indexing
* incremental invalidation
* incremental rendering updates
Editor interactions scale with the edited region rather than total document size.
### Rendering Determinism
Rendering output is derived from document state rather than interaction history.
Rendered content behaves consistently across:
* scrolling
* focus changes
* selection changes
* document reloads
### Editable Regions
The editor supports:
* single-line editing
* multi-line editing
* block editing
Rendered content transitions into source mode when actively edited.
### Rendered Elements
The editor supports first-class rendered elements including:
* headings
* task lists
* links
* code blocks
The architecture supports future rendered elements without fundamental redesign.
### Code Blocks
Code blocks are treated as semantic block elements rather than styled text.
They support:
* rendered containers
* syntax highlighting
* editable source transitions
### Viewport Stability
Rendered/source transitions preserve user context and do not require disruptive viewport repositioning.
## Technology Choice
The editor continues to use:
* NSTextView
* NSTextStorage
* NSLayoutManager
* TextKit
Investigation determined that observed performance bottlenecks originated primarily from Sapling's own document-wide algorithms rather than AppKit itself.
After introducing:
* incremental line indexing
* incremental invalidation
* region-based rendering
TextKit remained sufficiently performant for the project's requirements.
## Alternatives Considered
### Custom Text Engine
Rejected.
Reasons:
* significantly higher complexity
* increased maintenance burden
* no demonstrated need
* current architecture satisfies project requirements
### Split Editor / Preview Model
Rejected.
Reasons:
* interrupts writing flow
* increases cognitive overhead
* conflicts with Sapling's editing philosophy
### Full WYSIWYG Editor
Rejected.
Reasons:
* obscures Markdown source
* reduces portability
* conflicts with project goals
## Consequences
### Positive
* Markdown remains the source of truth.
* Editing remains fast on large documents.
* Rendered content improves readability.
* The editor architecture is stable enough for future feature development.
* Workspace and Git functionality can now be built on top of a proven editor foundation.