Skip to content

Inclusive Motions Set to Col -1 on Zero Length Lines #798

@mikejmcguirk

Description

@mikejmcguirk

Describe the bug
If selecting a text object with an ending col index of zero using inclusive motions, nvim_win_set_cursor produces a Cursor position outside buffer error

To Reproduce
In an empty Rust file, type the following:

/// My end col index will be zero
// I'm here so the row is valid

The select comment.outer

Expected behavior
In update_selection, instead of

api.nvim_win_set_cursor(0, { end_row + 1, end_col - end_col_offset })

Should be something like

api.nvim_win_set_cursor(0, { end_row + 1, math.max(end_col - end_col_offset, 0) })

Output of :checkhealth nvim-treesitter

==============================================================================
nvim-treesitter: ✅

Requirements ~

  • ✅ OK Neovim was compiled with tree-sitter runtime ABI version 15 (required >=13).
  • ✅ OK tree-sitter 0.25.8 (/home/mjm/.cargo/bin/tree-sitter)
  • ✅ OK node 22.18.0 (/home/mjm/.nvm/versions/node/v22.18.0/bin/node)
  • ✅ OK tar 1.35.0 (/usr/bin/tar)
  • ✅ OK curl 8.5.0 (/usr/bin/curl)
    curl 8.5.0 (x86_64-pc-linux-gnu) libcurl/8.5.0 OpenSSL/3.0.13 zlib/1.3 brotli/1.1.0 zstd/1.5.5 libidn2/2.3.7 libpsl/0.21.2 (+libidn2/2.3.7) libssh/0.10.6/openssl/zlib nghttp2/1.59.0 librtmp/2.3 OpenLDAP/2.6.7
    Release-Date: 2023-12-06, security patched: 8.5.0-2ubuntu10.6
    Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
    Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd

OS Info ~

  • machine: x86_64
  • release: 6.8.0-78-generic
  • sysname: Linux
  • version: #78-Ubuntu SMP PREEMPT_DYNAMIC Tue Aug 12 11:34:18 UTC 2025

Install directory for parsers and queries ~

  • /home/mjm/.local/share/nvim/site/
  • ✅ OK is writable.
  • ✅ OK is in runtimepath.

Installed languages H L F I J ~

  • bash ✓ ✓ ✓ . ✓

  • c ✓ ✓ ✓ ✓ ✓

  • c_sharp ✓ ✓ ✓ . ✓

  • css ✓ . ✓ ✓ ✓

  • diff ✓ . ✓ . ✓

  • ecma

  • git_rebase ✓ . . . ✓

  • gitattributes ✓ ✓ . . ✓

  • gitcommit ✓ . . . ✓

  • gitignore ✓ . . . ✓

  • go ✓ ✓ ✓ ✓ ✓

  • html ✓ ✓ ✓ ✓ ✓

  • html_tags

  • javascript ✓ ✓ ✓ ✓ ✓

  • json ✓ ✓ ✓ ✓ .

  • jsx

  • lua ✓ ✓ ✓ ✓ ✓

  • markdown ✓ . ✓ ✓ ✓

  • markdown_inline ✓ . . . ✓

  • perl ✓ . ✓ . ✓

  • python ✓ ✓ ✓ ✓ ✓

  • query ✓ ✓ ✓ ✓ ✓

  • rust ✓ ✓ ✓ ✓ ✓

  • sql ✓ . ✓ ✓ ✓

  • tmux ✓ . . . ✓

  • typescript ✓ ✓ ✓ ✓ ✓

  • vim ✓ ✓ ✓ . ✓

  • vimdoc ✓ . . . ✓

    Legend: H[ighlights], L[ocals], F[olds], I[ndents], In[J]ections ~

Output of nvim --version

NVIM v0.12.0-dev-1074+g58060c2340
Build type: RelWithDebInfo
LuaJIT 2.1.1753364724

Additional context

If the first line is a doc comment and there is no second line, the end index will be on row one even though it doesn't exist. Perhaps update_selection could also clamp the row to the result of nvim_buf_line_count(). But I'm not sure if the Rust parser producing a non-existent row is an upstream issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions