Repository navigation
Fix word wrap measurement resuming inside a wrapped word - #987
Open
user77 (hexbinoct) wants to merge 1 commit into
Open
user77 (hexbinoct) wants to merge 1 commit into
user77 (hexbinoct) wants to merge 1 commit into
Conversation
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.
Problem
When
measure_forwardstops on its target in the middle of a word, the lookahead checks whether that word still fits on the row. If it doesn't, the cursor moves to the next row along with the word, butwrap_oppstaystrue, even though the new row has no wrap opportunity before the cursor. The main loop clears it when it wraps; the lookahead doesn't.A measurement that continues from such a cursor then thinks the row can still be broken, and when the rest of the word reaches the wrap column it moves it down another row instead of hard wrapping it.
For example
01234 x56789abcdefghijklmnopat width 20:With the cursor after the
x(row 1, column 1),cursor_move_to_offsetto the end of the line returns row 3, column 1, a row that doesn't exist. From the line start it returns row 2, column 2.Since #979,
edit_word_wrap_layout_finishmeasures the end of the edited line from the cursor, so this also reachesvisual_line_count(). The example above is what you get by typingxafter01234in0123456789abcdefghijklmnopat width 20. After that edit the line has 3 rows, but the count says 4. After undo it says 3 instead of 2, and after redo 5 instead of 3.assert_layoutfrom #980 fails on each of those steps.Fix
Clear
wrap_oppin the lookahead branch too, like the main loop does when it wraps.test_measure_forward_word_wrapexpectedwrap_opp: truefor the cursor after thebinfoo bar, which the lookahead moved to row 1. That row has no wrap opportunity before the cursor, and the same test already expectsfalsefor the cursor at the start of that row (goto_visualto{0, 1}), so it now expectsfalsethere too.Testing
test_measure_forward_word_wrap_resume: measuring to the end of the line from a cursor inside a word that the lookahead wrapped gives the same cursor as measuring from the start. Without the fix it ends at{5, 2}instead of{1, 2}.cargo test --workspaceandcargo clippy -p edit --all-features --all-targets -- --no-deps --deny warningspass (Rust 1.95), and nightly rustfmt is clean on the changed file.TextBuffer(3000 seeds of 40 edits, a third of them with word wrap on, checking the layout from scratch after every step likeassert_layout), with and without this change. It fixes 19 failing seeds (visual line count, visual cursor position, and onecursor.visual_pos.y <= self.stats.visual_linesdebug assert) and adds no new failures. Some word wrap layout failures remain; they have other causes, at least one of them involving tabs.#845 and #957 also change this lookahead loop. Neither conflicts with this change, and the measurement tests pass with #957's change merged in.