Skip to content

[#912 Slice 1] Extract editor-core.ts + consolidate preprocessMarkdown #919

Closed

Description

@jeonghun-jj-lee

Important

Problem — The CodeMirror setup functions (baseExtensions, editableExtensions, loadLanguage, buildThemeExtension, buildSyntaxHighlightStyle, detectMode, externalUpdate) live inside editable-diff-view-core.ts, tightly coupled to the diff view. The new Preview editor needs these same functions but has nothing to do with diffs. Additionally, preprocessMarkdown is duplicated three times across the codebase with divergent implementations.

Approach — Extract the general-purpose CM6 setup functions into editor-core.ts in session-ui. Consolidate preprocessMarkdown into markdown-utils.ts. Also export a shared RENDERABLE_EXTENSIONS constant from markdown-utils.ts for use by all preview-related slices. Both extractions are pure moves — no signature changes, no behavior changes. The diff view imports from the new modules and its call sites remain unchanged.

Scope — in: function extraction, import rewiring, preprocessMarkdown consolidation, RENDERABLE_EXTENSIONS constant · out: any UI change, any new component, any behavior change

Acceptance Criteria

  • editor-core.ts exports baseExtensions, editableExtensions, loadLanguage, buildThemeExtension, buildSyntaxHighlightStyle, detectMode, and the externalUpdate annotation — all with their existing signatures
  • baseExtensions(opts: { theme: Extension, language?: LanguageSupport | null }): Extension[] — signature preserved exactly
  • editableExtensions and its co-located externalUpdate annotation both move to editor-core.ts (the annotation is referenced inside editableExtensions's update listener filter)
  • detectMode(): "light" | "dark" is extracted (it reads the theme from CSS and is needed by any consumer of buildThemeExtension)
  • editable-diff-view-core.ts imports from editor-core.ts — its own exports and behavior are unchanged
  • markdown-utils.ts exports a single preprocessMarkdown implementation — the canonical version with newlines and trim: `$$\n${body.trim()}\n$$`
  • markdown-utils.ts exports RENDERABLE_EXTENSIONS — the single source of truth for file type filtering: { markdown: [".md", ".markdown"], images: [".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp", ".ico", ".bmp"], pdf: [".pdf"] } and a helper isRenderable(filename: string): boolean
  • session-preview-tab.tsx and session-review-file-preview-v2.tsx both import preprocessMarkdown from the shared module
  • The test in markdown_preview.test.ts imports from the shared module and its assertions are updated to match the canonical implementation (the test currently defines its own copy WITHOUT newlines; 4 assertions need updating to expect the \n wrapping)
  • Files Changed tab behavior is completely unchanged (existing tests pass)

Testing Decisions

Run the existing test suite (pnpm --filter amicode test) — all tests must pass. Update markdown_preview.test.ts to: (1) delete its local preprocessMarkdown definition, (2) import from markdown-utils.ts, (3) update the 4 math-block assertions to expect the canonical $$\n...\n$$ format with trim. No new test files needed — this is a pure extraction. Add a unit test for isRenderable() covering each extension category and rejection of non-renderable extensions.

Key Decisions

Signatures preserved exactly. baseExtensions(opts: { theme: Extension, language?: LanguageSupport | null }), buildThemeExtension(mode: "light" | "dark"), loadLanguage(ext: string), detectMode(): "light" | "dark" — no wrappers, no adapters. The diff view's call sites do not change at all.

externalUpdate moves with editableExtensions. The annotation is referenced inside the update listener filter in editableExtensions. They are co-located in editor-core.ts and both re-exported.

preprocessMarkdown canonical version uses newlines + trim. The source implementation (`$$\n${body.trim()}\n$$`) is correct for KaTeX display math rendering. The test's version and the review file's copy (both no-newlines, no-trim) are updated to use the canonical import. The test assertions must change to match.

RENDERABLE_EXTENSIONS lives in markdown-utils.ts. This constant is consumed by Slices 2, 3, and 5. Defining it once here avoids duplication and gives future slices a single import.

Constraints & Invariants

  • Zero behavior change to the Files Changed tab — this is a pure extraction
  • No new dependencies added to session-ui
  • All three preprocessMarkdown call sites use the single shared export after this slice
  • The externalUpdate annotation is available from editor-core.ts for any future editor consumer

Prior Art

  • editable-diff-view-core.ts — the extraction source (functions at lines ~77, ~105, ~220, ~245, ~527; externalUpdate at line ~46)
  • session-preview-tab.tsx line 36, session-review-file-preview-v2.tsx line 39, markdown_preview.test.ts line 17 — the three preprocessMarkdown copies

Source

Part of #912

Activity

  1. jeonghun-jj-lee commented on Sep 9, 2026

    @jeonghun-jj-lee
    ContributorAuthor

    Superseded by #931 (Preview as sidebar companion). The Finder-based design is replaced by the reactive companion model — sidebar drives file selection, Preview is a pure viewer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

afkImplementable without human interaction

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions