refactor: move modal paste policy into editor input
This commit is contained in:
@@ -27,17 +27,19 @@ Commands: `:w [path]`, `:q`, `:q!`, `:wq [path]`, `:plugins`, and `:plugin-comma
|
||||
|
||||
`:q` refuses unsaved changes. `:wq` quits only after a successful save. Saves use a same-directory temporary file and rename, preserve existing permissions, and reject target symlinks. UTF-8 text is edited by extended grapheme; tabs render at four-cell stops. LF and trailing-newline structure are preserved; CRLF and CR are normalized to LF. Binary/terminal-control-containing text is rejected. Bracketed paste inserts only in Insert mode and never executes pasted commands in Normal mode.
|
||||
|
||||
Paste is backend input: it is ignored in Normal and Command modes, and inserts literal text in Insert mode, with CRLF/CR normalization and a 4 MiB limit. Pasted text is one undo action, separate from typing before and after it. Rejected paste reports an error without changing text, cursor, mode, or pending insert history.
|
||||
|
||||
## Module seams
|
||||
|
||||
One crate, four modules, no workspace or frontend-specific types in the editing backend:
|
||||
|
||||
- `editor`: owns buffer, cursor, modes, undo/redo, saving, command ownership, capabilities, and validated edit effects. Its low-level interface returns an `Invocation` when an external command is selected.
|
||||
- `editor`: owns buffer, cursor, modes, modal paste policy, undo/redo, saving, command ownership, capabilities, and validated edit effects. Its low-level interface returns an `Invocation` when an external command is selected.
|
||||
- `session`: `EditorSession` owns the editor and its Ruby hosts together. It loads configuration, registers eligible plugins before installing bindings, executes selected commands, and retires both host and command ownership on invocation or effect-validation failure.
|
||||
- `tui`: translates terminal events to session input, renders read-only editor state, and advertises `text` and `styled_text` capabilities. It has no plugin lifecycle callback or host storage.
|
||||
- `tui`: translates terminal events to session input, renders read-only editor state, and advertises `text` and `styled_text` capabilities. It has no plugin lifecycle callback, host storage, or paste acceptance policy.
|
||||
- `ruby`: evaluates configuration and runs isolated plugin hosts. Protocol, deadlines, and process cleanup stay inside this module.
|
||||
- The executable selects paths and frontend capabilities, opens an editor session, and launches the TUI.
|
||||
|
||||
Frontends drive `EditorSession::handle` or `execute` and inspect `editor()`; there is no mutable editor getter that could independently alter plugin registration. `apply` supports frontend-originated effects and reports validation errors; plugin effects are applied internally so a rejected result also retires its owner. The TUI retains its existing Insert-only paste policy and undo behavior.
|
||||
Frontends drive `EditorSession::handle` or `execute` and inspect `editor()`; there is no mutable editor getter that could independently alter plugin registration. Pasted text uses `Input::Paste(String)` through the same input seam as keys. Plugin effects are applied internally so a rejected result also retires its owner; there is no generic frontend effects entry point.
|
||||
|
||||
Built-in Ex commands register as the protected `core` feature in the same command registry used by plugins. External plugins cannot claim core status, replace existing commands, disable core, or bind over essential modal editing keys. `:plugins` lists active features and frontend capabilities.
|
||||
|
||||
@@ -98,4 +100,4 @@ cargo fmt --check
|
||||
ruby -c src/ruby_host.rb
|
||||
```
|
||||
|
||||
Regression checks exercise Unicode edits, undo/redo, saving and failed saves, capability/command ownership, effect atomicity, real Ruby execution, protocol errors, crash/timeout recovery, and inherited-pipe cleanup. Session checks join real Ruby execution to capability/collision rejection, complete command/binding retirement after invalid effects or host failure, surviving plugins, core editing/saving, and broken-config fallback. The executable was also exercised in PTY sessions for editing/saving, rejected-effect retirement, plugin crash and hang recovery, bracketed paste, undo/redo, scrolling, resize, and terminal restoration.
|
||||
Regression checks exercise Unicode edits, undo/redo, saving and failed saves, capability/command ownership, effect atomicity, real Ruby execution, protocol errors, crash/timeout recovery, and inherited-pipe cleanup. Backend paste checks cover ignored modes, literal Unicode/newline insertion, rejection atomicity, and typing/paste/typing undo and redo. Session checks join real Ruby execution to capability/collision rejection, complete command/binding retirement after invalid effects or host failure, surviving plugins, core editing/saving, and broken-config fallback. The executable was also exercised in PTY sessions for editing/saving, rejected-effect retirement, plugin crash and hang recovery, modal bracketed paste, rejected-paste feedback, undo/redo, scrolling, resize, and terminal restoration.
|
||||
|
||||
Reference in New Issue
Block a user