CLAUDE.md is a one-line @AGENTS.md import; make gate configures, builds, and runs kte_tests. CMakeLists.txt registers the tests with CTest. .junie/guidelines.md points Junie at AGENTS.md.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
RegexEngine.h/.cc wrap the regex engine for search, regex replace-all and
the terminal and ImGui renderers' match highlighting:
- With KTE_USE_PCRE2 (default ON; used when pkg-config finds libpcre2-8,
linked as -lpcre2-8) patterns are compiled by PCRE2 with its JIT and
matched under a match limit: catastrophic backtracking stops with a
status note instead of hanging the editor, and matching does not
recurse on the C stack (no large-stack thread; the per-keystroke and
per-frame line limit is 1 MiB instead of 2,000 bytes). Otherwise
std::regex is used as before.
- Replacement strings follow std::regex_replace (ECMAScript as libstdc++
reads it) with either engine: the PCRE2 path expands $&, $n, $`, $',
$$ itself and steps over empty matches the same way.
- Regex search walks lines over the materialized text instead of calling
GetLineView per row. The terminal renderer compiles the pattern once
per frame (it compiled it for every row).
- Only one checkpoint per journal is queued at a time: whole-file edits
in a row on a large buffer each queued a full copy of the buffer.
- default.nix and the Dockerfile add pcre2 and pkg-config.
On 26 MB: regex keystroke 1.6 -> 0.14 ms, next 62 -> 6 ms, replace-all
929 -> 438 ms; a rarely matching regex over 105 MB: 1.55 s -> 0.10 s.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
- A checkpoint larger than one record (16 MiB) is written as CHKPT_BEGIN
[size u64, CRC-32], CHKPT_DATA chunks and CHKPT_END. Replay assembles it
and applies it only when complete with the size and CRC matching; an
unfinished one is a torn tail (valid_bytes stops before it). Buffers
over 16 MiB could not be checkpointed before: a lost record left their
journal behind for good, and they were never compacted. Records are
written as segments straight from the snapshot. Header version 2;
version 1 journals are still read.
- Checkpoint thresholds scale with the buffer size (edits of half its
size; the timer only after a sixteenth; compaction at twice its size;
gap retries spaced by size), and a checkpoint that would compact is
written straight into the compacted journal instead of being appended
and then copied.
- The recovery prompt keeps the content it replayed for its preview and
installs it on 'y', instead of replaying the journal a second time.
- A base file over 64 MiB gets its CRC from the writer thread before it
creates the journal (it had none, so touching such a file made its
journal unusable for recovery).
- kte_tests takes optional name substrings to run a subset of tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
apply_syntax_to_buffer() was called every frame and unconditionally reset
edit mode from the file extension, making it impossible to toggle out of
writing mode for .txt/.md files. Add edit_mode_detected_ flag to Buffer so
auto-detection runs once per buffer. Writing mode now also disables syntax
highlighting as intended. Propagate edit_mode_ through Buffer copy/move ops.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>