Neovim Smart Lists

Lists. They can be smart. These lists are not going to win a Nobel or anything, but #Neovim can be configured to grow some efficiencies from other editors. Smart.

Let’s say you’ve created a markdown list, like this.

* The start of my list <-- cursor is here

Then, when you press Enter, the same list marker you were using is automatically inserted for you.

* The start of my list
* I didn't have to type "*"!

In addition, I wanted a few more features.

  1. If the line is otherwise empty, except for the list marker, pressing Enter deletes the item and gives you a new line.
  2. Numerical lists should increment.
  3. It should also work for the non-standard “task” list type, aka - [ ] .

I came up with a little mapping, which does the detection with REGEX.

-- Inside ~/.config/nvim/ftplugin/markdown.lua
vim.keymap.set('i', '<CR>', function()
    local line = vim.fn.trim(vim.api.nvim_get_current_line())
    local bullet = string.match(line, '^[%*|%+|%-]')
    local num_bullet = string.match(line, '^[%d]*%.')
    local task_bullet = string.match(line, '^%-%s%[%s%]')
    if not bullet and not num_bullet and not task_bullet then
        return '<CR>'
    end
    if line == bullet or line == num_bullet or line == task_bullet then
        return '<Esc>0Do'
    end
    if task_bullet then
        return '<CR>' .. task_bullet .. ' '
    end
    if num_bullet then
        return '<CR>' .. num_bullet .. ' <Esc>0<C-a>A'
    end
    return '<CR>' .. bullet .. ' '
end, { buffer = true, expr = true })

I’m sure there’s more efficient ways of doing this! If you know any, yell at me.

💽