setpos() updates the wrong logical Visual mark by Boulea7 · Pull Request #21023 · vim/vim · GitHub
Skip to content

setpos() updates the wrong logical Visual mark - #21023

Draft
Boulea7 wants to merge 1 commit into
vim:masterfrom
Boulea7:fix/19049-visual-marks
Draft

Boulea7 wants to merge 1 commit into
vim:masterfrom
Boulea7:fix/19049-visual-marks

Conversation

@Boulea7

@Boulea7 Boulea7 commented Aug 12, 2026

Copy link
Copy Markdown

Problem

For a reversed Visual selection, getpos("'<") reports the buffer-relative start while setpos("'<", ...) updates the endpoint associated with the selection direction. setcharpos() follows the same path, so the get/set APIs are inconsistent. Fixes #19049.

Solution

Resolve '< and '> to their logical buffer-relative endpoints before updating them. Crossing the other endpoint now changes the stored order without changing that other endpoint; getmark() continues to return the marks in logical order. Deleting either endpoint preserves the remaining endpoint so the deleted mark can be recreated.

Update builtin.txt and add regression coverage for forward and reversed selections, column and line crossings in both directions, deletion and recreation, active Visual mode, independent initialization, and setcharpos().

Tests

  • make -C src -j2
  • make -C src/testdir -W test_marks.vim TEST_FILTER=Test_setpos test_marks.res
  • make -C src/testdir -j3 -W test_marks.vim -W test_visual.vim -W test_codestyle.vim test_marks.res test_visual.res test_codestyle.res
  • git diff --check origin/master..HEAD

Full test counts: test_marks 14/14, test_visual 81/81, test_codestyle 5/5.

AI-assisted: Codex

@chrisbra

Copy link
Copy Markdown
Member

Problem:  setpos() and setcharpos() update the wrong logical Visual mark
          when a Visual selection was made in reverse (numEricL).
Solution: Resolve the Visual marks to buffer-relative endpoints before
          updating them, preserve the other endpoint when deleting a mark,
          and let getmark() order crossed endpoints (zhanglangning).

fixes:   vim#19049

AI-assisted: Codex
Signed-off-by: zhanglangning <zln1905391059@163.com>
@Boulea7
Boulea7 force-pushed the fix/19049-visual-marks branch from e218171 to cc83269 Compare August 13, 2026 03:20
@Boulea7

Boulea7 commented Aug 13, 2026

Copy link
Copy Markdown
Author

You're right. Your example exposed a bug in the clamping logic: moving '> before '< discarded the previous endpoint. I removed the clamping. setpos() now resolves the requested logical mark and updates only that endpoint, while getmark() handles the ordering.

I added your linewise case and the inverse crossing case; both now preserve the full range.

@Boulea7
Boulea7 marked this pull request as draft August 13, 2026 04:02
@Boulea7

Boulea7 commented Aug 13, 2026

Copy link
Copy Markdown
Author

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.

getpos and setpos are not consistent with visual marks

2 participants