if_lua.txt ForVim version 9.2. Last change: 2026 Feb 14VIM REFERENCE MANUAL by Luis CarvalhoTheLuaInterface to VimluaLua1. Commandslua-commands2. The vim modulelua-vim3.List userdatalua-list4.Dict userdatalua-dict5.Blob userdatalua-blob6.Funcref userdatalua-funcref7. Buffer userdatalua-buffer8. Window userdatalua-window9.luaeval() Vim functionlua-luaeval10. Dynamic loadinglua-dynamic{only available when Vim was compiled with the |+lua| feature}==============================================================================1. Commandslua-commands:lua:[range]lua{chunk}ExecuteLua chunk{chunk}.Examples::lua print("Hello, Vim!"):lua local curbuf = vim.buffer() curbuf[7] = "line #7":[range]lua<<[trim] [{endmarker}]{script}{endmarker}ExecuteLuascript{script}.Note: This command doesn't work when theLuafeature wasn't compiled in. To avoid errors, seescript-here.If[endmarker]is omitted from after the "<<",a dot '.'must be used after{script}, like for the:append and:insert commands. Refer to:let-heredoc for more information.This form of the:lua commandis mainly useful for includingLua codein Vim scripts.Example:function! CurrentLineInfo()lua << EOFlocal linenr = vim.window().linelocal curline = vim.buffer()[linenr]print(string.format("Current line [%d] has %d chars",linenr, #curline))EOFendfunctionTo see what version ofLua you have::lua print(_VERSION)If you use LuaJIT you can also use this::lua print(jit.version):luado:[range]luado{body}ExecuteLua function "function (line, linenr){body}end" for each line in the[range], with the functionargument being set to the text of each line in turn,withouta trailing<EOL>, and the current line number.If the value returned by the functionisastringitbecomes the text of the line in the current turn. Thedefault for[range]is the whole file: "1,$".Examples::luado return string.format("%s\t%d", line:reverse(), #line):lua require"lpeg":lua -- balanced parenthesis grammar::lua bp = lpeg.P{ "(" * ((1 - lpeg.S"()") + lpeg.V(1))^0 * ")" }:luado if bp:match(line) then return "-->\t" .. line end:luafile:[range]luafile{file}ExecuteLuascript in{file}.The whole argumentis usedasa single file name.Examples::luafile script.lua:luafile %All these commands executeaLua chunk from either the command line (:lua and:luado) ora file (:luafile) with the given line[range]. Similarly to theLua interpreter, each chunk has its own scope and so only globalvariables areshared between command calls. AllLua default libraries are available. Inaddition,Lua "print" function has its output redirected to the Vim messagearea, with arguments separated bya whitespace instead ofa tab.Lua uses the "vim" module (seelua-vim) to issue commands to Vimand managebuffers(lua-buffer) andwindows(lua-window). However,procedures that alter buffer content, open new buffers, and change cursorposition are restricted when the commandis executed in thesandbox.==============================================================================2. The vim modulelua-vimLua interfaces Vim through the "vim" module. The first and last line of theinput range are stored in "vim.firstline" and "vim.lastline" respectively.The module also includes routines for buffer, window, and current linequeries, Vim evaluation and command execution, and others.vim.list([arg])Returns an emptylist or, if "arg"isaLuatable with numeric keys 1, ...,n (a"sequence"), returnsalistl such that l[i]=arg[i] fori= 1, ...,n (seeList).Non-numeric keys are not used to initializethe list. See alsolua-eval for conversionrules. Example: :lua t = {math.pi, false, say = 'hi'} :echo luaeval('vim.list(t)') :" [3.141593, v:false], 'say' is ignoredvim.dict([arg])Returns an empty dictionary or, if "arg"isaLua table, returnsadictd such that d[k]=arg[k] for allstring keysk in "arg" (seeDictionary).Number keys are converted tostrings. Keys that are not strings are notused to initialize the dictionary. See alsolua-eval for conversion rules. Example: :lua t = {math.pi, false, say = 'hi'} :echo luaeval('vim.dict(t)') :" {'1': 3.141593, '2': v:false, :" 'say': 'hi'}vim.blob([arg])Returns an emptyblob or, if "arg"isaLuastring, returnsablobb such thatbisequivalent to "arg"asa byte string.Examples: :lua s = "12ab\x00\x80\xfe\xff" :echo luaeval('vim.blob(s)') :" 0z31326162.0080FEFFvim.funcref({name})ReturnsaFuncref to function{name} (seeFuncref). Itis equivalent to Vim'sfunction().vim.buffer([arg])If "arg"isa number, returns buffer withnumber "arg" in the bufferlist or, if "arg"isa string, returns buffer whose full orshort nameis "arg". In both cases, returns'nil' (nil value, not string) if the bufferisnot found. Otherwise, if "toboolean(arg)"is'true' returns the first buffer in the bufferlist or else the current buffer.vim.window([arg])If "arg"isa number, returnswindow withnumber "arg" or'nil' (nil value, not string)if not found. Otherwise, if "toboolean(arg)"is'true' returns the firstwindow or else thecurrent window.vim.type({arg})Returns the type of{arg}. Itis equivalentto Lua's "type" function, but returns "list","dict", "funcref", "buffer", or "window" if{arg}isa list, dictionary, funcref, buffer,or window, respectively. Examples::lua l = vim.list():lua print(type(l), vim.type(l)):" listvim.command({cmds})Executes one or more lines ofEx-mode commandsin{cmds}.Examples::lua vim.command"set tw=60":lua vim.command"normal ddp"lua << trim END vim.command([[ new Myfile.js call search('start') ]])ENDvim.eval({expr})Evaluatesexpression{expr} (seeexpression),converts the result to Lua, and returns it.Vim strings and numbers are directly convertedtoLua strings and numbers respectively. Vimlists and dictionaries are converted toLuauserdata (seelua-list andlua-dict).Examples::lua tw = vim.eval"&tw":lua print(vim.eval"{'a': 'one'}".a)vim.line()Returns the current line (without the trailing<EOL>),aLua string.vim.beep()Beeps.vim.open({fname})Opensa new buffer for file{fname} andreturns it.Note that the bufferis not setas current.vim.call({name} [,{args}])Proxy to call Vim function named{name} witharguments{args}. Example::lua print(vim.call('has', 'timers'))vim.fnProxy to call Vim functions. Proxy methodsare created on demand. Example::lua print(vim.fn.has('timers'))vim.lua_versionTheLua version Vim was compiled with, in theform{major}.{minor}.{patch}, e.g. "5.1.4".vim.version()ReturnsaLua table with the Vim version.The table will have the following keys:major- major Vim version.minor- minor Vim version.patch- latest patch included.lua-vim-variablesThe Vim editor global dictionariesg:w:b:t:v: can be accessedfromLua conveniently and idiomatically by referencing thevim.*Lua tablesdescribed below. In this way you can easily read and modify global Vimscriptvariables from Lua.Example: vim.g.foo = 5 -- Set the g:foo Vim script variable. print(vim.g.foo) -- Get and print the g:foo Vim script variable. vim.g.foo = nil -- Delete (:unlet) the Vim script variable.vim.gvim.g Global(g:) editor variables. Key with no value returnsnil.vim.bvim.b Buffer-scoped(b:)variables for the current buffer. Invalid or unset key returnsnil.vim.wvim.w Window-scoped(w:)variables for the current window. Invalid or unset key returnsnil.vim.tvim.t Tabpage-scoped(t:)variables for the current tabpage. Invalid or unset key returnsnil.vim.vvim.vv: variables. Invalid or unset key returnsnil.==============================================================================3.List userdatalua-listList userdata represent vim lists, and theinterface tries to follow closelyVim'ssyntax for lists. Since lists are objects, changes inlist referencesinLua are reflected in Vim and vice-versa.Alist "l" has the followingproperties and methods:NOTE: In patch 8.2.1066 array indexes were changed from zero-based toone-based. You can check with: if has("patch-8.2.1066")Properties----------o "#l"is the number of items inlist "l", equivalent to "len(l)" in Vim.o "l[k]" returns the k-th item in "l"; "l"is one-indexed,as in Lua. To modify the k-th item, simplydo "l[k]= newitem"; in particular, "l[k]= nil" removes the k-th item from "l". Item can be added to theend of thelist by "l[#l+ 1]= newitem"o "l()" returns an iterator for "l".o "table.insert(l, newitem)" inserts an itemat theend of the list. (onlyLua 5.3 and later)o "table.insert(l, position, newitem)" inserts an itemat the specified position. "position"is one-indexed. (onlyLua 5.3 and later)o "table.remove(l, position)" removes an itemat the specified position. "position"is one-indexed.Methods-------o "l:add(item)" appends "item" to theend of "l".o "l:insert(item[, pos])" inserts "item"at (optional) position "pos" in the list. The default value for "pos"is 0.Examples::let l = [1, 'item']:lua l = vim.eval('l') -- same 'l':lua l:add(vim.list()):lua l[1] = math.pi:echo l[0] " 3.141593:lua l[1] = nil -- remove first item:lua l:insert(true, 1):lua print(l, #l, l[1], l[2]):lua l[#l + 1] = 'value':lua table.insert(l, 100):lua table.insert(l, 2, 200):lua table.remove(l, 1):lua for item in l() do print(item) end==============================================================================4.Dict userdatalua-dictSimilarly tolist userdata,dict userdata represent vim dictionaries; sincedictionaries are also objects, references are kept betweenLua and Vim.Adict "d" has the following properties:Properties----------o "#d"is the number of items indict "d", equivalent to "len(d)" in Vim.o "d.key" or "d['key']" returns the valueat entry "key" in "d". To modify the entryat this key, simplydo "d.key= newvalue"; in particular, "d.key= nil" removes the entry from "d".o "d()" returns an iterator for "d" andis equivalent to "items(d)" in Vim.Examples::let d = {'n':10}:lua d = vim.eval('d') -- same 'd':lua print(d, d.n, #d):let d.self = d:lua for k, v in d() do print(d, k, v) end:lua d.x = math.pi:lua d.self = nil -- remove entry:echo d==============================================================================5.Blob userdatalua-blobBlob userdata represent vim blobs.Ablob "b" has the following properties:Properties----------o "#b"is the length ofblob "b", equivalent to "len(b)" in Vim.o "b[k]" returns the k-th item in "b"; "b"is zero-indexed,as in Vim. To modify the k-th item, simplydo "b[k]= number"; in particular, "b[#b]= number" can appenda byte to tail.Methods-------o "b:add(bytes)" appends "bytes" to theend of "b".Examples::let b = 0z001122:lua b = vim.eval('b') -- same 'b':lua print(b, b[0], #b):lua b[1] = 32:lua b[#b] = 0x33 -- append a byte to tail:lua b:add("\x80\x81\xfe\xff"):echo b==============================================================================6.Funcref userdatalua-funcrefFuncref userdata represent funcrefvariables in Vim. Funcrefs that weredefined witha "dict" attribute need to be obtainedasa dictionary keyin order to have "self" properly assigned to the dictionary (see examplesbelow.)A funcref "f" has the following properties:Properties----------o "#f"is the name of the function referenced by "f"o "f(...)" calls the function referenced by "f" (with arguments)Examples::function I(x): return a:x: endfunction:let R = function('I'):lua i1 = vim.funcref('I'):lua i2 = vim.eval('R'):lua print(#i1, #i2) -- both 'I':lua print(i1, i2, #i2(i1) == #i1(i2)):function Mylen() dict: return len(self.data): endfunction:let mydict = {'data': [0, 1, 2, 3]}:lua d = vim.eval('mydict'); d.len = vim.funcref('Mylen'):echo mydict.len():lua l = d.len -- assign d as 'self':lua print(l())Luafunctions and closures are automatically converted toa VimFuncref andcan be accessed in Vim scripts. Example:lua <<EOFvim.fn.timer_start(1000, function(timer) print('timer callback')end)EOF==============================================================================7. Buffer userdatalua-bufferBuffer userdata represent vim buffers.A buffer userdata "b" has thefollowing properties and methods:Properties----------o "b()" sets "b"as the current buffer.o "#b"is the number of lines in buffer "b".o "b[k]" represents line number k: "b[k]= newline" replaces linek withstring "newline" and "b[k]= nil" deletes line k.o "b.name" contains the short name of buffer "b" (read-only).o "b.fname" contains the full name of buffer "b" (read-only).o "b.number" contains the position of buffer "b" in the bufferlist (read-only).Methods-------o "b:insert(newline[, pos])" insertsstring "newline"at (optional) position "pos" in the buffer. The default value for "pos"is "#b+ 1". If "pos==0" then "newline" becomes the first line in the buffer.o "b:next()" returns the buffer next to "b" in the buffer list.o "b:previous()" returns the buffer previous to "b" in the buffer list.o "b:isvalid()" returns'true' (boolean) if buffer "b" corresponds toa "real" (not freed from memory) Vim buffer.Examples::lua b = vim.buffer() -- current buffer:lua print(b.name, b.number):lua b[1] = "first line":lua b:insert("FIRST!", 0):lua b[1] = nil -- delete top line:lua for i=1,3 do b:insert(math.random()) end:3,4lua for i=vim.lastline,vim.firstline,-1 do b[i] = nil end:lua vim.open"myfile"() -- open buffer and set it as currentfunction! ListBuffers()lua << EOFlocal b = vim.buffer(true) -- first buffer in listwhile b ~= nil doprint(b.number, b.name, #b)b = b:next()endvim.beep()EOFendfunction==============================================================================8. Window userdatalua-windowWindowobjects represent vim windows.Awindow userdata "w" has the followingproperties and methods:Properties----------o "w()" sets "w"as the current window.o "w.buffer" contains the buffer ofwindow "w" (read-only).o "w.line" represents the cursor line position inwindow "w".o "w.col" represents the cursor column position inwindow "w".o "w.width" represents the width ofwindow "w".o "w.height" represents the height ofwindow "w".Methods-------o "w:next()" returns thewindow next to "w".o "w:previous()" returns thewindow previous to "w".o "w:isvalid()" returns'true' (boolean) ifwindow "w" corresponds toa "real" (not freed from memory) Vim window.Examples::lua w = vim.window() -- current window:lua print(w.buffer.name, w.line, w.col):lua w.width = w.width + math.random(10):lua w.height = 2 * math.random() * w.height:lua n,w = 0,vim.window(true) while w~=nil do n,w = n + 1,w:next() end:lua print("There are " .. n .. " windows")==============================================================================9.luaeval() Vim functionlua-luaevallua-evalThe (dual) equivalent of "vim.eval" for passingLua values to Vimis"luaeval". "luaeval" takes anexpressionstring and an optional argument andreturns the result of the expression. Itis semantically equivalent inLuato:local chunkheader = "local _A = select(1, ...) return "function luaeval (expstr, arg) local chunk = assert(loadstring(chunkheader .. expstr, "luaeval")) return chunk(arg) -- return typvalendNote that "_A" receives the argument to "luaeval".Lua numbers, strings, andlist, dict, blob, and funcref userdata are converted to their Vim respectivetypes, whileLua booleans are converted to numbers. An erroris thrown ifconversion of any of the remainingLua types, including userdata other thanlists, dicts, blobs, and funcrefs,is attempted.Examples::echo luaeval('math.pi'):lua a = vim.list():add('newlist'):let a = luaeval('a'):echo a[0] " 'newlist':function Rand(x,y) " random uniform between x and y: return luaeval('(_A.y-_A.x)*math.random()+_A.x', {'x':a:x,'y':a:y}): endfunction:echo Rand(1,10)==============================================================================10. Dynamic loadinglua-dynamicOnMS-Windows andUnix theLua library can be loaded dynamically. The:version output then includes+lua/dyn.This means that Vim will search for theLua DLL or shared library file onlywhen needed. When you don't use theLuainterface you don't need it, thusyou can use Vim without this file.MS-WindowsTo use theLuainterface theLua DLLmust be in your search path. Inaconsolewindow type "path" to see what directories are used. The'luadll'option can be also used to specify theLua DLL. The version of the DLLmustmatch theLua version Vim was compiled with.UnixThe'luadll' option can be used to specify theLua shared library file insteadof DYNAMIC_LUA_DLL file what was specifiedat compile time. The version ofthe shared librarymust match theLua version Vim was compiled with.============================================================================== vim:tw=78:ts=8:noet:ft=help:norl: