- Improve text input/event batching - Enhance debugging with optional instrumentation - Begin implementation of non-linear undo tree structure.
139 lines
9.2 KiB
Markdown
139 lines
9.2 KiB
Markdown
### Context recap
|
||
|
||
- The undo system is now tree‑based with batching rules and `KTE_UNDO_DEBUG` instrumentation hooks already present in
|
||
`UndoSystem.{h,cc}`.
|
||
- GUI path uses SDL; printable input now flows exclusively via `SDL_TEXTINPUT` to `CommandId::InsertText`, while
|
||
control/meta/movement (incl. Backspace/Delete/Newline and k‑prefix) come from `SDL_KEYDOWN`.
|
||
- Commit boundaries must be enforced at well‑defined points (movement, non‑editing commands, newline, undo/redo, etc.).
|
||
|
||
### Status summary (2025‑12‑01)
|
||
|
||
- Input‑path unification: Completed. `GUIInputHandler.cc` routes all printable characters through `SDL_TEXTINPUT → InsertText`.
|
||
Newlines originate only from `SDL_KEYDOWN → Newline`. CR/LF are filtered out of `SDL_TEXTINPUT` payloads. Suppression
|
||
rules prevent stray `TEXTINPUT` after meta/prefix/universal‑argument flows. Terminal input path remains consistent.
|
||
- Tests: `test_undo.cc` expanded to cover branching behavior, UTF‑8 insertion, multi‑line newline/join, and typing batching.
|
||
All scenarios pass.
|
||
- Instrumentation: `KTE_UNDO_DEBUG` hooks exist in `UndoSystem.{h,cc}`; a CMake toggle has not yet been added.
|
||
- Commit boundaries: Undo/Redo commit boundaries are in place; newline path commits immediately by design. A final audit
|
||
pass across movement/non‑editing commands is still pending.
|
||
- Docs: This status document updated. Further docs (instrumentation how‑to and example traces) remain pending in
|
||
`docs/undo.md` / `docs/undo-roadmap.md`.
|
||
|
||
### Objectives
|
||
|
||
- Use the existing instrumentation to capture short traces of typing/backspacing/deleting and undo/redo.
|
||
- Unify input paths (SDL `KEYDOWN` vs `TEXTINPUT`) and lock down commit boundaries across commands.
|
||
- Extend tests to cover branching behavior, UTF‑8, and multi‑line operations.
|
||
|
||
### Plan of action
|
||
|
||
1. Enable instrumentation and make it easy to toggle
|
||
- Add a CMake option in `CMakeLists.txt` (root project):
|
||
`option(KTE_UNDO_DEBUG "Enable undo instrumentation logs" OFF)`.
|
||
- When ON, add a compile definition `-DKTE_UNDO_DEBUG` to all targets that include the editor core (e.g., `kte`,
|
||
`kge`, and test binaries).
|
||
- Keep the default OFF so normal builds are quiet; ensure both modes compile in CI.
|
||
|
||
2. Capture short traces to validate current behavior
|
||
- Build with `-DKTE_UNDO_DEBUG=ON` and run the GUI frontend:
|
||
- Scenario A: type a contiguous word, then move cursor (should show `Begin(Insert)` + multiple `Append`, single
|
||
`commit` at a movement boundary).
|
||
- Scenario B: hold backspace to delete a run, including backspace batching (prepend rule); verify
|
||
`Begin(Delete)` with prepended `Append` behavior, single `commit`.
|
||
- Scenario C: forward deletes at a fixed column (anchor batching); expected single `Begin(Delete)` with same
|
||
column.
|
||
- Scenario D: insert newline (`Newline` node) and immediately commit; type text on the next line; undo/redo
|
||
across the boundary.
|
||
- Scenario E: undo chain and redo chain; then type new text and confirm redo branch gets discarded in logs.
|
||
- Save representative trace snippets and add to `docs/undo.md` or `docs/undo-roadmap.md` for reference.
|
||
|
||
3. Input‑path unification (SDL `KEYDOWN` vs `TEXTINPUT`) — Completed 2025‑12‑01
|
||
- In `GUIInputHandler.cc`:
|
||
- Ensure printable characters are generated exclusively from `SDL_TEXTINPUT` and mapped to
|
||
`CommandId::InsertText`.
|
||
- Keep `SDL_KEYDOWN` for control/meta/movement, backspace/delete, newline, and k‑prefix handling.
|
||
- Maintain suppression of stray `SDL_TEXTINPUT` immediately following meta/prefix or universal‑argument
|
||
collection so no accidental text is inserted.
|
||
- Confirm that `InsertText` path never carries `"\n"`; newline must only originate from `KEYDOWN` →
|
||
`CommandId::Newline`.
|
||
- If the terminal input path exists, ensure parity: printable insertions go through `InsertText`, control via key
|
||
events, and the same commit boundaries apply.
|
||
- Status: Implemented. See `GUIInputHandler.cc` changes; tests confirm parity with terminal path.
|
||
|
||
4. Enforce and verify commit boundaries in command execution — In progress
|
||
- Audit `Command.cc` and ensure `u->commit()` is called before executing any non‑editing command that should end a
|
||
batch:
|
||
- Movement commands (left/right/up/down/home/end/page).
|
||
- Prompt accept/cancel transitions and mode switches (search prompts, replace prompts).
|
||
- Buffer/file operations (open/switch/save/close), and focus changes.
|
||
- Before running `Undo` or `Redo` (already present).
|
||
- Ensure immediate commit at the end of atomic edit operations:
|
||
- `Newline` insertion and line joins (`Delete` of newline when backspacing at column 0) should create
|
||
`UndoType::Newline` and commit immediately (parts are already implemented; verify all call sites).
|
||
- Pastes should be a single `Paste`/`Insert` batch per operation (depending on current design).
|
||
|
||
5. Extend automated tests (or add them if absent) — Phase 1 completed
|
||
- Branching behavior ✓
|
||
- Insert `"abc"`, undo twice (back to `"a"`), insert `"X"`, assert redo list is discarded, and new timeline
|
||
continues with `aX`.
|
||
- Navigate undo/redo along the new branch to ensure correctness.
|
||
- UTF‑8 insertion and deletion ✓
|
||
- Insert `"é漢"` (multi‑byte characters) via `InsertText`; verify buffer content and that a single Insert batch
|
||
is created.
|
||
- Undo/redo restores/removes the full insertion batch.
|
||
- Backspace after typed UTF‑8 should remove the last inserted codepoint from the batch in a single undo step (
|
||
current semantics are byte‑oriented in buffer ops; test to current behavior and document).
|
||
- Multi‑line operations ✓
|
||
- Newline splits a line: verify an `UndoType::Newline` node is created and committed immediately; undo/redo
|
||
round‑trip.
|
||
- Backspace at column 0 joins with previous line: record as `Newline` deletion (via `UndoType::Newline`
|
||
inverse); undo/redo round‑trip.
|
||
- Typing and deletion batching ✓ (typing) / Pending (delete batching)
|
||
- Typing a contiguous word (no cursor moves) yields one `Insert` node with accumulated text.
|
||
- Forward delete at a fixed anchor column yields one `Delete` batch. (Pending test)
|
||
- Backspace batching uses the prepend rule when the cursor moves left. (Pending test)
|
||
- Place tests near existing test suite files (e.g., `tests/test_undo.cc`) or create them if not present. Prefer
|
||
using `Buffer` + `UndoSystem` directly for tight unit tests; add higher‑level integration tests as needed.
|
||
|
||
6. Documentation updates — In progress
|
||
- In `docs/undo.md` and `docs/undo-roadmap.md`:
|
||
- Describe how to enable instrumentation (`KTE_UNDO_DEBUG`) and an example of trace logs.
|
||
- List batching rules and commit boundaries clearly with examples.
|
||
- Document current UTF‑8 semantics (byte‑wise vs codepoint‑wise) and any known limitations.
|
||
- Current status: this `undo-state.md` updated; instrumentation how‑to and example traces pending.
|
||
|
||
7. CI and build hygiene — Pending
|
||
- Default builds: `KTE_UNDO_DEBUG` OFF.
|
||
- Add a CI job that builds and runs tests with `KTE_UNDO_DEBUG=ON` to ensure the instrumentation path remains
|
||
healthy.
|
||
- Ensure no performance regressions or excessive logging in release builds.
|
||
|
||
8. Stretch goals (optional, time‑boxed) — Pending
|
||
- IME composition: confirm that `SDL_TEXTINPUT` behavior during IME composition does not produce partial/broken
|
||
insertions; if needed, buffer composition updates into a single commit.
|
||
- Ensure paste operations (multi‑line/UTF‑8) remain atomic in undo history.
|
||
|
||
### How to run the tests
|
||
|
||
- Configure with `-DBUILD_TESTS=ON` and build the `test_undo` target. Run the produced binary (e.g., `./test_undo`).
|
||
The test prints progress and uses assertions to validate behavior.
|
||
|
||
### Deliverables
|
||
|
||
- CMake toggle for instrumentation and verified logs for core scenarios. (Pending)
|
||
- Updated `GUIInputHandler.cc` solidifying `KEYDOWN` vs `TEXTINPUT` separation and suppression rules. (Completed)
|
||
- Verified commit boundaries in `Command.cc` with comments where appropriate. (In progress)
|
||
- New tests for branching, UTF‑8, and multi‑line operations; all passing. (Completed for listed scenarios)
|
||
- Docs updated with how‑to and example traces. (Pending)
|
||
|
||
### Acceptance criteria
|
||
|
||
### Current status (2025‑12‑01) vs acceptance criteria
|
||
|
||
- Short instrumentation traces match expected batching and commit behavior for typing, backspace/delete, newline, and
|
||
undo/redo. — Pending (instrumentation toggle + capture not done)
|
||
- Printable input comes exclusively from `SDL_TEXTINPUT`; no stray inserts after meta/prefix/universal‑argument flows.
|
||
— Satisfied (GUI path updated; terminal path consistent)
|
||
- Undo branching behaves correctly; redo is discarded upon new commits after undo. — Satisfied (tested)
|
||
- UTF‑8 and multi‑line scenarios round‑trip via undo/redo according to the documented semantics. — Satisfied (tested)
|
||
- Tests pass with `KTE_UNDO_DEBUG` both OFF and ON. — Pending (no CMake toggle yet; default OFF passes) |