[vim/vim] `operatorfunc` operators can't distinguish between regions ending or not in a newline (builtin operators can) (Issue #19324)

1 view
Skip to first unread message

Luis Calle

unread,
Feb 3, 2026, 1:28:18 PM (14 hours ago) Feb 3
to vim/vim, Subscribed
TheLeoP created an issue (vim/vim#19324)

Steps to reproduce

This was originally discovered/reported on Neovim (neovim/neovim#37664), but the same behavior is present in Vim.

  1. vim --clean -u minimal.vim where minimal.vim contains the following
function! 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()
  1. ia()<esc> i<cr><esc> O b<esc> to end up with the following buffer
a(
  b
)
  1. Put the cursor on b and vkol to end up with the following visual selection
image.png (view on web)

(note that my cursor is a line, not a block, so the end of the visual selection includes the newline character after b)

  1. y and :echo substitute(getreg('"'), "\n", '_', 'g'), it'll output _ b_. Note the trailing newline.
  2. 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']
  1. Put the cursor on b and vk to get the following visual selection
image.png (view on web)

(similar to the previous visual selection, but the trailing newline is not included this time)

  1. 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)
  • when the trailing newline is selected, the mark ] is located on [2, 3], on the b while the > mark is located one character to the right ([2, 4]), on the newline
  • the behavior is the same whether or not the trailing newline is visually selected (besides the > 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.

Expected behaviour

operatorfunc operators, just like builtin operators (d, y, etc), should be able to distinguish between regions with and without a trailing newline.

Version of Vim

VIM - Vi IMproved 9.1 (2024 Jan 02, compiled Jan 11 2026 00:11:36) Included patches: 1-2077 Compiled by Arch Linux

Environment

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)

Logs and stack traces


Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/19324@github.com>

Reply all
Reply to author
Forward
0 new messages