*lua.txt* Nvim
NVIM REFERENCE MANUAL
Lua engine *lua* *Lua*
Type |gO| to see the table of contents.
==============================================================================
INTRODUCTION *lua-intro*
The Lua 5.1 language is builtin and always available. Try this command to get
an idea of what lurks beneath: >
:lua print(vim.inspect(package.loaded))
Nvim includes a "standard library" |lua-stdlib| for Lua. It complements the
"editor stdlib" (|functions| and Ex commands) and the |API|, all of which can
be used from Lua code. A good overview of using Lua in neovim is given by
https://github.com/nanotee/nvim-lua-guide.
Module conflicts are resolved by "last wins". For example if both of these
are on 'runtimepath':
runtime/lua/foo.lua
~/.config/nvim/lua/foo.lua
then `require('foo')` loads "~/.config/nvim/lua/foo.lua", and
"runtime/lua/foo.lua" is not used. See |lua-require| to understand how Nvim
finds and loads Lua modules. The conventions are similar to VimL plugins,
with some extra features. See |lua-require-example| for a walkthrough.
==============================================================================
IMPORTING LUA MODULES *lua-require*
*lua-package-path*
Nvim automatically adjusts `package.path` and `package.cpath` according to
effective 'runtimepath' value. Adjustment happens whenever 'runtimepath' is
changed. `package.path` is adjusted by simply appending `/lua/?.lua` and
`/lua/?/init.lua` to each directory from 'runtimepath' (`/` is actually the
first character of `package.config`).
Similarly to `package.path`, modified directories from 'runtimepath' are also
added to `package.cpath`. In this case, instead of appending `/lua/?.lua` and
`/lua/?/init.lua` to each runtimepath, all unique `?`-containing suffixes of
the existing `package.cpath` are used. Example:
1. Given that
- 'runtimepath' contains `/foo/bar,/xxx;yyy/baz,/abc`;
- initial (defined at compile-time or derived from
`$LUA_CPATH`/`$LUA_INIT`) `package.cpath` contains
`./?.so;/def/ghi/a?d/j/g.elf;/def/?.so`.
2. It finds `?`-containing suffixes `/?.so`, `/a?d/j/g.elf` and `/?.so`, in
order: parts of the path starting from the first path component containing
question mark and preceding path separator.
3. The suffix of `/def/?.so`, namely `/?.so` is not unique, as it’s the same
as the suffix of the first path from `package.path` (i.e. `./?.so`). Which
leaves `/?.so` and `/a?d/j/g.elf`, in this order.
4. 'runtimepath' has three paths: `/foo/bar`, `/xxx;yyy/baz` and `/abc`. The
second one contains semicolon which is a paths separator so it is out,
leaving only `/foo/bar` and `/abc`, in order.
5. The cartesian product of paths from 4. and suffixes from 3. is taken,
giving four variants. In each variant `/lua` path segment is inserted
between path and suffix, leaving
- `/foo/bar/lua/?.so`
- `/foo/bar/lua/a?d/j/g.elf`
- `/abc/lua/?.so`
- `/abc/lua/a?d/j/g.elf`
6. New paths are prepended to the original `package.cpath`.
The result will look like this:
`/foo/bar,/xxx;yyy/baz,/abc` ('runtimepath')
× `./?.so;/def/ghi/a?d/j/g.elf;/def/?.so` (`package.cpath`)
= `/foo/bar/lua/?.so;/foo/bar/lua/a?d/j/g.elf;/abc/lua/?.so;/abc/lua/a?d/j/g.elf;./?.so;/def/ghi/a?d/j/g.elf;/def/?.so`
Note:
- To track 'runtimepath' updates, paths added at previous update are
remembered and removed at the next update, while all paths derived from the
new 'runtimepath' are prepended as described above. This allows removing
paths when path is removed from 'runtimepath', adding paths when they are
added and reordering `package.path`/`package.cpath` content if 'runtimepath'
was reordered.
- Although adjustments happen automatically, Nvim does not track current
values of `package.path` or `package.cpath`. If you happen to delete some
paths from there you can set 'runtimepath' to trigger an update: >
let &runtimepath = &runtimepath
- Skipping paths from 'runtimepath' which contain semicolons applies both to
`package.path` and `package.cpath`. Given that there are some badly written
plugins using shell which will not work with paths containing semicolons it
is better to not have them in 'runtimepath' at all.
==============================================================================
Lua Syntax Information *lua-syntax-help*
While Lua has a simple syntax, there are a few things to understand,
particularly when looking at the documentation above.
*lua-syntax-call-function*
Lua functions can be called in multiple ways. Consider the function: >
local example_func = function(a, b)
print("A is: ", a)
print("B is: ", b)
end
The first way to call a function is: >
example_func(1, 2)
-- ==== Result ====
-- A is: 1
-- B is: 2
<
This way of calling a function is familiar to most scripting languages.
In Lua, it's important to understand that any function arguments that are
not supplied are automatically set to `nil`. For example: >
example_func(1)
-- ==== Result ====
-- A is: 1
-- B is: nil
<
Additionally, if any extra parameters are passed, they are discarded
completely.
In Lua, it is also possible (when only one argument is passed) to call the
function without any parentheses. This is most often used to approximate
"keyword"-style arguments with a single dictionary. For example: >
local func_with_opts = function(opts)
local will_do_foo = opts.foo
local filename = opts.filename
...
end
func_with_opts { foo = true, filename = "hello.world" }
<
In this style, each "parameter" is passed via keyword. It is still valid
to call the function in this style: >
func_with_opts({ foo = true, filename = "hello.world" })
<
But often in the documentation, you will see the former rather than the
latter style, due to its brevity (this is vim after all!).
------------------------------------------------------------------------------
LUA PLUGIN EXAMPLE *lua-require-example*
The following example plugin adds a command `:MakeCharBlob` which transforms
current buffer into a long `unsigned char` array. Lua contains transformation
function in a module `lua/charblob.lua` which is imported in
`autoload/charblob.vim` (`require("charblob")`). Example plugin is supposed
to be put into any directory from 'runtimepath', e.g. `~/.config/nvim` (in
this case `lua/charblob.lua` means `~/.config/nvim/lua/charblob.lua`).
autoload/charblob.vim: >
function charblob#encode_buffer()
call setline(1, luaeval(
\ 'require("charblob").encode(unpack(_A))',
\ [getline(1, '$'), &textwidth, ' ']))
endfunction
plugin/charblob.vim: >
if exists('g:charblob_loaded')
finish
endif
let g:charblob_loaded = 1
command MakeCharBlob :call charblob#encode_buffer()
lua/charblob.lua: >
local function charblob_bytes_iter(lines)
local init_s = {
next_line_idx = 1,
next_byte_idx
|