1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668
|
*if_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*
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 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*
*:lua*
:[range]lua {chunk}
Execute 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)
<
:[range]lua << [endmarker]
{script}
{endmarker}
Execute Lua script {script}. Useful for including Lua
code in Vim scripts.
The {endmarker} must NOT be preceded by any white space.
If [endmarker] is omitted from after the "<<", a dot '.' must be used after
{script}, like for the |:append| and |:insert| commands.
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 block finishes. This is
not the case for globals.
*:luado*
:[range]luado {body} Execute Lua function "function (line, linenr) {body}
end" for each line in the [range], with the function
argument being set to the text of each line in turn,
without a trailing <EOL>, and the current line number.
If the value returned by the function is a string it
becomes the text of the line in the current turn. The
default 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}
Execute Lua script in {file}.
The whole argument is used as a single file name.
Examples:
>
:luafile script.lua
:luafile %
<
All these commands execute a Lua chunk from either the command line (:lua and
:luado) or a file (:luafile) with the given line [range]. Similarly to the Lua
interpreter, each chunk has its own scope and so only global variables are
shared between command calls. All Lua default libraries are available. In
addition, Lua "print" function has its output redirected to the Nvim message
area, with arguments separated by a white space instead of a tab.
Lua uses the "vim" module (see |lua-vim|) to issue commands to Nvim. However,
procedures that alter buffer content, open new buffers, and change cursor
position are restricted when the command is executed in the |sandbox|.
==============================================================================
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 that currently second argument to `luaeval` undergoes VimL to lua
conversion, so changing containers in lua do not affect values in VimL. Return
value is also always converted. When converting, |msgpack-special-dict|s are
treated specially.
==============================================================================
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.API *lua-api*
`vim.api` exposes the full Nvim |API| as a table of Lua functions.
Example: to use the "nvim_get_current_line()" API function, call
"vim.api.nvim_get_current_line()": >
print(tostring(vim.api.nvim_get_current_line()))
------------------------------------------------------------------------------
VIM.LOOP *lua-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: http://docs.libuv.org
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))
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: 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_connection)
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_connection(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 *lua-util*
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.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.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 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
paste({lines}, {phase}) *vim.paste()*
Paste handler, invoked by |nvim_paste()| when a conforming UI
(such as the |TUI|) pastes text into the editor.
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()|
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.
Parameters: ~
{orig} Table to copy
Return: ~
New table of copied keys and (nested) values.
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
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()|
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_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_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.
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
pesc({s}) *vim.pesc()*
Escapes magic chars in a Lua pattern string.
Parameters: ~
{s} String to escape
Return: ~
%-escaped pattern string
See also: ~
https://github.com/rxi/lume
vim:tw=78:ts=8:ft=help:norl:
|