Commit Graph
12 Commits
Author SHA1 Message Date
Claude 790fbc90e1 Region and paragraph commands: indent, reflow, counted deletes
- Indent-region skips empty lines. With the whole buffer selected, the
  empty row after the final newline became a tab-only last line.
- Reflow no longer wraps before a line's first word: a first word longer
  than the width (a URL) got a prefix-only line before it, a blank line
  or a bullet marker split from its text, and another on every reflow.
- A whitespace-only line (spaces, tabs, a CR) separates paragraphs for
  reflow; such paragraphs were merged.
- Reflow of CRLF lines strips the CR before wrapping and restores it on
  every output line; the CRs ended up in the middle of joined lines.
- A counted backspace or delete-char is one undo step even when it joins
  lines.
- The C++ highlighter stops looking for a raw-string '(' after 16
  delimiter characters; scanning the whole line at every R" was
  quadratic.

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 b9f91b0ed2 Round-seven fixes: swap name room for .tmp; input and notice details
- The shortened fallback swap name was capped at exactly NAME_MAX, so
  compaction's '<journal>.tmp' failed with ENAMETOOLONG on every
  checkpoint and the journal grew by a full copy of the buffer each
  time. Cap it at NAME_MAX - 4.
- A lone UTF-8 lead byte (8-bit Meta terminals) waited a second for
  continuation bytes on every key; wait 250 ms. An invalid byte now ends
  a pending ESC/C-k prefix instead of leaving it for the next key.
- Journal notices are shown after a deferred open's own status (which
  used to overwrite them), all pending ones at once, and the lock-out
  notice is not repeated after every save while the lock is still held.

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 78d78f6f54 Swap: tell the user when a journal is locked out or failing; long names
- SwapManager queues user notices when a journal is held by another kte
  (this session's edits are then not journaled) and, once per gap, when
  journal writes fail. Editor shows them in the status line from its
  per-frame hook. Both went only to the error log, so crash recovery was
  silently off or incomplete.
- The fallback swap name '<basename>.<hash>.swp' exceeded NAME_MAX for
  basenames over ~233 bytes, so such files were never journaled; the
  basename is shortened (on a UTF-8 boundary) only in that case.
- Audit doc: sixth-round findings.

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 853416f65a Journal insert_row as one record; keep the cursor in the buffer; fix ENABLE_ASAN
- Buffer::insert_row recorded its text and newline as two swap records
  after inserting both. A checkpoint triggered by the first (1 MiB of
  edits, or the checkpoint timer) snapshotted the newline already, and
  the second added it again on replay: recovery after undoing C-k C-k
  silently gained a blank line. It is now one record.
- Visual-line yank placed the cursor relative to its row assuming that
  row was inside the selection; after C-k a or Enter it was not, and the
  cursor ended past the end of a line or the buffer, where typed text was
  recorded for undo at a position it was not inserted at and could not
  be undone. The formula uses the nearest selected row, and run_handler
  now clamps the cursor to the buffer before and after every command.
- ENABLE_ASAN added -fsanitize=address to CMAKE_C_FLAGS only; the
  project is C++, so nothing was instrumented. Add it to
  CMAKE_CXX_FLAGS.

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 1e312fcd0b Swap: retry a journal's recovery checkpoint while idle
After a lost record the journal drops position-based records until a
full checkpoint. That checkpoint was only requested from later edits,
rate-limited to once a second; when the writer handled the failing
record before its edit asked for a checkpoint, the checkpoint failed as
well and consumed the slot, so edits made within the next second were
not recovered and, if the user stopped typing, the journal stayed behind
indefinitely. SwapManager::RetryGapCheckpoints(), called once per frame
from Editor::ProcessPendingOpens, requests it once the interval has
passed. This also made SwapReplay_LostRecord_ResyncsWithCheckpoint flaky
under load; the test now exercises the retry.

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 b1b0b3de57 Fix round-four regressions: save fallback, replace memory, regex skip
- Save's in-place fallbacks (no temp file; no hard-link copy) now apply
  only when the directory refuses a new name (EACCES, EPERM,
  ENAMETOOLONG). On ENOSPC, EDQUOT or EIO the in-place write truncated
  the file and then failed, leaving it corrupt; now the save fails and
  the file is untouched (checked on a full tmpfs).
- replace_rows_text/replace_buffer_text delete and insert only the span
  between the old and new text's common prefix and suffix (kept on
  UTF-8 boundaries). Replace-all recorded the whole buffer twice in the
  undo tree per run.
- Regex search skips long lines only while typing (limit lowered to
  2,000 bytes, as for renderer highlighting; '.*q' on a 20 KB line took
  12 s), reports how many were skipped, and next/previous match search
  every line. Previously matches on long lines could not be found.

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 ca3a6e675b Audit doc: record the fourth review round's fixes
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 58706489bb docs: record follow-up review rounds and known limitations
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 7b8ccbb8db docs: update audit fix status
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 66259db177 tests: add regression tests for audit fixes; record fix status
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 64139b4868 docs: add 2026-09-23 bug and performance audit
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 daeeecb342 Standardize error handling patterns and improve ErrorHandler integration.
- Added a comprehensive error propagation standardization report detailing dominant patterns, inconsistencies, and recommended remediations (`docs/audits/error-propagation-standardization.md`).
- Integrated `ErrorHandler` into key components, including `main.cc` for robust exception reporting, and added centralized logging to a user state path.
- Introduced EINTR-safe syscall wrappers (`SyscallWrappers.h`, `.cc`) to improve resilience of file and metadata operations.
- Enhanced `DEVELOPER_GUIDE.md` with an error handling conventions section, covering pattern guidelines and best practices.
- Identified gaps in `PieceTable` and internal helpers; deferred fixes with detailed recommendations for improved memory allocation error reporting.
2026-02-17 21:25:19 -08:00