Skip to content

bug: normal-mode ,mq (Quote) crashes when no prior visual selection — line("'<") returns 0 not nil #21

Description

@monkeyxite

Reproduce

In a mail buffer, without having made any visual selection first, press ,mq in normal mode.

Result

E5108: Lua: .../nvim-mail/init.lua:123: 'start' is higher than 'end'
stack traceback:
        [C]: in function 'nvim_buf_set_lines'
        .../nvim-mail/init.lua:123: in function <.../nvim-mail/init.lua:116>

Root cause

lua/nvim-mail/init.lua lines 117-118 (normal-mode Quote handler):

local start_line = vim.fn.line("'<") or vim.fn.line('.')
local end_line   = vim.fn.line("'>") or vim.fn.line('.')

When the '< / '> marks are unset, vim.fn.line() returns 0, not nil. Since 0 is truthy in Lua, the or fallback never fires. This leaves start_line = 0 and end_line = 0, so the call becomes:

vim.api.nvim_buf_set_lines(0, -1, 0, false, lines)

start = -1 counts from the end of the buffer (= last line), end = 0, so start > end → E5108.

Scope

Only the normal-mode variant is affected. The visual-mode variant at lines 128-129 is safe because '< / '> are guaranteed set when a visual-mode mapping fires.

Proposed fix

Explicit zero-check on the mark lookup:

map('q', function()
  local start_line = vim.fn.line("'<")
  if start_line == 0 then start_line = vim.fn.line('.') end
  local end_line = vim.fn.line("'>")
  if end_line == 0 then end_line = vim.fn.line('.') end
  -- ... rest unchanged
end, ' Quote')

Alternative design worth considering: the normal-mode ,mq currently reads stale visual marks (which may point at an unrelated line from a prior visual selection). Arguably normal-mode ,mq should just quote the current line (line('.') for both start and end) and not consult '< / '> at all. That would be the less-surprising behavior.

Suggested test

Add to tests/mail/init_spec.lua (or wherever quote tests belong): open a mail fixture, do not enter visual mode, call the normal-mode ,mq handler directly. Assert no error is raised and the current line gets a > prefix.

Related audit

Grepped the whole lua/nvim-mail/ tree for vim.fn.line("'<") / vim.fn.line("'>") / getpos and or vim.fn.line — only these two lines match. No wider family of the same bug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions