Search code examples
pluginsluaneovim

How to get the last inserted character using Lua in Neovim?


Using Lua I want to know what the inserted character (in Insert-Mode) was that triggered an InsertCharPre/TextChangedI/... event.

I want to write a simple Neovim plugin that automatically adds a new line to a markdown bullet-list if I press enter while being in such a list. So far the plugin is able to detect if a given line is a bullet-list line. Now, if the inserted character is a <CR>, I want to insert it, check the current indentation of the bullet list and add a new element at the same level in the next line. The autocommand is triggered via InsertCharPre event, that is created if a key was pressed but before it is inserted into the buffer.

This code is creating the autocommand for it:

api.nvim_create_autocmd("InsertCharPre", {
    pattern = { "*.md" },
    callback = create_new_bullet_list_entry,
    group = mdGroup
})

Here is where I want to continue and check if the last character entered is <CR>:

local create_new_bullet_list_entry = function(table)
    local cur_line = api.nvim_get_current_line()
    local is_bullet_list = is_line_bullet_list(cur_line)
    if not is_bullet_list then
        return
    end
end

How can I check what character was entered to trigger the InsertCharPre event?

I checked the table that is passed to the callback function and it does not contain any information regarding the typed character:

{ ["id"] = 36,["file"] = /foo/bar,["match"] = /foo/bar,["group"] = 28,["buf"] = 1,["event"] = InsertCharPre,}

Other approaches to achieve the same outcome would also be very helpful!


Solution

  • To check what character was entered to trigger the InsertCharPre event, you can reference the v:char variable using vim.v.char in the event callback.

    However, this won't work for your use case since your requirement is to check if the inserted character is a carriage return which won't trigger InsertCharPre events. As Bram suggests in this Github issue, you may want to go for an expression mapping instead. I'd imagine something like:

    au FileType markdown inoremap <expr> <CR> CreateNewBulletListEntry()
    

    And have that function defined with the functionality you want.