The simple way to remap key in lua is:

vim.api.nvim_set_keymap('n', 'foo', 'bar', { noremap = true, silent = true })

But I want a simple syntax like vimScript: nnoremap foo bar


How I can I write this function n_keymap ?

  • 7
    if you need the simple syntax, use the VimScript language. Commented Jul 20, 2021 at 16:13
  • lua table if powerful ,i cant do anything and the execution is very fast than vimscript
    – nextloop
    Commented Jul 21, 2021 at 17:57
  • Well fine, but it is a configuration file, speed does not really matter here. Also, when reading vim.api.nvim_set_keymap this just looks ugly and too verbose, and it not clear to anybody not used to the neovim stuff Commented Jul 21, 2021 at 18:27
  • 3
    Note you're not really going to get any performance benefits from using Lua for your mappings vs. VimScript; the parsing of init.lua vs. init.vim might be fractionally faster (probably not perceptually so unless your vimrc is huge), but running the mappings is not going to be faster: it just modifies the same internal table in Neovim. Commented Jul 22, 2021 at 16:18
  • some time, lua not speed than vimscripte , but i migrate all plugin to lua and yours config files , i want to stop use (vim.cmd) for mapping , and keep config file readable if i can, @stalox give me a nice function that simple and i see useful in my case
    – nextloop
    Commented Jul 24, 2021 at 0:54

3 Answers 3


A simple way to do it is like this:

local n_keymap = function(lhs, rhs)
    vim.api.nvim_set_keymap('n', lhs, rhs, { noremap = true, silent = true })


But in my opinion that doesn't make any sense because the map function are quite powerful (they support different modes, recursive or not, silent or not, expression mappings, buffer local mappings, etc...) so

  1. At one point you will have to incorporate these features into you own function which is basically reinventing the wheel
  2. You won't make the syntax easier or shorter than what already exists in vimscript while keeping it readable
  3. You are creating something super custom that you are the only one to use, that you will need to maintain and which will most likely cost you more time in maintenance than if you'd use the built-in mechanisms.

So my recommendation would be: do use that.

  • i have a lot of plugin, for each plugin i have some keymapping, in sepate files, i hate call vimscripte for do this mapping , also i don't like default mapping , so this fun tion that you write , it's help me for use lua anywhere and readable , also i can creat multi function for silent or recursuve, thank you very much
    – nextloop
    Commented Jul 24, 2021 at 0:47

I have found a slightly different solution here:

local function map(mode, lhs, rhs, opts)
local options = {noremap = true}
    if opts then options = vim.tbl_extend('force', options, opts) end
    vim.keymap.set(mode, lhs, rhs, options)

Bellow, you have some example mappings using the proposed function

-- <Tab> to navigate the completion menu
map('i', '<S-Tab>', 'pumvisible() ? "\\<C-p>" : "\\<Tab>"', {expr = true})
map('i', '<Tab>', 'pumvisible() ? "\\<C-n>" : "\\<Tab>"', {expr = true})

map('n', '<C-l>', '<cmd>noh<CR>')    -- clears highlights
map("i", "<s-cr>", "<c-o>o")         -- adds new line below (insert)
map("i", "<c-cr>", "<c-o>O")         -- adds new line above (insert)

-- It adds motions like 25j and 30k to the jump list, so you can cycle
-- through them with control-o and control-i.
-- source: https://www.vi-improved.org/vim-tips/
map("n", "j", [[v:count ? (v:count > 5 ? "m'" . v:count : '') . 'j' : 'gj']], { expr = true })
map("n", "k", [[v:count ? (v:count > 5 ? "m'" . v:count : '') . 'k' : 'gk']], { expr = true })


This is a bug. On vim this menu used to be horizontal. They made it vertical on neovim but they didn't change the controls. You can fix it like:


vim.api.nvim_set_keymap('c', '<Up>', 'wildmenumode() ? "<Left>" : "<Up>"', {expr = true, noremap=true})
vim.api.nvim_set_keymap('c', '<Down>', 'wildmenumode() ? "<Right>" : "<Down>"', {expr = true, noremap=true})
vim.api.nvim_set_keymap('c', '<Left>', 'wildmenumode() ? "<Up>" : "<Left>"', {expr = true, noremap=true})
vim.api.nvim_set_keymap('c', '<Right>', 'wildmenumode() ? "<Down>" : "<Right>"', {expr = true, noremap=true})

Vimscript alternative

cnoremap <expr> <Up> wildmenumode() ? '<Left>' : '<Up>'
cnoremap <expr> <Down> wildmenumode() ? '<Right>' : '<Down>'
cnoremap <expr> <Left> wildmenumode() ? '<Up>' : '<Left>'
cnoremap <expr> <Right> wildmenumode() ? '<Down>' : '<Right>'

See: https://github.com/neovim/neovim/issues/9953


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.