Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix cursor may move too many lines over "right" & "below" virt text #14317

Closed

Conversation

dylanahsmith
Copy link
Contributor

Based on #14307, see dylanahsmith/vim@fix-12213...dylanahsmith:vim:fix-cursor-move-over-below-right to exclude that branch's commits from the comparison

Problem

The problem can be demonstrated by saving the following vim script as repro.vim, then loading it with vim --clean -S repro.vim

vim9script
set nowrap

setline(1, [
  'here is text long enough to fill the row',
  'second line',
])

prop_type_add("test", {"highlight": "Error"})
prop_add(1, 0, {type: 'test', text: 'right text', text_align: 'right'})
prop_add(1, 0, {type: 'test', text: 'below text', text_align: 'below'})
normal G$

which without this fix results in the cursor appearing on the screen line below the last character in second line.

My PR #14307 actually work around this issue that I originally uncovered from an earlier version of its regression test, which added the "right" virtual text property before the "below" property. As noted in that PR description, those text properties aren't sorted, but instead got stored in the reverse order of how they were stored.

When calculating the line height in prop_count_above_below, next_right_goes_below = TRUE was for some reason set when encountering the "below" text property, leading to it incorrectly counting an "extra" line for the following "right" property even though it was the first "right" property.

Solution

Only "right" virtual text properties should always shift other "right" properties on the same line to the next line, so I removed the unnecessary next_right_goes_below = TRUE; statements and simplified the code. I then updated the regression test to cover this case, such that the test fails without this fix.

Problem:  The if branch to set `text_prop_follows` was both checking if
          it was at the end of the buffer text line or if it was at the
          end of the screen line, but the former being true skipped
          a guard condition in the latter to only consider 'below'
          virtual text to follow. `text_prop_follows` being improperly
          set caused it to skip a conditional block to break at the end
          as well as one to move `ptr` to the end of the text line,
          while repeated for each following line of the window.
Solution: Move the check for whether 'below' virtual text should follow
          so it is also used when at the end of the buffer text line.

closes: vim#12213
Problem:  When a line is truncated just before 'after'/'right' virtual
          text and the line also has 'below' virtual text, then the
          'below' virtual text would not be displayed, depending on the
          order these text properties were added.
Solution: In the loop to make text properties active, skip instead of
          break for 'after'/'right' virtual text properties that are
          ignored due to truncation, so following 'below' text
          properties can still be made active.
          Similarly, a loop is needed to determine if a text property
          follows at the end of the screen.
Problem:  There are two dense conditions with duplication that needs to
          be kept in sync between the while loop break condition and the
          condition to skip certain text properties.
Solution: Refactor the loop by moving while loop conditions into the
          body of the while loop so they can be shared with skip
          conditions. `break` and an `active` variable are used to
          handle the outcome of these merged conditions.
Problem:  If a line has "right" & "below" virtual text properties,
          where the "below" property may be stored first due to lack of
          ordering between them, then the line height is calculated to
          be 1 more and causes the cursor to far over the line.
Solution: Remove some unnecessary setting of a
          `next_right_goes_below = TRUE` flag for "below" and "above"
          text properties.

I modified a regression test I recently added to cover this case,
leveraging the fact that "after", "right" & "below" text properties are
being stored in the reverse of the order they are added in.  The
previous version of this regression test was crafted to workaround this
issue so it can be addressed by this separate patch.
@dylanahsmith dylanahsmith changed the title patch: cursor may move too many lines over "right" & "below" virt text Fix cursor may move too many lines over "right" & "below" virt text Mar 27, 2024
@chrisbra
Copy link
Member

thanks. If I see this correctly, after having merged #14307 we just need the latest commit here: 9adb353

I'll include that now as v9.1.224. Please check if there is anything missing from that.

@chrisbra chrisbra closed this in 515f734 Mar 28, 2024
@dylanahsmith dylanahsmith deleted the fix-cursor-move-over-below-right branch March 28, 2024 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants