EditorPane loads the resolved file, polls it every 2 s while visible,
reloads a clean buffer silently and shows the "Changed on disk" banner
for a dirty one, saves against the loaded hash, and intercepts closing
with unsaved edits. ViewerApp routes to the editor, the not-found list
or the choose list.
Preflight rulings carried: one reload helper that passes the truncated
flag and polled hash (P3/P14), a poll right after a save conflict so
Overwrite on save adopts the current hash (P4), a chunked base64
encoder (P5), StatusIndicator for the badge (P11), banner-only test
queries (P2), and a Range geometry stub for jsdom (P17). A save the
container user may not write is reported as read-only and keeps the
buffer.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Implements Task 10 of the terminal file viewer plan: highlightLine.ts
(line-range StateField + setHighlight effect), viewerTheme.ts (EditorView
theme + syntax HighlightStyle), and CodeEditor.tsx (the React wrapper with
getDoc/setDoc/goTo/focus).
Also implements languages.ts + languages.test.ts, moved here from Task 7
per preflight ruling P1 (they need @codemirror/* packages, which only
Task 6 installs).
Preflight rulings applied:
- P1: languages.ts/.test.ts live here, not in Task 7.
- P12: syntax colours are `--syntax-*` custom properties in index.css,
not hard-coded hex.
- P13: languageFor tests assert `.not.toBeNull()` for mapped extensions
and move README to the "returns null" case, instead of the vacuous
`.resolves.toBeDefined()`.
- P14(c): readOnly extension array factored into readOnlyExt(readOnly)
instead of being duplicated in CodeEditor.
- P16: no custom Mod-g binding; searchKeymap's Mod-Alt-g covers "go to
line" already.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Task 6 of the terminal file viewer plan: app/viewer.html plus
src/viewer/{main,ViewerApp}.tsx (placeholder ViewerApp for Task 11 to
replace), registers viewer.html as a second Rollup input in
vite.config.ts, adds the file-viewer capability restricted to
file-viewer-* windows (allow-listen/unlisten for the goto event,
allow-destroy for the close-button/prevent_close interaction,
allow-internal-toggle-devtools to match default.json's dev
convenience), installs the CodeMirror packages Task 10 builds
languages.ts on top of (P1), and pins the viewer entry/capability
with a Rust fallback-trap test.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- viewerState.ts: pure reducer for the clean/dirty, same/changed/gone,
container-down and overwrite-on-save states (spec §5), plus the
pollEffect/canSave helpers EditorPane will drive off.
- editability.ts: classifies a fetched file as text/image/binary and
decides whether it is editable, deferring to Rust's readonly_reason
when it refuses.
Per preflight P1, languages.ts/.test.ts move to Task 10 (needs the
CodeMirror packages Task 6 installs; out of scope for this task's
worktree). Per P3, the "reloaded" action now carries `truncated` and
`polledHash` so a poll-driven reload of a truncated (prefix-hash-only)
file adopts the polled full-file hash instead of re-triggering a
reload on every subsequent poll -- with a reducer test covering it.
Per P13, tightened the poll_failed/canSave test to start from a dirty
doc so it actually exercises containerDown rather than passing only
because the doc was clean.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>