feat: add guarded and forceful editor restart actions
This commit is contained in:
@@ -24,12 +24,14 @@ One editor crate; the workspace also includes its patched Crossterm dependency.
|
||||
- `session`: `EditorSession` owns the editor, native LSP, and Ruby hosts together. It loads configuration once, registers eligible plugins before installing shared bindings, tracks document open/change/save/close events, polls native and plugin results, validates versioned diagnostics/navigation/completion, and retires failed plugin ownership. Each tab with a comparison has a cancellable repository worker; inactive tabs keep their workers and receive tagged results without changing visible focus. Closed or superseded comparisons reject stale results. Focused diff text supports native LSP navigation, hover, and diagnostics; read-only buffers still reject asynchronous editing effects, and selectors/file lists are not document-action targets.
|
||||
- `tui`: translates terminal events to session input, renders read-only active-buffer state, keeps frontend-owned viewports and syntax caches by stable buffer ID or immutable diff snapshot/file identity, and advertises `text`, `styled_text`, and `diagnostics` capabilities. It maps semantic tokens and diagnostics to terminal styling and has no server/protocol logic 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.
|
||||
- The executable selects paths and frontend capabilities, opens an editor session, and launches the TUI. On restart, it restores the terminal and drops the entire `EditorSession`, including workers and plugin hosts, before relaunching the same executable with the original CLI arguments. Unix replaces the process with `exec`; other platforms spawn a fresh process and return. Startup rereads configuration and the original startup file, or creates an unnamed buffer; current buffers, tabs, views, and session state are not restored.
|
||||
|
||||
## Frontend interface
|
||||
|
||||
Frontends drive `EditorSession::handle` or `execute`, periodically call `poll()` even without input, and inspect `editor()`; there is no mutable editor getter that could independently alter plugin registration. `poll()` reports whether background activity requires redrawing. 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.
|
||||
|
||||
`Editor::should_quit()` tells the frontend to exit its input/render loop for either quit or restart; `Editor::should_restart()` distinguishes a requested executable relaunch from an ordinary exit. Normal-mode `core.restart` / `:restart` first closes clean buffers across all tabs, panes, and historical views. Remaining dirty buffers retain unsaved text and undo/redo history, block the exit/relaunch request with a warning, and leave the editor interactive; already closed clean buffers remain closed. `core.force_restart` / `:force_restart` (alias `:restart!`) requests relaunch without saving, discarding unsaved text. Both commands take no arguments and have no default binding. Force restart uses palette confirmation, while configured action bindings execute directly.
|
||||
|
||||
Session polling schedules synchronous `Editor::refresh_files()` metadata scans every 250 ms; the editor method itself is unthrottled and reports whether a redraw is needed. Scans include active and parked live buffers across inactive tabs/panes, but never immutable historical snapshots, and read content only after metadata changes. Valid changed disk text replaces only clean buffers, updates the saved baseline and text revision, clears stale undo/redo, preserves/clamps every associated view, invalidates annotations and stale requests, and refreshes live comparisons. Dirty buffers keep edits; missing, unreadable, or invalid changed files preserve text and report a warning.
|
||||
|
||||
Every save independently re-reads disk content and compares its LF-normalized text with the saved baseline, rather than trusting polling or modification timestamps. Normal writes refuse external changes/deletion; newly opened nonexistent paths can be created normally. Typed `core.force_save` / `core.force_save_and_quit` expose canonical `:force_save [path]` / `:force_save_and_quit [path]` and aliases `:w!` / `:wq!`. Force bypasses only the external-change check, retaining snapshot read-only, target-symlink, and another-buffer path-ownership protections. Both save-and-quit variants quit only after a successful save and only when all buffers are clean.
|
||||
|
||||
Reference in New Issue
Block a user