Skip to content

Keep register changes the user makes while a snippet is active - #1697

Merged
SirVer merged 4 commits into
masterfrom
sirver/1695-keep-user-register-changes
Sep 6, 2026
Merged

SirVer merged 4 commits into
masterfrom
sirver/1695-keep-user-register-changes

Conversation

@SirVer

@SirVer SirVer commented Sep 5, 2026 •

Copy link
Copy Markdown
Owner

Since #1636 the registers @", @0, @- and @1-@9 are cached at the first tabstop jump and restored on every InsertLeave and again at snippet teardown, so that a select-mode placeholder replacement (which deletes the placeholder text into @" and @-/@1) does not leak into the user's registers. The restore ran unconditionally. A user who yanked a line, expanded a snippet, left it with <Esc>, deleted a line with dd and then moved the cursor away saw the teardown revert @" to the yank from before the expansion, throwing the dd away. The same happened on the InsertLeave path for any register change made in normal mode while the snippet was still active.

VimState now keeps the texts of the placeholders the snippet has selected since the cache was taken. Registers are restored only when @" currently holds one of those texts, i.e. when a placeholder replacement is what last wrote it. Anything else in @" was put there by the user and wins; the restore is skipped and teardown drops the cache as before. The comparison happens inside Vim (index([...], @")) so binary register contents never cross the Python boundary, and it is exact and case-sensitive, unlike the != the old code used.

The same check replaces the old single "text to expect" comparison that decided whether to refresh the cache at a jump. That comparison only knew the most recently selected placeholder, so typing over tabstop 1, jumping to tabstop 2 and back again re-cached the placeholder text as the "original" register state. Tracking every selected placeholder text closes that gap too.

Fixes #1695.

The registers cached at the first tabstop jump were restored on every
InsertLeave and at snippet teardown regardless of who last wrote them.
Leaving a snippet with <Esc>, deleting a line with dd and then moving
the cursor away tore the snippet down and reverted @" (and @1) to the
yank from before the expansion.

VimState now tracks the texts of the placeholders the snippet selected
since the cache was taken. Only when @" holds one of them, i.e. when a
select-mode placeholder replacement is what last wrote it, are the
cached registers restored; anything else in @" was put there by the
user and wins. The same check replaces the single "expected text"
comparison that decided whether to refresh the cache at a jump.

Fixes #1695
…er-register-changes

# Conflicts:
#	ChangeLog
@SirVer
SirVer merged commit 0ca6a21 into master Sep 6, 2026
15 checks passed
@SirVer
SirVer deleted the sirver/1695-keep-user-register-changes branch September 6, 2026 11:29
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.

Unnamed register " altered after when moving after expanding a snippet

1 participant