mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 11:15:14 -07:00
1566 lines
60 KiB
Plaintext
1566 lines
60 KiB
Plaintext
*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.
|
||
|
||
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 = 1,
|
||
lines = lines,
|
||
}
|
||
local function next(s, _)
|
||
if lines[s.next_line_idx] == nil then
|
||
return nil
|
||
end
|
||
if s.next_byte_idx > #(lines[s.next_line_idx]) then
|
||
s.next_line_idx = s.next_line_idx + 1
|
||
s.next_byte_idx = 1
|
||
return ('\n'):byte()
|
||
end
|
||
local ret = lines[s.next_line_idx]:byte(s.next_byte_idx)
|
||
if ret == ('\n'):byte() then
|
||
ret = 0 -- See :h NL-used-for-NUL.
|
||
end
|
||
s.next_byte_idx = s.next_byte_idx + 1
|
||
return ret
|
||
end
|
||
return next, init_s, nil
|
||
end
|
||
|
||
local function charblob_encode(lines, textwidth, indent)
|
||
local ret = {
|
||
'const unsigned char blob[] = {',
|
||
indent,
|
||
}
|
||
for byte in charblob_bytes_iter(lines) do
|
||
-- .- space + number (width 3) + comma
|
||
if #(ret[#ret]) + 5 > textwidth then
|
||
ret[#ret + 1] = indent
|
||
else
|
||
ret[#ret] = ret[#ret] .. ' '
|
||
end
|
||
ret[#ret] = ret[#ret] .. (('%3u,'):format(byte))
|
||
end
|
||
ret[#ret + 1] = '};'
|
||
return ret
|
||
end
|
||
|
||
return {
|
||
bytes_iter = charblob_bytes_iter,
|
||
encode = charblob_encode,
|
||
}
|
||
|
||
==============================================================================
|
||
COMMANDS *lua-commands*
|
||
|
||
These commands execute a Lua chunk from either the command line (:lua, :luado)
|
||
or a file (:luafile) on the given line [range]. As always in Lua, each chunk
|
||
has its own scope (closure), so only global variables are shared between
|
||
command calls. The |lua-stdlib| modules, user modules, and anything else on
|
||
|lua-package-path| are available.
|
||
|
||
The Lua print() function redirects its output to the Nvim message area, with
|
||
arguments separated by " " (space) instead of "\t" (tab).
|
||
|
||
*:lua*
|
||
:[range]lua {chunk}
|
||
Executes Lua chunk {chunk}.
|
||
|
||
Examples: >
|
||
:lua vim.api.nvim_command('echo "Hello, Nvim!"')
|
||
< To see the Lua version: >
|
||
:lua print(_VERSION)
|
||
< To see the LuaJIT version: >
|
||
:lua print(jit.version)
|
||
<
|
||
*:lua-heredoc*
|
||
:[range]lua << [endmarker]
|
||
{script}
|
||
{endmarker}
|
||
Executes Lua script {script} from within Vimscript.
|
||
{endmarker} must NOT be preceded by whitespace. You
|
||
can omit [endmarker] after the "<<" and use a dot "."
|
||
after {script} (similar to |:append|, |:insert|).
|
||
|
||
Example:
|
||
>
|
||
function! CurrentLineInfo()
|
||
lua << EOF
|
||
local linenr = vim.api.nvim_win_get_cursor(0)[1]
|
||
local curline = vim.api.nvim_buf_get_lines(
|
||
0, linenr, linenr + 1, false)[1]
|
||
print(string.format("Current line [%d] has %d bytes",
|
||
linenr, #curline))
|
||
EOF
|
||
endfunction
|
||
|
||
< Note that the `local` variables will disappear when
|
||
the block finishes. But not globals.
|
||
|
||
*:luado*
|
||
:[range]luado {body} Executes Lua chunk "function(line, linenr) {body} end"
|
||
for each buffer line in [range], where `line` is the
|
||
current line text (without <EOL>), and `linenr` is the
|
||
current line number. If the function returns a string
|
||
that becomes the text of the corresponding buffer
|
||
line. Default [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}
|
||
Execute Lua script in {file}.
|
||
The whole argument is used as a single file name.
|
||
|
||
Examples:
|
||
>
|
||
:luafile script.lua
|
||
:luafile %
|
||
<
|
||
|
||
==============================================================================
|
||
luaeval() *lua-eval* *luaeval()*
|
||
|
||
The (dual) equivalent of "vim.eval" for passing Lua values to Nvim is
|
||
"luaeval". "luaeval" takes an expression string and an optional argument used
|
||
for _A inside expression and returns the result of the expression. It is
|
||
semantically equivalent in Lua to:
|
||
>
|
||
local chunkheader = "local _A = select(1, ...) return "
|
||
function luaeval (expstr, arg)
|
||
local chunk = assert(loadstring(chunkheader .. expstr, "luaeval"))
|
||
return chunk(arg) -- return typval
|
||
end
|
||
|
||
Lua nils, numbers, strings, tables and booleans are converted to their
|
||
respective VimL types. An error is thrown if conversion of any other Lua types
|
||
is attempted.
|
||
|
||
The magic global "_A" contains the second argument to luaeval().
|
||
|
||
Example: >
|
||
:echo luaeval('_A[1] + _A[2]', [40, 2])
|
||
42
|
||
:echo luaeval('string.match(_A, "[a-z]+")', 'XYXfoo123')
|
||
foo
|
||
|
||
Lua tables are used as both dictionaries and lists, so it is impossible to
|
||
determine whether empty table is meant to be empty list or empty dictionary.
|
||
Additionally Lua does not have integer numbers. To distinguish between these
|
||
cases there is the following agreement:
|
||
|
||
0. Empty table is empty list.
|
||
1. Table with N incrementally growing integral numbers, starting from 1 and
|
||
ending with N is considered to be a list.
|
||
2. Table with string keys, none of which contains NUL byte, is considered to
|
||
be a dictionary.
|
||
3. Table with string keys, at least one of which contains NUL byte, is also
|
||
considered to be a dictionary, but this time it is converted to
|
||
a |msgpack-special-map|.
|
||
*lua-special-tbl*
|
||
4. Table with `vim.type_idx` key may be a dictionary, a list or floating-point
|
||
value:
|
||
- `{[vim.type_idx]=vim.types.float, [vim.val_idx]=1}` is converted to
|
||
a floating-point 1.0. Note that by default integral Lua numbers are
|
||
converted to |Number|s, non-integral are converted to |Float|s. This
|
||
variant allows integral |Float|s.
|
||
- `{[vim.type_idx]=vim.types.dictionary}` is converted to an empty
|
||
dictionary, `{[vim.type_idx]=vim.types.dictionary, [42]=1, a=2}` is
|
||
converted to a dictionary `{'a': 42}`: non-string keys are ignored.
|
||
Without `vim.type_idx` key tables with keys not fitting in 1., 2. or 3.
|
||
are errors.
|
||
- `{[vim.type_idx]=vim.types.list}` is converted to an empty list. As well
|
||
as `{[vim.type_idx]=vim.types.list, [42]=1}`: integral keys that do not
|
||
form a 1-step sequence from 1 to N are ignored, as well as all
|
||
non-integral keys.
|
||
|
||
Examples: >
|
||
|
||
:echo luaeval('math.pi')
|
||
: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)
|
||
|
||
Note: second argument to `luaeval` undergoes VimL to Lua conversion
|
||
("marshalled"), so changes to Lua containers do not affect values in VimL.
|
||
Return value is also always converted. When converting,
|
||
|msgpack-special-dict|s are treated specially.
|
||
|
||
==============================================================================
|
||
Vimscript v:lua interface *v:lua-call*
|
||
|
||
From Vimscript the special `v:lua` prefix can be used to call Lua functions
|
||
which are global or accessible from global tables. The expression >
|
||
v:lua.func(arg1, arg2)
|
||
is equivalent to the Lua chunk >
|
||
return func(...)
|
||
where the args are converted to Lua values. The expression >
|
||
v:lua.somemod.func(args)
|
||
is equivalent to the Lua chunk >
|
||
return somemod.func(...)
|
||
|
||
You can use `v:lua` in "func" options like 'tagfunc', 'omnifunc', etc.
|
||
For example consider the following Lua omnifunc handler: >
|
||
|
||
function mymod.omnifunc(findstart, base)
|
||
if findstart == 1 then
|
||
return 0
|
||
else
|
||
return {'stuff', 'steam', 'strange things'}
|
||
end
|
||
end
|
||
vim.api.nvim_buf_set_option(0, 'omnifunc', 'v:lua.mymod.omnifunc')
|
||
|
||
Note: the module ("mymod" in the above example) must be a Lua global.
|
||
|
||
Note: `v:lua` without a call is not allowed in a Vimscript expression:
|
||
|Funcref|s cannot represent Lua functions. The following are errors: >
|
||
|
||
let g:Myvar = v:lua.myfunc " Error
|
||
call SomeFunc(v:lua.mycallback) " Error
|
||
let g:foo = v:lua " Error
|
||
let g:foo = v:['lua'] " Error
|
||
|
||
|
||
==============================================================================
|
||
Lua standard modules *lua-stdlib*
|
||
|
||
The Nvim Lua "standard library" (stdlib) is the `vim` module, which exposes
|
||
various functions and sub-modules. It is always loaded, thus require("vim")
|
||
is unnecessary.
|
||
|
||
You can peek at the module properties: >
|
||
|
||
:lua print(vim.inspect(vim))
|
||
|
||
Result is something like this: >
|
||
|
||
{
|
||
_os_proc_children = <function 1>,
|
||
_os_proc_info = <function 2>,
|
||
...
|
||
api = {
|
||
nvim__id = <function 5>,
|
||
nvim__id_array = <function 6>,
|
||
...
|
||
},
|
||
deepcopy = <function 106>,
|
||
gsplit = <function 107>,
|
||
...
|
||
}
|
||
|
||
To find documentation on e.g. the "deepcopy" function: >
|
||
|
||
:help vim.deepcopy()
|
||
|
||
Note that underscore-prefixed functions (e.g. "_os_proc_children") are
|
||
internal/private and must not be used by plugins.
|
||
|
||
------------------------------------------------------------------------------
|
||
VIM.LOOP *lua-loop* *vim.loop*
|
||
|
||
`vim.loop` exposes all features of the Nvim event-loop. This is a low-level
|
||
API that provides functionality for networking, filesystem, and process
|
||
management. Try this command to see available functions: >
|
||
|
||
:lua print(vim.inspect(vim.loop))
|
||
|
||
Reference: https://github.com/luvit/luv/blob/master/docs.md
|
||
Examples: https://github.com/luvit/luv/tree/master/examples
|
||
|
||
*E5560* *lua-loop-callbacks*
|
||
It is an error to directly invoke `vim.api` functions (except |api-fast|) in
|
||
`vim.loop` callbacks. For example, this is an error: >
|
||
|
||
local timer = vim.loop.new_timer()
|
||
timer:start(1000, 0, function()
|
||
vim.api.nvim_command('echomsg "test"')
|
||
end)
|
||
|
||
To avoid the error use |vim.schedule_wrap()| to defer the callback: >
|
||
|
||
local timer = vim.loop.new_timer()
|
||
timer:start(1000, 0, vim.schedule_wrap(function()
|
||
vim.api.nvim_command('echomsg "test"')
|
||
end))
|
||
|
||
(For one-shot timers, see |vim.defer_fn()|, which automatically adds the wrapping.)
|
||
|
||
Example: repeating timer
|
||
1. Save this code to a file.
|
||
2. Execute it with ":luafile %". >
|
||
|
||
-- Create a timer handle (implementation detail: uv_timer_t).
|
||
local timer = vim.loop.new_timer()
|
||
local i = 0
|
||
-- Waits 1000ms, then repeats every 750ms until timer:close().
|
||
timer:start(1000, 750, function()
|
||
print('timer invoked! i='..tostring(i))
|
||
if i > 4 then
|
||
timer:close() -- Always close handles to avoid leaks.
|
||
end
|
||
i = i + 1
|
||
end)
|
||
print('sleeping');
|
||
|
||
|
||
Example: File-change detection *watch-file*
|
||
1. Save this code to a file.
|
||
2. Execute it with ":luafile %".
|
||
3. Use ":Watch %" to watch any file.
|
||
4. Try editing the file from another text editor.
|
||
5. Observe that the file reloads in Nvim (because on_change() calls
|
||
|:checktime|). >
|
||
|
||
local w = vim.loop.new_fs_event()
|
||
local function on_change(err, fname, status)
|
||
-- Do work...
|
||
vim.api.nvim_command('checktime')
|
||
-- Debounce: stop/start.
|
||
w:stop()
|
||
watch_file(fname)
|
||
end
|
||
function watch_file(fname)
|
||
local fullpath = vim.api.nvim_call_function(
|
||
'fnamemodify', {fname, ':p'})
|
||
w:start(fullpath, {}, vim.schedule_wrap(function(...)
|
||
on_change(...) end))
|
||
end
|
||
vim.api.nvim_command(
|
||
"command! -nargs=1 Watch call luaeval('watch_file(_A)', expand('<args>'))")
|
||
|
||
|
||
Example: TCP echo-server *tcp-server*
|
||
1. Save this code to a file.
|
||
2. Execute it with ":luafile %".
|
||
3. Note the port number.
|
||
4. Connect from any TCP client (e.g. "nc 0.0.0.0 36795"): >
|
||
|
||
local function create_server(host, port, on_connect)
|
||
local server = vim.loop.new_tcp()
|
||
server:bind(host, port)
|
||
server:listen(128, function(err)
|
||
assert(not err, err) -- Check for errors.
|
||
local sock = vim.loop.new_tcp()
|
||
server:accept(sock) -- Accept client connection.
|
||
on_connect(sock) -- Start reading messages.
|
||
end)
|
||
return server
|
||
end
|
||
local server = create_server('0.0.0.0', 0, function(sock)
|
||
sock:read_start(function(err, chunk)
|
||
assert(not err, err) -- Check for errors.
|
||
if chunk then
|
||
sock:write(chunk) -- Echo received messages to the channel.
|
||
else -- EOF (stream closed).
|
||
sock:close() -- Always close handles to avoid leaks.
|
||
end
|
||
end)
|
||
end)
|
||
print('TCP echo-server listening on port: '..server:getsockname().port)
|
||
|
||
------------------------------------------------------------------------------
|
||
VIM.TREESITTER *lua-treesitter*
|
||
|
||
Nvim integrates the tree-sitter library for incremental parsing of buffers.
|
||
|
||
Currently Nvim does not provide the tree-sitter parsers, instead these must
|
||
be built separately, for instance using the tree-sitter utility. The only
|
||
exception is a C parser being included in official builds for testing
|
||
purposes. Parsers are searched for as `parser/{lang}.*` in any 'runtimepath'
|
||
directory. A parser can also be loaded manually using a full path: >
|
||
|
||
vim.treesitter.require_language("python", "/path/to/python.so")
|
||
|
||
<Create a parser for a buffer and a given language (if another plugin uses the
|
||
same buffer/language combination, it will be safely reused). Use >
|
||
|
||
parser = vim.treesitter.get_parser(bufnr, lang)
|
||
|
||
<`bufnr=0` can be used for current buffer. `lang` will default to 'filetype' (this
|
||
doesn't work yet for some filetypes like "cpp") Currently, the parser will be
|
||
retained for the lifetime of a buffer but this is subject to change. A plugin
|
||
should keep a reference to the parser object as long as it wants incremental
|
||
updates.
|
||
|
||
Parser files *treesitter-parsers*
|
||
|
||
Parsers are the heart of tree-sitter. They are libraries that tree-sitter will
|
||
search for in the `parsers` runtime directory.
|
||
|
||
For a parser to be available for a given language, there must be a file named
|
||
`{lang}.so` within the parser directory.
|
||
|
||
Parser methods *lua-treesitter-parser*
|
||
|
||
tsparser:parse() *tsparser:parse()*
|
||
Whenever you need to access the current syntax tree, parse the buffer: >
|
||
|
||
tstree = parser:parse()
|
||
|
||
<This will return an immutable tree that represents the current state of the
|
||
buffer. When the plugin wants to access the state after a (possible) edit
|
||
it should call `parse()` again. If the buffer wasn't edited, the same tree will
|
||
be returned again without extra work. If the buffer was parsed before,
|
||
incremental parsing will be done of the changed parts.
|
||
|
||
NB: to use the parser directly inside a |nvim_buf_attach| Lua callback, you must
|
||
call `get_parser()` before you register your callback. But preferably parsing
|
||
shouldn't be done directly in the change callback anyway as they will be very
|
||
frequent. Rather a plugin that does any kind of analysis on a tree should use
|
||
a timer to throttle too frequent updates.
|
||
|
||
tsparser:set_included_ranges({ranges}) *tsparser:set_included_ranges()*
|
||
Changes the ranges the parser should consider. This is used for
|
||
language injection. {ranges} should be of the form (all zero-based): >
|
||
{
|
||
{start_node, end_node},
|
||
...
|
||
}
|
||
<
|
||
NOTE: `start_node` and `end_node` are both inclusive.
|
||
|
||
Tree methods *lua-treesitter-tree*
|
||
|
||
tstree:root() *tstree:root()*
|
||
Return the root node of this tree.
|
||
|
||
|
||
Node methods *lua-treesitter-node*
|
||
|
||
tsnode:parent() *tsnode:parent()*
|
||
Get the node's immediate parent.
|
||
|
||
tsnode:iter_children() *tsnode:iter_children()*
|
||
Iterates over all the direct children of {tsnode}, regardless of
|
||
wether they are named or not.
|
||
Returns the child node plus the eventual field name corresponding to
|
||
this child node.
|
||
|
||
tsnode:field({name}) *tsnode:field()*
|
||
Returns a table of the nodes corresponding to the {name} field.
|
||
|
||
tsnode:child_count() *tsnode:child_count()*
|
||
Get the node's number of children.
|
||
|
||
tsnode:child({index}) *tsnode:child()*
|
||
Get the node's child at the given {index}, where zero represents the
|
||
first child.
|
||
|
||
tsnode:named_child_count() *tsnode:named_child_count()*
|
||
Get the node's number of named children.
|
||
|
||
tsnode:named_child({index}) *tsnode:named_child()*
|
||
Get the node's named child at the given {index}, where zero represents
|
||
the first named child.
|
||
|
||
tsnode:start() *tsnode:start()*
|
||
Get the node's start position. Return three values: the row, column
|
||
and total byte count (all zero-based).
|
||
|
||
tsnode:end_() *tsnode:end_()*
|
||
Get the node's end position. Return three values: the row, column
|
||
and total byte count (all zero-based).
|
||
|
||
tsnode:range() *tsnode:range()*
|
||
Get the range of the node. Return four values: the row, column
|
||
of the start position, then the row, column of the end position.
|
||
|
||
tsnode:type() *tsnode:type()*
|
||
Get the node's type as a string.
|
||
|
||
tsnode:symbol() *tsnode:symbol()*
|
||
Get the node's type as a numerical id.
|
||
|
||
tsnode:named() *tsnode:named()*
|
||
Check if the node is named. Named nodes correspond to named rules in
|
||
the grammar, whereas anonymous nodes correspond to string literals
|
||
in the grammar.
|
||
|
||
tsnode:missing() *tsnode:missing()*
|
||
Check if the node is missing. Missing nodes are inserted by the
|
||
parser in order to recover from certain kinds of syntax errors.
|
||
|
||
tsnode:has_error() *tsnode:has_error()*
|
||
Check if the node is a syntax error or contains any syntax errors.
|
||
|
||
tsnode:sexpr() *tsnode:sexpr()*
|
||
Get an S-expression representing the node as a string.
|
||
|
||
tsnode:descendant_for_range({start_row}, {start_col}, {end_row}, {end_col})
|
||
*tsnode:descendant_for_range()*
|
||
Get the smallest node within this node that spans the given range of
|
||
(row, column) positions
|
||
|
||
tsnode:named_descendant_for_range({start_row}, {start_col}, {end_row}, {end_col})
|
||
*tsnode:named_descendant_for_range()*
|
||
Get the smallest named node within this node that spans the given
|
||
range of (row, column) positions
|
||
|
||
Query methods *lua-treesitter-query*
|
||
|
||
Tree-sitter queries are supported, with some limitations. Currently, the only
|
||
supported match predicate is `eq?` (both comparing a capture against a string
|
||
and two captures against each other).
|
||
|
||
vim.treesitter.parse_query({lang}, {query})
|
||
*vim.treesitter.parse_query()*
|
||
Parse {query} as a string. (If the query is in a file, the caller
|
||
should read the contents into a string before calling).
|
||
|
||
query:iter_captures({node}, {bufnr}, {start_row}, {end_row})
|
||
*query:iter_captures()*
|
||
Iterate over all captures from all matches inside {node}.
|
||
{bufnr} is needed if the query contains predicates, then the caller
|
||
must ensure to use a freshly parsed tree consistent with the current
|
||
text of the buffer. {start_row} and {end_row} can be used to limit
|
||
matches inside a row range (this is typically used with root node
|
||
as the node, i e to get syntax highlight matches in the current
|
||
viewport)
|
||
|
||
The iterator returns two values, a numeric id identifying the capture
|
||
and the captured node. The following example shows how to get captures
|
||
by name:
|
||
>
|
||
for id, node in query:iter_captures(tree:root(), bufnr, first, last) do
|
||
local name = query.captures[id] -- name of the capture in the query
|
||
-- typically useful info about the node:
|
||
local type = node:type() -- type of the captured node
|
||
local row1, col1, row2, col2 = node:range() -- range of the capture
|
||
... use the info here ...
|
||
end
|
||
<
|
||
query:iter_matches({node}, {bufnr}, {start_row}, {end_row})
|
||
*query:iter_matches()*
|
||
Iterate over all matches within a node. The arguments are the same as
|
||
for |query:iter_captures()| but the iterated values are different:
|
||
an (1-based) index of the pattern in the query, and a table mapping
|
||
capture indices to nodes. If the query has more than one pattern
|
||
the capture table might be sparse, and e.g. `pairs` should be used and not
|
||
`ipairs`. Here an example iterating over all captures in
|
||
every match:
|
||
>
|
||
for pattern, match in cquery:iter_matches(tree:root(), bufnr, first, last) do
|
||
for id,node in pairs(match) do
|
||
local name = query.captures[id]
|
||
-- `node` was captured by the `name` capture in the match
|
||
... use the info here ...
|
||
end
|
||
end
|
||
|
||
Treesitter Query Predicates *lua-treesitter-predicates*
|
||
|
||
When writing queries for treesitter, one might use `predicates`, that is,
|
||
special scheme nodes that are evaluted to verify things on a captured node for
|
||
example, the |eq?| predicate : >
|
||
((identifier) @foo (#eq? @foo "foo"))
|
||
|
||
This will only match identifier corresponding to the `"foo"` text.
|
||
Here is a list of built-in predicates :
|
||
|
||
`eq?` *ts-predicate-eq?*
|
||
This predicate will check text correspondance between nodes or
|
||
strings : >
|
||
((identifier) @foo (#eq? @foo "foo"))
|
||
((node1) @left (node2) @right (#eq? @left @right))
|
||
<
|
||
`match?` *ts-predicate-match?*
|
||
This will match if the provived lua regex matches the text
|
||
corresponding to a node : >
|
||
((idenfitier) @constant (#match? @constant "^[A-Z_]+$"))
|
||
< Note: the `^` and `$` anchors will respectively match the
|
||
start and end of the node's text.
|
||
|
||
`vim-match?` *ts-predicate-vim-match?*
|
||
This will match the same way than |match?| but using vim
|
||
regexes.
|
||
|
||
`contains?` *ts-predicate-contains?*
|
||
Will check if any of the following arguments appears in the
|
||
text corresponding to the node : >
|
||
((identifier) @foo (#contains? @foo "foo"))
|
||
((identifier) @foo-bar (#contains @foo-bar "foo" "bar"))
|
||
<
|
||
*lua-treesitter-not-predicate*
|
||
Each predicate has a `not-` prefixed predicate that is just the negation of
|
||
the predicate.
|
||
|
||
*vim.treesitter.query.add_predicate()*
|
||
vim.treesitter.query.add_predicate({name}, {handler})
|
||
|
||
This adds a predicate with the name {name} to be used in queries.
|
||
{handler} should be a function whose signature will be : >
|
||
handler(match, pattern, bufnr, predicate)
|
||
|
||
Treesitter syntax highlighting (WIP) *lua-treesitter-highlight*
|
||
|
||
NOTE: This is a partially implemented feature, and not usable as a default
|
||
solution yet. What is documented here is a temporary interface indented
|
||
for those who want to experiment with this feature and contribute to
|
||
its development.
|
||
|
||
Highlights are defined in the same query format as in the tree-sitter highlight
|
||
crate, which some limitations and additions. Set a highlight query for a
|
||
buffer with this code: >
|
||
|
||
local query = [[
|
||
"for" @keyword
|
||
"if" @keyword
|
||
"return" @keyword
|
||
|
||
(string_literal) @string
|
||
(number_literal) @number
|
||
(comment) @comment
|
||
|
||
(preproc_function_def name: (identifier) @function)
|
||
|
||
; ... more definitions
|
||
]]
|
||
|
||
highlighter = vim.treesitter.TSHighlighter.new(query, bufnr, lang)
|
||
-- alternatively, to use the current buffer and its filetype:
|
||
-- highlighter = vim.treesitter.TSHighlighter.new(query)
|
||
|
||
-- Don't recreate the highlighter for the same buffer, instead
|
||
-- modify the query like this:
|
||
local query2 = [[ ... ]]
|
||
highlighter:set_query(query2)
|
||
|
||
As mentioned above the supported predicate is currently only `eq?`. `match?`
|
||
predicates behave like matching always fails. As an addition a capture which
|
||
begin with an upper-case letter like `@WarningMsg` will map directly to this
|
||
highlight group, if defined. Also if the predicate begins with upper-case and
|
||
contains a dot only the part before the first will be interpreted as the
|
||
highlight group. As an example, this warns of a binary expression with two
|
||
identical identifiers, highlighting both as |hl-WarningMsg|: >
|
||
|
||
((binary_expression left: (identifier) @WarningMsg.left right: (identifier) @WarningMsg.right)
|
||
(eq? @WarningMsg.left @WarningMsg.right))
|
||
|
||
------------------------------------------------------------------------------
|
||
VIM.HIGHLIGHT *lua-highlight*
|
||
|
||
Nvim includes a function for highlighting a selection on yank (see for example
|
||
https://github.com/machakann/vim-highlightedyank). To enable it, add
|
||
>
|
||
au TextYankPost * silent! lua vim.highlight.on_yank()
|
||
<
|
||
to your `init.vim`. You can customize the highlight group and the duration of
|
||
the highlight via
|
||
>
|
||
au TextYankPost * silent! lua vim.highlight.on_yank {higroup="IncSearch", timeout=150}
|
||
<
|
||
If you want to exclude visual selections from highlighting on yank, use
|
||
>
|
||
au TextYankPost * silent! lua vim.highlight.on_yank {on_visual=false}
|
||
<
|
||
|
||
vim.highlight.on_yank({opts}) *vim.highlight.on_yank()*
|
||
Highlights the yanked text. The fields of the optional dict {opts}
|
||
control the highlight:
|
||
- {higroup} highlight group for yanked region (default `"IncSearch"`)
|
||
- {timeout} time in ms before highlight is cleared (default `150`)
|
||
- {on_macro} highlight when executing macro (default `false`)
|
||
- {on_visual} highlight when yanking visual selection (default `true`)
|
||
- {event} event structure (default `vim.v.event`)
|
||
|
||
vim.highlight.range({bufnr}, {ns}, {higroup}, {start}, {finish}, {rtype}, {inclusive})
|
||
*vim.highlight.range()*
|
||
Highlights the range between {start} and {finish} (tuples of {line,col})
|
||
in buffer {bufnr} with the highlight group {higroup} using the namespace
|
||
{ns}. Optional arguments are the type of range (characterwise, linewise,
|
||
or blockwise, see |setreg|; default to characterwise) and whether the
|
||
range is inclusive (default false).
|
||
|
||
------------------------------------------------------------------------------
|
||
VIM.REGEX *lua-regex*
|
||
|
||
Vim regexes can be used directly from lua. Currently they only allow
|
||
matching within a single line.
|
||
|
||
vim.regex({re}) *vim.regex()*
|
||
|
||
Parse the regex {re} and return a regex object. 'magic' and
|
||
'ignorecase' options are ignored, lua regexes always defaults to magic
|
||
and ignoring case. The behavior can be changed with flags in
|
||
the beginning of the string |/magic|.
|
||
|
||
Regex objects support the following methods:
|
||
|
||
regex:match_str({str}) *regex:match_str()*
|
||
Match the string against the regex. If the string should match the
|
||
regex precisely, surround the regex with `^` and `$`.
|
||
If the was a match, the byte indices for the beginning and end of
|
||
the match is returned. When there is no match, `nil` is returned.
|
||
As any integer is truth-y, `regex:match()` can be directly used
|
||
as a condition in an if-statement.
|
||
|
||
regex:match_line({bufnr}, {line_idx}[, {start}, {end}]) *regex:match_line()*
|
||
Match line {line_idx} (zero-based) in buffer {bufnr}. If {start} and
|
||
{end} are supplied, match only this byte index range. Otherwise see
|
||
|regex:match_str()|. If {start} is used, then the returned byte
|
||
indices will be relative {start}.
|
||
|
||
------------------------------------------------------------------------------
|
||
VIM *lua-builtin*
|
||
|
||
vim.api.{func}({...}) *vim.api*
|
||
Invokes Nvim |API| function {func} with arguments {...}.
|
||
Example: call the "nvim_get_current_line()" API function: >
|
||
print(tostring(vim.api.nvim_get_current_line()))
|
||
|
||
vim.in_fast_event() *vim.in_fast_event()*
|
||
Returns true if the code is executing as part of a "fast" event
|
||
handler, where most of the API is disabled. These are low-level events
|
||
(e.g. |lua-loop-callbacks|) which can be invoked whenever Nvim polls
|
||
for input. When this is `false` most API functions are callable (but
|
||
may be subject to other restrictions such as |textlock|).
|
||
|
||
vim.NIL *vim.NIL*
|
||
Special value used to represent NIL in msgpack-rpc and |v:null| in
|
||
vimL interaction, and similar cases. Lua `nil` cannot be used as
|
||
part of a lua table representing a Dictionary or Array, as it
|
||
is equivalent to a missing value: `{"foo", nil}` is the same as
|
||
`{"foo"}`
|
||
|
||
vim.empty_dict() *vim.empty_dict()*
|
||
Creates a special table which will be converted to an empty
|
||
dictionary when converting lua values to vimL or API types. The
|
||
table is empty, and this property is marked using a metatable. An
|
||
empty table `{}` without this metatable will default to convert to
|
||
an array/list.
|
||
|
||
Note: if numeric keys are added to the table, the metatable will be
|
||
ignored and the dict converted to a list/array anyway.
|
||
|
||
vim.region({bufnr}, {pos1}, {pos2}, {type}, {inclusive}) *vim.region()*
|
||
Converts a selection specified by the buffer ({bufnr}), starting
|
||
position ({pos1}, a zero-indexed pair `{line1,column1}`), ending
|
||
position ({pos2}, same format as {pos1}), the type of the register
|
||
for the selection ({type}, see |regtype|), and a boolean indicating
|
||
whether the selection is inclusive or not, into a zero-indexed table
|
||
of linewise selections of the form `{linenr = {startcol, endcol}}` .
|
||
|
||
*vim.register_keystroke_callback()*
|
||
vim.register_keystroke_callback({fn}, {ns_id})
|
||
Register a lua {fn} with an {ns_id} to be run after every keystroke.
|
||
|
||
Parameters: ~
|
||
{fn}: (function): Function to call on keystroke.
|
||
It should take one argument, which is a string.
|
||
The string will contain the literal keys typed.
|
||
See |i_CTRL-V|
|
||
|
||
If {fn} is `nil`, it removes the callback for the
|
||
associated {ns_id}.
|
||
|
||
{ns_id}: (number) Namespace ID. If not passed or 0, will generate
|
||
and return a new namespace ID from |nvim_create_namespace()|
|
||
|
||
Return: ~
|
||
(number) Namespace ID associated with {fn}
|
||
|
||
NOTE: {fn} will be automatically removed if an error occurs while
|
||
calling. This is to prevent the annoying situation of every keystroke
|
||
erroring while trying to remove a broken callback.
|
||
|
||
NOTE: {fn} will receive the keystrokes after mappings have been
|
||
evaluated
|
||
|
||
NOTE: {fn} will *NOT* be cleared from |nvim_buf_clear_namespace()|
|
||
|
||
vim.rpcnotify({channel}, {method}[, {args}...]) *vim.rpcnotify()*
|
||
Sends {event} to {channel} via |RPC| and returns immediately.
|
||
If {channel} is 0, the event is broadcast to all channels.
|
||
|
||
This function also works in a fast callback |lua-loop-callbacks|.
|
||
|
||
vim.rpcrequest({channel}, {method}[, {args}...]) *vim.rpcrequest()*
|
||
Sends a request to {channel} to invoke {method} via
|
||
|RPC| and blocks until a response is received.
|
||
|
||
Note: NIL values as part of the return value is represented as
|
||
|vim.NIL| special value
|
||
|
||
vim.stricmp({a}, {b}) *vim.stricmp()*
|
||
Compares strings case-insensitively. Returns 0, 1 or -1 if strings
|
||
are equal, {a} is greater than {b} or {a} is lesser than {b},
|
||
respectively.
|
||
|
||
vim.str_utfindex({str}[, {index}]) *vim.str_utfindex()*
|
||
Convert byte index to UTF-32 and UTF-16 indicies. If {index} is not
|
||
supplied, the length of the string is used. All indicies are zero-based.
|
||
Returns two values: the UTF-32 and UTF-16 indicies respectively.
|
||
|
||
Embedded NUL bytes are treated as terminating the string. Invalid
|
||
UTF-8 bytes, and embedded surrogates are counted as one code
|
||
point each. An {index} in the middle of a UTF-8 sequence is rounded
|
||
upwards to the end of that sequence.
|
||
|
||
vim.str_byteindex({str}, {index}[, {use_utf16}]) *vim.str_byteindex()*
|
||
Convert UTF-32 or UTF-16 {index} to byte index. If {use_utf16} is not
|
||
supplied, it defaults to false (use UTF-32). Returns the byte index.
|
||
|
||
Invalid UTF-8 and NUL is treated like by |vim.str_byteindex()|. An {index}
|
||
in the middle of a UTF-16 sequence is rounded upwards to the end of that
|
||
sequence.
|
||
|
||
vim.schedule({callback}) *vim.schedule()*
|
||
Schedules {callback} to be invoked soon by the main event-loop. Useful
|
||
to avoid |textlock| or other temporary restrictions.
|
||
|
||
|
||
vim.defer_fn({fn}, {timeout}) *vim.defer_fn*
|
||
Defers calling {fn} until {timeout} ms passes. Use to do a one-shot timer
|
||
that calls {fn}.
|
||
|
||
Note: The {fn} is |schedule_wrap|ped automatically, so API functions are
|
||
safe to call.
|
||
|
||
Parameters: ~
|
||
{fn} Callback to call once {timeout} expires
|
||
{timeout} Time in ms to wait before calling {fn}
|
||
|
||
Returns: ~
|
||
|vim.loop|.new_timer() object
|
||
|
||
vim.wait({time}, {callback} [, {interval}]) *vim.wait()*
|
||
Wait for {time} in milliseconds until {callback} returns `true`.
|
||
|
||
Executes {callback} immediately and at approximately {interval}
|
||
milliseconds (default 200). Nvim still processes other events during
|
||
this time.
|
||
|
||
|
||
Returns: ~
|
||
If {callback} returns `true` during the {time}:
|
||
`true, nil`
|
||
|
||
If {callback} never returns `true` during the {time}:
|
||
`false, -1`
|
||
|
||
If {callback} is interrupted during the {time}:
|
||
`false, -2`
|
||
|
||
If {callback} errors, the error is raised.
|
||
|
||
Examples: >
|
||
|
||
---
|
||
-- Wait for 100 ms, allowing other events to process
|
||
vim.wait(100, function() end)
|
||
|
||
---
|
||
-- Wait for 100 ms or until global variable set.
|
||
vim.wait(100, function() return vim.g.waiting_for_var end)
|
||
|
||
---
|
||
-- Wait for 1 second or until global variable set, checking every ~500 ms
|
||
vim.wait(1000, function() return vim.g.waiting_for_var end, 500)
|
||
|
||
---
|
||
-- Schedule a function to set a value in 100ms
|
||
vim.defer_fn(function() vim.g.timer_result = true end, 100)
|
||
|
||
-- Would wait ten seconds if results blocked. Actually only waits 100 ms
|
||
if vim.wait(10000, function() return vim.g.timer_result end) then
|
||
print('Only waiting a little bit of time!')
|
||
end
|
||
<
|
||
|
||
vim.type_idx *vim.type_idx*
|
||
Type index for use in |lua-special-tbl|. Specifying one of the
|
||
values from |vim.types| allows typing the empty table (it is
|
||
unclear whether empty Lua table represents empty list or empty array)
|
||
and forcing integral numbers to be |Float|. See |lua-special-tbl| for
|
||
more details.
|
||
|
||
vim.val_idx *vim.val_idx*
|
||
Value index for tables representing |Float|s. A table representing
|
||
floating-point value 1.0 looks like this: >
|
||
{
|
||
[vim.type_idx] = vim.types.float,
|
||
[vim.val_idx] = 1.0,
|
||
}
|
||
< See also |vim.type_idx| and |lua-special-tbl|.
|
||
|
||
vim.types *vim.types*
|
||
Table with possible values for |vim.type_idx|. Contains two sets
|
||
of key-value pairs: first maps possible values for |vim.type_idx|
|
||
to human-readable strings, second maps human-readable type names to
|
||
values for |vim.type_idx|. Currently contains pairs for `float`,
|
||
`array` and `dictionary` types.
|
||
|
||
Note: one must expect that values corresponding to `vim.types.float`,
|
||
`vim.types.array` and `vim.types.dictionary` fall under only two
|
||
following assumptions:
|
||
1. Value may serve both as a key and as a value in a table. Given the
|
||
properties of Lua tables this basically means “value is not `nil`”.
|
||
2. For each value in `vim.types` table `vim.types[vim.types[value]]`
|
||
is the same as `value`.
|
||
No other restrictions are put on types, and it is not guaranteed that
|
||
values corresponding to `vim.types.float`, `vim.types.array` and
|
||
`vim.types.dictionary` will not change or that `vim.types` table will
|
||
only contain values for these three types.
|
||
|
||
------------------------------------------------------------------------------
|
||
LUA-VIMSCRIPT BRIDGE *lua-vimscript*
|
||
|
||
Nvim Lua provides an interface to Vimscript variables and functions, and
|
||
editor commands and options.
|
||
|
||
vim.call({func}, {...}) *vim.call()*
|
||
Invokes |vim-function| or |user-function| {func} with arguments {...}.
|
||
See also |vim.fn|.
|
||
Equivalent to: >
|
||
vim.fn[func]({...})
|
||
|
||
vim.cmd({cmd}) *vim.cmd()*
|
||
Invokes an Ex command (the ":" commands, Vimscript statements).
|
||
See also |ex-cmd-index|.
|
||
Example: >
|
||
vim.cmd('echo 42')
|
||
|
||
vim.fn.{func}({...}) *vim.fn*
|
||
Invokes |vim-function| or |user-function| {func} with arguments {...}.
|
||
To call autoload functions, use the syntax: >
|
||
vim.fn['some#function']({...})
|
||
<
|
||
Unlike vim.api.|nvim_call_function| this converts directly between Vim
|
||
objects and Lua objects. If the Vim function returns a float, it will
|
||
be represented directly as a Lua number. Empty lists and dictionaries
|
||
both are represented by an empty table.
|
||
|
||
Note: |v:null| values as part of the return value is represented as
|
||
|vim.NIL| special value
|
||
|
||
Note: vim.fn keys are generated lazily, thus `pairs(vim.fn)` only
|
||
enumerates functions that were called at least once.
|
||
|
||
|
||
*lua-vim-variables*
|
||
The Vim editor global dictionaries |g:| |w:| |b:| |t:| |v:| can be accessed
|
||
from Lua conveniently and idiomatically by referencing the `vim.*` Lua tables
|
||
described below. In this way you can easily read and modify global Vimscript
|
||
variables from Lua.
|
||
|
||
Example: >
|
||
|
||
vim.g.foo = 5 -- Set the g:foo Vimscript variable.
|
||
print(vim.g.foo) -- Get and print the g:foo Vimscript variable.
|
||
vim.g.foo = nil -- Delete (:unlet) the Vimscript variable.
|
||
|
||
vim.g *vim.g*
|
||
Global (|g:|) editor variables.
|
||
Key with no value returns `nil`.
|
||
|
||
vim.b *vim.b*
|
||
Buffer-scoped (|b:|) variables for the current buffer.
|
||
Invalid or unset key returns `nil`.
|
||
|
||
vim.w *vim.w*
|
||
Window-scoped (|w:|) variables for the current window.
|
||
Invalid or unset key returns `nil`.
|
||
|
||
vim.t *vim.t*
|
||
Tabpage-scoped (|t:|) variables for the current tabpage.
|
||
Invalid or unset key returns `nil`.
|
||
|
||
vim.v *vim.v*
|
||
|v:| variables.
|
||
Invalid or unset key returns `nil`.
|
||
|
||
vim.env *vim.env*
|
||
Environment variables defined in the editor session.
|
||
See |expand-env| and |:let-environment| for the Vimscript behavior.
|
||
Invalid or unset key returns `nil`.
|
||
Example: >
|
||
vim.env.FOO = 'bar'
|
||
print(vim.env.TERM)
|
||
<
|
||
|
||
*lua-vim-options*
|
||
From Lua you can work with editor |options| by reading and setting items in
|
||
these Lua tables:
|
||
|
||
vim.o *vim.o*
|
||
Get or set editor options, like |:set|. Invalid key is an error.
|
||
Example: >
|
||
vim.o.cmdheight = 4
|
||
print(vim.o.columns)
|
||
|
||
vim.bo *vim.bo*
|
||
Get or set buffer-scoped |local-options|. Invalid key is an error.
|
||
Example: >
|
||
vim.bo.buflisted = true
|
||
print(vim.bo.comments)
|
||
|
||
vim.wo *vim.wo*
|
||
Get or set window-scoped |local-options|. Invalid key is an error.
|
||
Example: >
|
||
vim.wo.cursorcolumn = true
|
||
print(vim.wo.foldmarker)
|
||
|
||
|
||
==============================================================================
|
||
Lua module: vim *lua-vim*
|
||
|
||
inspect({object}, {options}) *vim.inspect()*
|
||
Return a human-readable representation of the given object.
|
||
|
||
See also: ~
|
||
https://github.com/kikito/inspect.lua
|
||
https://github.com/mpeterv/vinspect
|
||
|
||
make_meta_accessor({get}, {set}, {del}) *vim.make_meta_accessor()*
|
||
TODO: Documentation
|
||
|
||
paste({lines}, {phase}) *vim.paste()*
|
||
Paste handler, invoked by |nvim_paste()| when a conforming UI
|
||
(such as the |TUI|) pastes text into the editor.
|
||
|
||
Example: To remove ANSI color codes when pasting: >
|
||
|
||
vim.paste = (function(overridden)
|
||
return function(lines, phase)
|
||
for i,line in ipairs(lines) do
|
||
-- Scrub ANSI color codes from paste input.
|
||
lines[i] = line:gsub('\27%[[0-9;mK]+', '')
|
||
end
|
||
overridden(lines, phase)
|
||
end
|
||
end)(vim.paste)
|
||
<
|
||
|
||
Parameters: ~
|
||
{lines} |readfile()|-style list of lines to paste.
|
||
|channel-lines|
|
||
{phase} -1: "non-streaming" paste: the call contains all
|
||
lines. If paste is "streamed", `phase` indicates the stream state:
|
||
• 1: starts the paste (exactly once)
|
||
• 2: continues the paste (zero or more times)
|
||
• 3: ends the paste (exactly once)
|
||
|
||
Return: ~
|
||
false if client should cancel the paste.
|
||
|
||
See also: ~
|
||
|paste|
|
||
|
||
schedule_wrap({cb}) *vim.schedule_wrap()*
|
||
Defers callback `cb` until the Nvim API is safe to call.
|
||
|
||
See also: ~
|
||
|lua-loop-callbacks|
|
||
|vim.schedule()|
|
||
|vim.in_fast_event()|
|
||
|
||
|
||
|
||
|
||
deep_equal({a}, {b}) *vim.deep_equal()*
|
||
TODO: Documentation
|
||
|
||
deepcopy({orig}) *vim.deepcopy()*
|
||
Returns a deep copy of the given object. Non-table objects are
|
||
copied as in a typical Lua assignment, whereas table objects
|
||
are copied recursively. Functions are naively copied, so
|
||
functions in the copied table point to the same functions as
|
||
those in the input table. Userdata and threads are not copied
|
||
and will throw an error.
|
||
|
||
Parameters: ~
|
||
{orig} Table to copy
|
||
|
||
Return: ~
|
||
New table of copied keys and (nested) values.
|
||
|
||
endswith({s}, {suffix}) *vim.endswith()*
|
||
Tests if `s` ends with `suffix` .
|
||
|
||
Parameters: ~
|
||
{s} (string) a string
|
||
{suffix} (string) a suffix
|
||
|
||
Return: ~
|
||
(boolean) true if `suffix` is a suffix of s
|
||
|
||
gsplit({s}, {sep}, {plain}) *vim.gsplit()*
|
||
Splits a string at each instance of a separator.
|
||
|
||
Parameters: ~
|
||
{s} String to split
|
||
{sep} Separator string or pattern
|
||
{plain} If `true` use `sep` literally (passed to
|
||
String.find)
|
||
|
||
Return: ~
|
||
Iterator over the split components
|
||
|
||
See also: ~
|
||
|vim.split()|
|
||
https://www.lua.org/pil/20.2.html
|
||
http://lua-users.org/wiki/StringLibraryTutorial
|
||
|
||
is_callable({f}) *vim.is_callable()*
|
||
Returns true if object `f` can be called as a function.
|
||
|
||
Parameters: ~
|
||
{f} Any object
|
||
|
||
Return: ~
|
||
true if `f` is callable, else false
|
||
|
||
list_extend({dst}, {src}, {start}, {finish}) *vim.list_extend()*
|
||
Extends a list-like table with the values of another list-like
|
||
table.
|
||
|
||
NOTE: This mutates dst!
|
||
|
||
Parameters: ~
|
||
{dst} list which will be modified and appended to.
|
||
{src} list from which values will be inserted.
|
||
{start} Start index on src. defaults to 1
|
||
{finish} Final index on src. defaults to #src
|
||
|
||
Return: ~
|
||
dst
|
||
|
||
See also: ~
|
||
|vim.tbl_extend()|
|
||
|
||
pesc({s}) *vim.pesc()*
|
||
Escapes magic chars in a Lua pattern.
|
||
|
||
Parameters: ~
|
||
{s} String to escape
|
||
|
||
Return: ~
|
||
%-escaped pattern string
|
||
|
||
See also: ~
|
||
https://github.com/rxi/lume
|
||
|
||
split({s}, {sep}, {plain}) *vim.split()*
|
||
Splits a string at each instance of a separator.
|
||
|
||
Examples: >
|
||
split(":aa::b:", ":") --> {'','aa','','bb',''}
|
||
split("axaby", "ab?") --> {'','x','y'}
|
||
split(x*yz*o, "*", true) --> {'x','yz','o'}
|
||
<
|
||
|
||
Parameters: ~
|
||
{s} String to split
|
||
{sep} Separator string or pattern
|
||
{plain} If `true` use `sep` literally (passed to
|
||
String.find)
|
||
|
||
Return: ~
|
||
List-like table of the split components.
|
||
|
||
See also: ~
|
||
|vim.gsplit()|
|
||
|
||
startswith({s}, {prefix}) *vim.startswith()*
|
||
Tests if `s` starts with `prefix` .
|
||
|
||
Parameters: ~
|
||
{s} (string) a string
|
||
{prefix} (string) a prefix
|
||
|
||
Return: ~
|
||
(boolean) true if `prefix` is a prefix of s
|
||
|
||
tbl_add_reverse_lookup({o}) *vim.tbl_add_reverse_lookup()*
|
||
Add the reverse lookup values to an existing table. For
|
||
example: tbl_add_reverse_lookup { A = 1 } == { [1] = 'A , A = 1 }`
|
||
|
||
Parameters: ~
|
||
{o} table The table to add the reverse to.
|
||
|
||
tbl_contains({t}, {value}) *vim.tbl_contains()*
|
||
Checks if a list-like (vector) table contains `value` .
|
||
|
||
Parameters: ~
|
||
{t} Table to check
|
||
{value} Value to compare
|
||
|
||
Return: ~
|
||
true if `t` contains `value`
|
||
|
||
tbl_count({t}) *vim.tbl_count()*
|
||
Counts the number of non-nil values in table `t` .
|
||
>
|
||
|
||
vim.tbl_count({ a=1, b=2 }) => 2
|
||
vim.tbl_count({ 1, 2 }) => 2
|
||
<
|
||
|
||
Parameters: ~
|
||
{t} Table
|
||
|
||
Return: ~
|
||
Number that is the number of the value in table
|
||
|
||
See also: ~
|
||
https://github.com/Tieske/Penlight/blob/master/lua/pl/tablex.lua
|
||
|
||
tbl_deep_extend({behavior}, {...}) *vim.tbl_deep_extend()*
|
||
Merges recursively two or more map-like tables.
|
||
|
||
Parameters: ~
|
||
{behavior} Decides what to do if a key is found in more
|
||
than one map:
|
||
• "error": raise an error
|
||
• "keep": use value from the leftmost map
|
||
• "force": use value from the rightmost map
|
||
{...} Two or more map-like tables.
|
||
|
||
See also: ~
|
||
|tbl_extend()|
|
||
|
||
tbl_extend({behavior}, {...}) *vim.tbl_extend()*
|
||
Merges two or more map-like tables.
|
||
|
||
Parameters: ~
|
||
{behavior} Decides what to do if a key is found in more
|
||
than one map:
|
||
• "error": raise an error
|
||
• "keep": use value from the leftmost map
|
||
• "force": use value from the rightmost map
|
||
{...} Two or more map-like tables.
|
||
|
||
See also: ~
|
||
|extend()|
|
||
|
||
tbl_filter({func}, {t}) *vim.tbl_filter()*
|
||
Filter a table using a predicate function
|
||
|
||
Parameters: ~
|
||
{func} function or callable table
|
||
{t} table
|
||
|
||
tbl_flatten({t}) *vim.tbl_flatten()*
|
||
Creates a copy of a list-like table such that any nested
|
||
tables are "unrolled" and appended to the result.
|
||
|
||
Parameters: ~
|
||
{t} List-like table
|
||
|
||
Return: ~
|
||
Flattened copy of the given list-like table.
|
||
|
||
See also: ~
|
||
Fromhttps://github.com/premake/premake-core/blob/master/src/base/table.lua
|
||
|
||
tbl_isempty({t}) *vim.tbl_isempty()*
|
||
Checks if a table is empty.
|
||
|
||
Parameters: ~
|
||
{t} Table to check
|
||
|
||
See also: ~
|
||
https://github.com/premake/premake-core/blob/master/src/base/table.lua
|
||
|
||
tbl_islist({t}) *vim.tbl_islist()*
|
||
Determine whether a Lua table can be treated as an array.
|
||
|
||
An empty table `{}` will default to being treated as an array.
|
||
Use `vim.emtpy_dict()` to create a table treated as an empty
|
||
dict. Empty tables returned by `rpcrequest()` and `vim.fn`
|
||
functions can be checked using this function whether they
|
||
represent empty API arrays and vimL lists.
|
||
|
||
Parameters: ~
|
||
{t} Table
|
||
|
||
Return: ~
|
||
`true` if array-like table, else `false` .
|
||
|
||
tbl_keys({t}) *vim.tbl_keys()*
|
||
Return a list of all keys used in a table. However, the order
|
||
of the return table of keys is not guaranteed.
|
||
|
||
Parameters: ~
|
||
{t} Table
|
||
|
||
Return: ~
|
||
list of keys
|
||
|
||
See also: ~
|
||
Fromhttps://github.com/premake/premake-core/blob/master/src/base/table.lua
|
||
|
||
tbl_map({func}, {t}) *vim.tbl_map()*
|
||
Apply a function to all values of a table.
|
||
|
||
Parameters: ~
|
||
{func} function or callable table
|
||
{t} table
|
||
|
||
tbl_values({t}) *vim.tbl_values()*
|
||
Return a list of all values used in a table. However, the
|
||
order of the return table of values is not guaranteed.
|
||
|
||
Parameters: ~
|
||
{t} Table
|
||
|
||
Return: ~
|
||
list of values
|
||
|
||
trim({s}) *vim.trim()*
|
||
Trim whitespace (Lua pattern "%s") from both sides of a
|
||
string.
|
||
|
||
Parameters: ~
|
||
{s} String to trim
|
||
|
||
Return: ~
|
||
String with whitespace removed from its beginning and end
|
||
|
||
See also: ~
|
||
https://www.lua.org/pil/20.2.html
|
||
|
||
validate({opt}) *vim.validate()*
|
||
Validates a parameter specification (types and values).
|
||
|
||
Usage example: >
|
||
|
||
function user.new(name, age, hobbies)
|
||
vim.validate{
|
||
name={name, 'string'},
|
||
age={age, 'number'},
|
||
hobbies={hobbies, 'table'},
|
||
}
|
||
...
|
||
end
|
||
<
|
||
|
||
Examples with explicit argument values (can be run directly): >
|
||
|
||
vim.validate{arg1={{'foo'}, 'table'}, arg2={'foo', 'string'}}
|
||
=> NOP (success)
|
||
<
|
||
>
|
||
vim.validate{arg1={1, 'table'}}
|
||
=> error('arg1: expected table, got number')
|
||
<
|
||
>
|
||
vim.validate{arg1={3, function(a) return (a % 2) == 0 end, 'even number'}}
|
||
=> error('arg1: expected even number, got 3')
|
||
<
|
||
|
||
Parameters: ~
|
||
{opt} Map of parameter names to validations. Each key is
|
||
a parameter name; each value is a tuple in one of
|
||
these forms:
|
||
1. (arg_value, type_name, optional)
|
||
• arg_value: argument value
|
||
• type_name: string type name, one of: ("table",
|
||
"t", "string", "s", "number", "n", "boolean",
|
||
"b", "function", "f", "nil", "thread",
|
||
"userdata")
|
||
• optional: (optional) boolean, if true, `nil`
|
||
is valid
|
||
|
||
2. (arg_value, fn, msg)
|
||
• arg_value: argument value
|
||
• fn: any function accepting one argument,
|
||
returns true if and only if the argument is
|
||
valid
|
||
• msg: (optional) error string if validation
|
||
fails
|
||
|
||
vim:tw=78:ts=8:sw=2:et:ft=help:norl:
|