Improve editor rendering, plugins, LSP, and undo#68
Open
fcoury wants to merge 30 commits into
Open
Conversation
Remove the duplicate test-only action reducer so integration tests execute the same editor dispatch path as production. Tighten cursor, line-boundary, and Unicode handling around grapheme-aware editing so movement, deletion, and diagnostics avoid byte-index assumptions.
Route window switching and layout mutations through editor helpers so active-window state is saved and reloaded consistently. Add coverage that verifies split window navigation preserves each window cursor independently.
Extract cursor terminal-position calculation so it can be tested without terminal output. Use the active window buffer line directly when computing display columns, avoiding double application of `vtop` after scrolling.
Use the same terminal cursor position for overlay avoid-cursor placement that rendering uses for the actual cursor. Mark overlays dirty when recalculated placement changes so cursor-driven overlays redraw after moving across screen regions.
Treat render-buffer text writes as terminal cell writes so wide characters reserve their continuation cell. Tighten boundary checks to ignore `x == width` and `y == height` writes instead of allowing them to spill into later cells.
Measure plugin overlay width and right alignment in terminal display columns so wide characters align correctly. Clear the full overlay area before rendering each row to prevent stale cells when content shrinks or shifts.
Use character-aware deletion for command and search backspace instead of byte slicing. Clear the command line before rendering prompt text so Unicode search input and narrow terminal widths do not leave stale cells or underflow padding.
Use display-width-aware, saturating layout math for statusline segments so narrow terminals do not underflow while computing file and position areas. Clear the row before writing statusline segments to avoid stale cells when segments shrink or overlap.
Measure completion labels, icons, details, and documentation with terminal display widths so popup rows stay aligned for emoji and CJK text. Add shared helpers for fitting strings to display columns without splitting grapheme clusters during truncation.
Keep picker lists safe when filtering leaves no matches, and make list row truncation use terminal display widths for wide Unicode labels. Use character-aware backspace and display-width cursor math for picker search text so non-ASCII search terms do not panic or misplace the cursor.
Draw info tooltip text from the dialog content origin instead of applying the horizontal offset twice, which misplaced content away from its border. Measure and pad tooltip rows by display width so wide Unicode text is clipped and filled consistently with other popup surfaces.
Use display-width-aware title measurement and truncation when drawing dialog borders, so long titles cannot underflow the centering calculation. This also keeps Unicode titles aligned with the rest of the popup rendering surfaces that measure terminal columns instead of bytes.
Use terminal display width instead of byte length when reporting the cursor position for command and search prompts. This keeps the cursor aligned with rendered commandline text when prompts contain wide Unicode characters such as emoji or CJK text.
Use saturating geometry for picker dialog, list, separator, and cursor rows so small terminal heights cannot underflow popup layout calculations. Make editor viewport height saturating as well, matching the window manager's reserved status and command line handling on very small screens.
Move info tooltip placement into a small geometry helper that uses saturating math for cursor offsets, horizontal fitting, and available height checks. This prevents hover/info popup layout from underflowing on tiny terminal heights after viewport height is clamped to zero.
Skip statusline and commandline drawing when terminal dimensions leave no valid row for those chrome elements, and use saturating command/search cursor rows. This prevents refresh rendering from underflowing on one-row or zero-size test terminal layouts.
Keep split membership checks from mutating the traversal index before recursing into nested split trees, so resize commands can reach the active window's inner parent split. Also report a no-op when resizing a single window, since there is no parent split ratio to adjust.
Advance the window traversal index when removing the target leaf so later siblings are not mistaken for the same active window during close. This lets closing the first window in a split collapse to the remaining sibling instead of failing to remove the active window.
Build diagnostic rows with display-width-aware fitting so indicators and messages cannot spill beyond the available window columns. Preserve truncation with an ellipsis for wide Unicode diagnostics and keep cramped rows bounded when many diagnostics share a line.
Add a bounded completion popup layout path that clamps popup width, flips above the cursor when there is not enough space below, and limits rendered rows to the available terminal height. Use terminal cursor coordinates for LSP completion popups so placement includes gutter and window offsets instead of buffer-local cursor positions.
Add configurable language server definitions and route editor LSP requests through a manager keyed by document language and workspace root. Keep Rust enabled by default while moving `rust-analyzer` details into server config so other stdio LSPs can be added through `config.toml`.
Add a plugin-owned side panel surface with focus routing, layout reservation, filesystem listing, and directory watch APIs so plugins can build persistent tree-style UI. Register a sample `NeoTree` plugin on `Ctrl-e`, including toggle behavior, file opening, and explicit editor focus handoff after file activation.
Clamp viewport and cursor state after movement actions so commands that overshoot the buffer cannot land past the final navigable line. Cover `G`, oversized line jumps, direct cursor positioning, paging, and scrolling against files that end with a trailing newline.
Keep `w` and `b` from scrolling when their destination line is already visible. Word movement should update the cursor within the current viewport and only scroll when the target word is offscreen. Add a movement regression that asserts both next-word and previous-word motions preserve `vtop` for visible targets.
Allow page movement to use partial pages at file edges so `Ctrl-b` and `Ctrl-f` land on the top or final navigable line instead of refusing to move when a full page is unavailable. Fix visual selection rendering to include the final visible character on selected lines and resolve selection line lengths against buffer lines.
Move `$` to the final visible character instead of one cell past the end of the line, while keeping append-at-end behavior by moving right before entering insert mode for `A`. Bind `$` and `End` in visual modes so visual selections can extend to the line end, and update movement and append tests for the new cursor behavior.
When leaving insert mode, move a one-past-end cursor back onto the final visible character so normal mode does not remain past the line end. Keep insert mode free to use one-past-end positions while editing and add a regression for escaping from an append-at-end cursor.
Add buffer-local transaction undo and redo backed by text edit ranges. Route editor and plugin mutations through the transaction path so insert sessions, deletes, visual edits, paste, indent, and redo share one model. Track clean revisions in the undo history so the dirty indicator clears when undo returns a buffer to its saved state and updates after save.
Derive the default panel side and use key-based reverse sorting for picker matches to satisfy the current Clippy toolchain. Update `bytes` in `Cargo.lock` to the patched release required by the security audit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR bundles the editor hardening and modularization work from the E2E
analysis branch. It improves rendering safety, editor motion correctness,
plugin panel support, LSP modularity, and replaces the ad hoc undo stack with
buffer-local transaction undo/redo.
What changed
commandline/statusline rendering, and picker/list layout edge cases.
sibling close behavior, and nested split resizing.
rust-analyzeris a configured default serverinstead of a hard-coded singleton.
focus handling and
Ctrl-etoggle behavior.page movement,
$, visual mode$, and insert-mode escape clamping.Ctrl-rredo.
undo returns a buffer to the saved revision.
Testing
cargo fmt --checkcargo test