Claude 061e836fa4 Swap/recovery: second-pass fixes from the follow-up review
- Recovery works when another named buffer is current. On that path
  OpenFile's NotifyFilenameChanged deleted the journal (old path ==
  new path) that was about to be replayed; the swap was lost and the
  file opened without the edits (pre-existing).
- After recovering from a journal with a torn final record, the torn
  bytes are truncated before the session appends to it (ReplayFile now
  reports the valid prefix length). A journal that recovers nothing is
  removed instead of appended to.
- Reload restarts the journal; recovery used to replay the edits the
  reload discarded.
- Opening a file that is already open switches to its buffer (in
  OpenFile and before the recovery check). Two buffers for one file
  interleaved records in one journal, and closing either unlinked it.
- Swap file names escape '!' and '%', so distinct paths no longer
  share a journal ('/x/a!b' vs '/x/a/b'). Swap files for paths that
  contain those characters get new names.
- The gap flag is cleared when the journal restarts, and a gap that
  cannot be closed (buffer too large to checkpoint) is reported once.
- crc32's table is initialised thread-safely; writer-thread error
  reports identify the buffer by journal path instead of racing on
  Buffer::Filename(); Close() no longer retries on EINTR (the fd is
  already released and may have been reused).

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
2025-11-30 19:08:34 -08:00
2026-01-02 09:50:08 -08:00
2026-01-02 10:39:33 -08:00
2026-09-24 09:16:04 -07:00
2025-11-30 22:02:23 -08:00
2025-11-30 19:08:34 -08:00
2025-11-30 21:07:41 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00
2026-02-17 13:44:36 -08:00

kte - Kyle's Text Editor

Editor screenshot

Vision

kte is a small, fast, and understandable text editor with a terminal-first UX and an optional ImGui GUI. It modernizes the original ke editor while preserving its familiar WordStar/VDE‑style command model and Emacs‑influenced ergonomics. The focus is on simplicity of design, excellent latency, and pragmatic features you can learn and keep in your head.

I am experimenting with using Jetbrains Junie to assist in development, largely as a way to learn the effective use of agentic coding. I worked with the agent by feeding it notes that I've been taking about text editors for the last few years, as well as the sources from the original ke editor that is all handwritten C.

Project Goals

  • Keep the core minimal and readable; favor straightforward data structures (gap buffer, piece table) and incremental evolution.
  • Round‑trip editing of large files with low latency in a terminal environment.
  • Preserve ke keybindings and command semantics wherever sensible; smooth migration for ke users.
  • Provide a clean separation between core model, input, and rendering so a GUI can grow independently of the TUI.
  • Minimize dependencies; the GUI layer remains optional and isolated.

Keybindings

kte maintains ke’s command model while internals evolve. Highlights ( subject to refinement):

  • K‑command prefix: C-k enters k‑command mode; exit with ESC or C-g.
  • Save/Exit: C-k s (save), C-k x or C-k C-x (save and exit), C-k q (quit with confirm), C-k C-q (quit immediately).
  • Editing: C-k d (kill to EOL), C-k C-d (kill line), C-w (kill region), C-y (yank), C-u (universal argument).
  • Navigation/Search: C-s (incremental find), C-r (regex search), ESC f/b (word next/prev), ESC BACKSPACE (delete previous word).
  • Buffers/Files: C-k e (open), C-k b/C-k p (switch), C-k c (close), C-k l (reload).
  • Misc: C-l (refresh), C-g (cancel), C-k g (goto line).

See ke.md for the canonical ke reference retained for now.

Build and Run

Prerequisites: C++20 compiler, CMake, and ncurses development headers/libs.

Dependencies by platform

  • macOS (Homebrew)

    • Terminal (default):
      • brew install ncurses
    • Optional GUI (enable with -DBUILD_GUI=ON):
      • brew install sdl2 freetype
      • OpenGL is provided by the system framework on macOS; no package needed.
  • Debian/Ubuntu

    • Terminal (default):
      • sudo apt-get install -y libncurses5-dev libncursesw5-dev
    • Optional GUI (enable with -DBUILD_GUI=ON):

      sudo apt-get install -y libsdl2-dev libfreetype6-dev mesa-common-dev
      • The mesa-common-dev package provides OpenGL headers/libs ( libGL).
  • NixOS/Nix

    • Terminal (default):
      • Ad-hoc shell: nix-shell -p cmake gcc ncurses
    • Optional GUI (enable with -DBUILD_GUI=ON):
      • Ad-hoc shell: nix-shell -p cmake gcc ncurses SDL2 freetype libGL
    • With flakes/devshell (example flake.nix inputs not provided): include ncurses for TUI, and SDL2, freetype, libGL for GUI in your devShell.

Notes

  • The GUI is OFF by default to keep SDL/OpenGL/Freetype optional. Enable it by configuring with -DBUILD_GUI=ON and ensuring the GUI deps above are installed for your platform.
  • If you previously configured with GUI ON and want to disable it, reconfigure the build directory with -DBUILD_GUI=OFF.

Example build:

cmake -S . -B cmake-build-debug -DCMAKE_BUILD_TYPE=Debug
cmake --build cmake-build-debug

Run:

./cmake-build-debug/kte [files]

If you configured the GUI, you can also run the GUI-first target (when built as kge) or request the GUI from kte:

./cmake-build-debug/kte --gui [files]
# or if built/installed as a separate GUI target
./cmake-build-debug/kge [files]

GUI build example

To build with the optional GUI (after installing the GUI dependencies listed above):

cmake -S . -B cmake-build-debug -DCMAKE_BUILD_TYPE=Debug -DBUILD_GUI=ON
cmake --build cmake-build-debug
./cmake-build-debug/kte --gui [files]

Status

  • This project is a hobby text editor meant to be my personal editor. I do not warrant its suitability for anyone else.
S
Description
No description provided
Readme
64 MiB
Languages
C++ 92.6%
C 6.5%
Objective-C++ 0.6%
CMake 0.2%