This was originally discovered/reported on Neovim (neovim/neovim#37664), but the same behavior is present in Vim.
vim --clean -u minimal.vim where minimal.vim contains the followingfunction! MyYank(type='') abort if a:type == '' let &operatorfunc = function('MyYank') return 'g@' endif let region = getregion(getpos("'["), getpos("']"), #{type: a:type == 'line' ? 'V' : a:type == 'char' ? 'v' : "\<c-v>"}) "__PRINT_EXP_START echom '┆MyYank┆ ╎getpos("'']")╎ ┊1┊:' getpos("']")|"__PRINT_EXP_END "__PRINT_EXP_START echom '┆MyYank┆ ╎getpos("''>")╎ ┊1┊:' getpos("'>")|"__PRINT_EXP_END "__PRINT_VAR_START echom '┆MyYank┆ ╎region╎ ┊1┊:' region|"__PRINT_VAR_END endfunction nnoremap <expr> gy MyYank() xnoremap <expr> gy MyYank()
ia()<esc> i<cr><esc> O b<esc> to end up with the following buffera(
b
)
b and vkol to end up with the following visual selection(note that my cursor is a line, not a block, so the end of the visual selection includes the newline character after b)
y and :echo substitute(getreg('"'), "\n", '_', 'g'), it'll output _ b_. Note the trailing newline.gv and gy, it'll output the following (it may be necessary to use :messages to see the full output)┆MyYank┆ ╎getpos("']")╎ ┊1┊: [0, 2, 3, 0]
┆MyYank┆ ╎getpos("'>")╎ ┊1┊: [0, 2, 4, 0]
┆MyYank┆ ╎region╎ ┊1┊: ['', ' b']
b and vk to get the following visual selection(similar to the previous visual selection, but the trailing newline is not included this time)
gy, it'll output (it may be necessary to use :messages to see the full output)┆MyYank┆ ╎getpos("']")╎ ┊1┊: [0, 2, 3, 0]
┆MyYank┆ ╎getpos("'>")╎ ┊1┊: [0, 2, 3, 0]
┆MyYank┆ ╎region╎ ┊1┊: ['', ' b']
Note that:
region does not contain a trailing newline (while it does contain a leading one) in either case (trailing newline is selected or not)] is located on [2, 3], on the b while the > mark is located one character to the right ([2, 4]), on the newline> mark being correctly located when the trailing newline is selected)This happens because builtin operators (like y) get to operate on the range defined by oap
https://github.com/vim/vim/blob/4b83d5ca76573373c0b57238b221a6a504bdb50b/src/register.c#L1314-L1321
before its end is adjusted with decl
https://github.com/vim/vim/blob/4b83d5ca76573373c0b57238b221a6a504bdb50b/src/register.c#L1422-L1424
On the other hand, operatorfunc operators get the value adjusted by decl before they can even see it
https://github.com/vim/vim/blob/4b83d5ca76573373c0b57238b221a6a504bdb50b/src/ops.c#L3742-L3744
This bug report relies in visual mode, but the same is true for custom textobjects that select trailing newline in visual char mode.
operatorfunc operators, just like builtin operators (d, y, etc), should be able to distinguish between regions with and without a trailing newline.
VIM - Vi IMproved 9.1 (2024 Jan 02, compiled Jan 11 2026 00:11:36) Included patches: 1-2077 Compiled by Arch Linux
Operating system/version: Arch linux latest
Terminal name/version: wezterm 20240203-110809-5046fc22
$TERM environment variable: wezterm
shell: zsh 5.9 (x86_64-pc-linux-gnu)
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()