Functional Design Plan: Unit 1 — Core Editor Engine

Unit Context

Execution Checklist

Phase 1: Domain Entities

Phase 2: Business Logic Model

Phase 3: Business Rules

Phase 4: Frontend Components


Clarification Questions

Question 1

How should incremental re-parsing work when the user edits text?

A) Re-parse only the edited block (paragraph/heading/etc.) — fastest, but may miss cross-block effects (e.g., opening a code fence) B) Re-parse the edited block plus adjacent blocks — balanced approach for detecting multi-block elements C) Re-parse the entire document on every edit — simplest to implement, may be slow on large documents X) Other (please describe after Answer: tag below)

Claude Code分析: swift-markdownは増分パースAPIを持たず、クロスブロック効果(コードフェンス開始で後続ブロックすべてが変化等)は実在する。cmark(C実装)は大きなドキュメントでも極めて高速であり、MVPでのボトルネックはパースよりもNSAttributedStringの適用・レンダリング側にある。 Codexレビュー: Cが最適。正確性と実装コストが決め手。MVPの最適分割は「正確性のための全ドキュメントパース + UI コスト制御のための選択的ブロック再レンダリング」。実装戦略: (1) 編集ごとにパーサーアクターでオフメインスレッド解析、(2) 旧/新EditorNodeModel配列を安定IDとコンテンツハッシュでdiff、(3) 変更された非アクティブブロックのみNSAttributedStringに再レンダリング、(4) TextKit 2のテキスト要素/段落範囲で該当領域のみ置換。リスク軽減: ドキュメントリビジョンで古い結果を破棄、短いデバウンスでキーストロークごとの再パースを抑制、IME composition中のアクティブブロック置換を回避。将来の最適化パスも同じAPIの背後に隠蔽可能。

Question 2

How should the active block boundary be defined for paragraph-level delayed rendering?

A) Structural block — the AST-level block containing the cursor (paragraph, heading, list item, code block as a whole) B) Visual line — the single line the cursor is on C) Paragraph cluster — the paragraph plus any attached inline elements (e.g., a paragraph followed by its sub-list) X) Other (please describe after Answer: tag below)

Claude Code分析: Typoraは要素レベルのトグルだが、Shoe ChooのMVPは段落レベルの遅延レンダリング。TextKit 2のNSTextParagraphが自然な単位であり、構造ブロック(A)はswift-markdownのASTノードに直接マッピングされる。コードブロック内のどこにカーソルがあっても全体を生表示すべきであり、視覚行(B)では不十分。 Codexレビュー: Aが最適。構造ブロック+構文種別ごとの明示的ルールを推奨。MVP境界ルール: 段落/見出し→そのノード、コードフェンス→ブロック全体(フェンス構文+内容すべて)、テーブル→テーブル全体(行をまたぐ構造)、リスト項目→現在のリスト項目のみ(リスト全体ではない)、ブロック引用→引用内の現在の子ブロック(引用コンテナ全体ではない)、ブロック引用内のネストリスト→最内のリスト項目。UX上の利点: 「編集中のブロックは生表示、他はレンダリング済み」という説明可能な動作。実装: EditorNodeModelにkindsourceRangecontainerPathactivationScopeを格納し、キャレット位置→ソースオフセット変換→最内ノード検出→ルールで正規化→アクティブノードとしてマーク。