Commit Graph
6 Commits
Author SHA1 Message Date
Claude bba7d34539 Large files: bound highlighter cache, scan search once, row ranges as one edit
- HighlighterEngine caches spans only for rows near the requested row
  and trims the cache around it past 16k entries; per-row end states are
  still kept to resume lexing. Jumping to the end of a 78 MB C++ file
  cached every row's spans (854 MB RSS, now 197 MB), and the first edit
  near the top spent 270 ms freeing them.
- Plain and regex search read lines as views into the materialized
  buffer instead of Buffer::Rows(), which built (and kept) a string per
  line, O(lines x pieces) after edits. Plain search scans the whole text
  once and tracks rows by newline.
- transform_rows() applies a per-row rewrite of a row range as one edit
  (replace_rows_text). Indent/unindent region and visual-line insert,
  backspace, delete, newline and yank used one piece-table edit per row,
  each linear in the buffer: 1.1 s per keystroke with 5,000 rows selected
  in a 26 MB file (now 4 ms), and minutes to indent a large region.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
2026-09-24 09:16:04 -07:00
Claude f853fa60b1 Highlighting: invalidate from the edited row, not the whole buffer
Every edit bumped the buffer version (through SetDirty) and called
InvalidateFrom(0), so all cached spans and line states were discarded
and stateful highlighters re-lexed from row 0 to the viewport on each
keystroke.

Buffer mutators now report the row they changed (edited_at_), which
bumps the version and tells the engine to drop only rows from there
down; a row's highlighting depends only on rows above it. A version
change that arrives without that notice still clears everything, so a
missed path cannot show stale spans. The engine keeps states as a
contiguous vector and caches spans for every row it lexes. SetDirty no
longer touches the version: the edits themselves do, including undo
and redo back to the saved state (D9 still holds; its test now checks
the highlighting itself).

Typing near the end of a 100k-line C++ file: 46.3 ms -> 0.14 ms of
highlighting work per keystroke.

Audit finding P3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
2026-09-24 09:16:04 -07:00
Claude fc9f83966c HighlighterEngine: remove background warm-up thread
The worker read the Buffer (PieceTable pieces and add buffer) while the
main thread edited it with no shared lock, and kept a raw Buffer* that
dangled once the buffer vector reallocated or shifted. PrefetchViewport
now only highlights the visible rows synchronously.

Audit finding M2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
2026-09-24 09:16:04 -07:00
kyle 337b585ba0 Reformat code. 2026-02-17 13:44:36 -08:00
kyle 78b9345799 Add swap file journaling for crash recovery.
- Introduced `SwapManager` for buffering and writing incremental edits to sidecar `.kte.swp` files.
- Implemented basic operations: insertion, deletion, split, join, and checkpointing.
- Added recovery design doc (`docs/plans/swap-files.md`).
- Updated editor initialization to integrate `SwapManager` instance for crash recovery across buffers.
2025-12-04 08:48:32 -08:00
kyle d15b241140 Refactor syntax highlighting infrastructure and related classes.
- Moved all language highlighter implementations (`CppHighlighter`, `GoHighlighter`, `JsonHighlighter`, etc.), the engine, and registry to `syntax/`.
2025-12-02 01:36:26 -08:00