vimtricks.wiki Concise Vim tricks, one at a time.

How do I call a Lua function or evaluate a Lua expression from within Vimscript in Neovim?

Answer

luaeval('lua_expression')

Explanation

When you have existing Vimscript code that needs to reach into Neovim's Lua ecosystem, luaeval() is the bridge. It evaluates a Lua expression string and returns the result converted to an equivalent Vimscript value: strings stay strings, numbers stay numbers, Lua tables with integer keys become Lists, and other tables become Dicts.

How it works

  • luaeval('{expr}') — evaluates the Lua expression and returns the result to Vimscript
  • luaeval('{expr}', {val}) — binds val to the special variable _A inside the Lua expression, letting you pass data in without string interpolation
  • Lua nil maps to Vimscript v:null
  • Lua true/false map to Vimscript v:true/v:false

Example

" Read the Neovim version from Lua
let v = luaeval('vim.version().major')
echo v  " prints e.g. 0

" Get all lines of the current buffer as a List
let lines = luaeval('vim.api.nvim_buf_get_lines(0, 0, -1, false)')
echo len(lines)

" Pass a dict to Lua via _A to avoid quoting issues
let result = luaeval('_A.x * _A.y', {'x': 6, 'y': 7})
echo result  " 42

Tips

  • For calling a single Lua function from a Vimscript expression (not a statement), use v:lua.funcname() instead: let n = v:lua.vim.fn.line('.')
  • The reverse path — Lua calling Vimscript — uses vim.fn.* (e.g., vim.fn.line('.')) or vim.api.nvim_eval()
  • Prefer luaeval() over building Lua code via string concatenation to avoid injection and quoting bugs
  • If your Lua expression returns a function, you get v:null back — functions cannot be represented in Vimscript

Next

How do I enable matchit so % jumps between if/else/end style pairs?