aboutsummaryrefslogtreecommitdiff
path: root/runtime/doc/lua.txt
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
commit9243becbedbb6a1592208051f8fa2b090dcc5e7d (patch)
tree607c2a862ec3f4399b8766383f6f8e04c4aa43b4 /runtime/doc/lua.txt
parent9e40b6e9e1bc67f2d856adb837ee64dd0e25b717 (diff)
parent3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff)
downloadrneovim-usermarks.tar.gz
rneovim-usermarks.tar.bz2
rneovim-usermarks.zip
Merge remote-tracking branch 'upstream/master' into usermarksusermarks
Diffstat (limited to 'runtime/doc/lua.txt')
-rw-r--r--runtime/doc/lua.txt1320
1 files changed, 742 insertions, 578 deletions
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index 42f3a5e432..47249a484b 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -11,30 +11,119 @@ Lua engine *lua* *Lua*
==============================================================================
INTRODUCTION *lua-intro*
-The Lua 5.1 language is builtin and always available. Try this command to get
-an idea of what lurks beneath: >
+The Lua 5.1 script engine is builtin and always available. Try this command to
+get an idea of what lurks beneath: >vim
:lua print(vim.inspect(package.loaded))
+
+Nvim includes a "standard library" |lua-stdlib| for Lua. It complements the
+"editor stdlib" (|builtin-functions| and |Ex-commands|) and the |API|, all of
+which can be used from Lua code (|lua-vimscript| |vim.api|). Together these
+"namespaces" form the Nvim programming interface.
+
+Lua plugins and user config are automatically discovered and loaded, just like
+Vimscript. See |lua-guide| for practical guidance.
+
+You can also run Lua scripts from your shell using the |-l| argument: >
+ nvim -l foo.lua [args...]
+<
+ *lua-compat*
+Lua 5.1 is the permanent interface for Nvim Lua. Plugins need only consider
+Lua 5.1, not worry about forward-compatibility with future Lua versions. If
+Nvim ever ships with Lua 5.4+, a Lua 5.1 compatibility shim will be provided
+so that old plugins continue to work transparently.
+
+==============================================================================
+LUA CONCEPTS AND IDIOMS *lua-concepts*
+
+Lua is very simple: this means that, while there are some quirks, once you
+internalize those quirks, everything works the same everywhere. Scopes
+(closures) in particular are very consistent, unlike JavaScript or most other
+languages.
+
+Lua has three fundamental mechanisms—one for "each major aspect of
+programming": tables, closures, and coroutines.
+https://www.lua.org/doc/cacm2018.pdf
+- Tables are the "object" or container datastructure: they represent both
+ lists and maps, you can extend them to represent your own datatypes and
+ change their behavior using |luaref-metatable| (like Python's "datamodel").
+- EVERY scope in Lua is a closure: a function is a closure, a module is
+ a closure, a `do` block (|luaref-do|) is a closure--and they all work the
+ same. A Lua module is literally just a big closure discovered on the "path"
+ (where your modules are found: |package.cpath|).
+- Stackful coroutines enable cooperative multithreading, generators, and
+ versatile control for both Lua and its host (Nvim).
+
+ *lua-call-function*
+Lua functions can be called in multiple ways. Consider the function: >lua
+ local foo = function(a, b)
+ print("A: ", a)
+ print("B: ", b)
+ end
+
+The first way to call this function is: >lua
+ foo(1, 2)
+ -- ==== Result ====
+ -- A: 1
+ -- B: 2
+
+This way of calling a function is familiar from most scripting languages.
+In Lua, any missing arguments are passed as `nil`. Example: >lua
+ foo(1)
+ -- ==== Result ====
+ -- A: 1
+ -- B: nil
+
+Furthermore it is not an error if extra parameters are passed, they are just
+discarded.
+
+ *kwargs*
+When calling a function, you can omit the parentheses if the function takes
+exactly one string literal (`"foo"`) or table literal (`{1,2,3}`). The latter
+is often used to approximate "named parameters" ("kwargs" or "keyword args")
+as in languages like Python and C#. Example: >lua
+ 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" }
<
-Nvim includes a "standard library" |lua-stdlib| for Lua. It complements the
-"editor stdlib" (|builtin-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.
+There's nothing special going on here except that parentheses are treated as
+whitespace. But visually, this small bit of sugar gets reasonably close to
+a "keyword args" interface.
+
+It is of course also valid to call the function with parentheses: >lua
+ func_with_opts({ foo = true, filename = "hello.world" })
+<
+Nvim tends to prefer the keyword args style.
+
+------------------------------------------------------------------------------
+LUA PATTERNS *lua-patterns*
-The |:source| and |:runtime| commands can run Lua scripts as well as Vim
-scripts. Lua modules can be loaded with `require('name')`, which
-conventionally returns a table but can return any value.
+Lua intentionally does not support regular expressions, instead it has limited
+"patterns" |luaref-patterns| which avoid the performance pitfalls of extended
+regex. Lua scripts can also use Vim regex via |vim.regex()|.
-See |lua-require| for details on how Nvim finds and loads Lua modules.
-See |lua-require-example| for an example of how to write and use a module.
+These examples use |string.match()| to demonstrate Lua patterns: >lua
+
+ print(string.match("foo123bar123", "%d+"))
+ -- 123
+ print(string.match("foo123bar123", "[^%d]+"))
+ -- foo
+ print(string.match("foo123bar123", "[abc]+"))
+ -- ba
+ print(string.match("foo.bar", "%.bar"))
+ -- .bar
==============================================================================
-IMPORTING LUA MODULES *lua-require*
+IMPORTING LUA MODULES *require()* *lua-require*
Modules are searched for under the directories specified in 'runtimepath', in
-the order they appear. Any `.` in the module name is treated as a directory
-separator when searching. For a module `foo.bar`, each directory is searched
-for `lua/foo/bar.lua`, then `lua/foo/bar/init.lua`. If no files are found,
+the order they appear. Any "." in the module name is treated as a directory
+separator when searching. For a module `foo.bar`, each directory is searched
+for `lua/foo/bar.lua`, then `lua/foo/bar/init.lua`. If no files are found,
the directories are searched again for a shared library with a name matching
`lua/foo/bar.?`, where `?` is a list of suffixes (such as `so` or `dll`) derived from
the initial value of |package.cpath|. If still no files are found, Nvim falls
@@ -43,13 +132,11 @@ back to Lua's default search mechanism. The first script found is run and
The return value is cached after the first call to `require()` for each module,
with subsequent calls returning the cached value without searching for, or
-executing any script. For further details on `require()`, see the Lua
-documentation at https://www.lua.org/manual/5.1/manual.html#pdf-require.
+executing any script. For further details on `require()`, see |luaref-require()|.
For example, if 'runtimepath' is `foo,bar` and |package.cpath| was
`./?.so;./?.dll` at startup, `require('mod')` searches these paths in order
-and loads the first module found:
-
+and loads the first module found ("first wins"): >
foo/lua/mod.lua
foo/lua/mod/init.lua
bar/lua/mod.lua
@@ -58,10 +145,11 @@ and loads the first module found:
foo/lua/mod.dll
bar/lua/mod.so
bar/lua/mod.dll
-
+<
+ *lua-package-path*
Nvim automatically adjusts |package.path| and |package.cpath| according to the
effective 'runtimepath' value. Adjustment happens whenever 'runtimepath' is
-changed. |package.path| is adjusted by simply appending `/lua/?.lua` and
+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`).
@@ -70,37 +158,33 @@ 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
+- 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 a 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, a `/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`
+ - initial |package.cpath| (defined at compile-time or derived from
+ `$LUA_CPATH` / `$LUA_INIT`) 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 a 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 a `/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:
@@ -113,7 +197,7 @@ Note:
- 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: >
+ paths from there you can set 'runtimepath' to trigger an update: >vim
let &runtimepath = &runtimepath
- Skipping paths from 'runtimepath' which contain semicolons applies both to
@@ -122,170 +206,13 @@ Note:
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 this function is: >
-
- example_func(1, 2)
- -- ==== Result ====
- -- A is: 1
- -- B is: 2
-<
-This way of calling a function is familiar from 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 to omit the parentheses (only) if the function
-takes a single string or table literal (`"foo"` or "`{1,2,3}`", respectively).
-The latter 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 the standard 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.
-
-==============================================================================
-Lua Patterns *lua-patterns*
-
-For performance reasons, Lua does not support regular expressions natively.
-Instead, the Lua `string` standard library allows manipulations using a
-restricted set of "patterns", see |luaref-patterns|.
-
-Examples (`string.match` extracts the first match): >
-
- print(string.match("foo123bar123", "%d+"))
- -- -> 123
-
- print(string.match("foo123bar123", "[^%d]+"))
- -- -> foo
-
- print(string.match("foo123bar123", "[abc]+"))
- -- -> ba
-
- print(string.match("foo.bar", "%.bar"))
- -- -> .bar
-
-For more complex matching, Vim regular expressions can be used from Lua
-through |vim.regex()|.
-
-------------------------------------------------------------------------------
-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.
+|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).
@@ -296,11 +223,11 @@ arguments separated by " " (space) instead of "\t" (tab).
chunk is evaluated as an expression and printed. `:lua =expr` is
equivalent to `:lua print(vim.inspect(expr))`
- Examples: >
+ Examples: >vim
:lua vim.api.nvim_command('echo "Hello, Nvim!"')
-< To see the Lua version: >
+< To see the Lua version: >vim
:lua print(_VERSION)
-< To see the LuaJIT version: >
+< To see the LuaJIT version: >vim
:lua =jit.version
<
*:lua-heredoc*
@@ -311,7 +238,7 @@ arguments separated by " " (space) instead of "\t" (tab).
be preceded by whitespace. You can omit [endmarker] after the "<<" and use
a dot "." after {script} (similar to |:append|, |:insert|).
- Example: >
+ Example: >vim
function! CurrentLineInfo()
lua << EOF
local linenr = vim.api.nvim_win_get_cursor(0)[1]
@@ -333,13 +260,13 @@ arguments separated by " " (space) instead of "\t" (tab).
that becomes the text of the corresponding buffer line. Default [range] is
the whole file: "1,$".
- Examples: >
+ Examples: >vim
: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
+ :luado if bp:match(line) then return "=>\t" .. line end
<
*:luafile*
:luafile {file}
@@ -347,7 +274,7 @@ arguments separated by " " (space) instead of "\t" (tab).
The whole argument is used as the filename (like |:edit|), spaces do not
need to be escaped. Alternatively you can |:source| Lua files.
- Examples: >
+ Examples: >vim
:luafile script.lua
:luafile %
<
@@ -358,7 +285,7 @@ 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: >
+semantically equivalent in Lua to: >lua
local chunkheader = "local _A = select(1, ...) return "
function luaeval (expstr, arg)
@@ -372,11 +299,11 @@ converted to a |Blob|. Conversion of other Lua types is an error.
The magic global "_A" contains the second argument to luaeval().
-Example: >
+Example: >vim
:echo luaeval('_A[1] + _A[2]', [40, 2])
- 42
+ " 42
:echo luaeval('string.match(_A, "[a-z]+")', 'XYXfoo123')
- foo
+ " 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.
@@ -408,7 +335,7 @@ cases there is the following agreement:
form a 1-step sequence from 1 to N are ignored, as well as all
non-integral keys.
-Examples: >
+Examples: >vim
:echo luaeval('math.pi')
:function Rand(x,y) " random uniform between x and y
@@ -425,29 +352,29 @@ 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 >
+which are global or accessible from global tables. The expression >vim
+ call v:lua.func(arg1, arg2)
+is equivalent to the Lua chunk >lua
return func(...)
-where the args are converted to Lua values. The expression >
- v:lua.somemod.func(args)
-is equivalent to the Lua chunk >
+where the args are converted to Lua values. The expression >vim
+ call v:lua.somemod.func(args)
+is equivalent to the Lua chunk >lua
return somemod.func(...)
-In addition, functions of packages can be accessed like >
- v:lua.require'mypack'.func(arg1, arg2)
- v:lua.require'mypack.submod'.func(arg1, arg2)
+In addition, functions of packages can be accessed like >vim
+ call v:lua.require'mypack'.func(arg1, arg2)
+ call v:lua.require'mypack.submod'.func(arg1, arg2)
Note: Only single quote form without parens is allowed. Using
`require"mypack"` or `require('mypack')` as prefixes do NOT work (the latter
is still valid as a function call of itself, in case require returns a useful
value).
The `v:lua` prefix may be used to call Lua functions as |method|s. For
-example: >
- arg1->v:lua.somemod.func(arg2)
+example: >vim
+ :eval arg1->v:lua.somemod.func(arg2)
<
You can use `v:lua` in "func" options like 'tagfunc', 'omnifunc', etc.
-For example consider the following Lua omnifunc handler: >
+For example consider the following Lua omnifunc handler: >lua
function mymod.omnifunc(findstart, base)
if findstart == 1 then
@@ -459,10 +386,10 @@ For example consider the following Lua omnifunc handler: >
vim.api.nvim_buf_set_option(0, 'omnifunc', 'v:lua.mymod.omnifunc')
Note: The module ("mymod" in the above example) must either be a Lua global,
-or use the require syntax as specified above to access it from a package.
+or use require() as shown above to access it from a package.
Note: `v:lua` without a call is not allowed in a Vimscript expression:
-|Funcref|s cannot represent Lua functions. The following are errors: >
+|Funcref|s cannot represent Lua functions. The following are errors: >vim
let g:Myvar = v:lua.myfunc " Error
call SomeFunc(v:lua.mycallback) " Error
@@ -476,7 +403,7 @@ 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: >
+You can peek at the module properties: >vim
:lua print(vim.inspect(vim))
@@ -496,7 +423,7 @@ Result is something like this: >
...
}
-To find documentation on e.g. the "deepcopy" function: >
+To find documentation on e.g. the "deepcopy" function: >vim
:help vim.deepcopy()
@@ -508,7 +435,7 @@ 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: >
+management. Try this command to see available functions: >vim
:lua print(vim.inspect(vim.loop))
<
@@ -517,14 +444,14 @@ see |luv-intro| for a full reference manual.
*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: >
+`vim.loop` callbacks. For example, this is an error: >lua
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: >
+To avoid the error use |vim.schedule_wrap()| to defer the callback: >lua
local timer = vim.loop.new_timer()
timer:start(1000, 0, vim.schedule_wrap(function()
@@ -536,7 +463,7 @@ wrapping.)
Example: repeating timer
1. Save this code to a file.
- 2. Execute it with ":luafile %". >
+ 2. Execute it with ":luafile %". >lua
-- Create a timer handle (implementation detail: uv_timer_t).
local timer = vim.loop.new_timer()
@@ -557,7 +484,7 @@ Example: File-change detection *watch-file*
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|). >
+ |:checktime|). >lua
local w = vim.loop.new_fs_event()
local function on_change(err, fname, status)
@@ -580,7 +507,7 @@ 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"): >
+ 4. Connect from any TCP client (e.g. "nc 0.0.0.0 36795"): >lua
local function create_server(host, port, on_connect)
local server = vim.loop.new_tcp()
@@ -617,7 +544,7 @@ A subset of the `vim.*` API is available in threads. This includes:
- `vim.loop` with a separate event loop per thread.
- `vim.mpack` and `vim.json` (useful for serializing messages between threads)
-- `require` in threads can use lua packages from the global |lua-package-path|
+- `require` in threads can use lua packages from the global |package.path|
- `print()` and `vim.inspect`
- `vim.diff`
- most utility functions in `vim.*` for working with pure lua values
@@ -629,16 +556,16 @@ 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
->
+>vim
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
->
+>vim
au TextYankPost * silent! lua vim.highlight.on_yank {higroup="IncSearch", timeout=150}
<
If you want to exclude visual selections from highlighting on yank, use
->
+>vim
au TextYankPost * silent! lua vim.highlight.on_yank {on_visual=false}
<
vim.highlight.on_yank({opts}) *vim.highlight.on_yank()*
@@ -656,14 +583,14 @@ vim.highlight.range({bufnr}, {ns}, {hlgroup}, {start}, {finish}, {opts})
Apply highlight group to range of text.
Parameters: ~
- {bufnr} buffer number
- {ns} namespace for highlights
- {hlgroup} highlight group name
- {start} starting position (tuple {line,col})
- {finish} finish position (tuple {line,col})
- {opts} optional parameters:
+ • {bufnr} buffer number
+ • {ns} namespace for highlights
+ • {hlgroup} highlight group name
+ • {start} starting position (tuple {line,col})
+ • {finish} finish position (tuple {line,col})
+ • {opts} optional parameters:
• `regtype`: type of range (characterwise, linewise,
- or blockwise, see |setreg|), default `'v'`
+ or blockwise, see |setreg()|), default `'v'`
• `inclusive`: range includes end position,
default `false`
• `priority`: priority of highlight, default
@@ -674,6 +601,7 @@ vim.highlight.priorities *vim.highlight.priorities*
Table with default priorities used for highlighting:
• `syntax`: `50`, used for standard syntax highlighting
• `treesitter`: `100`, used for tree-sitter-based highlighting
+ • `semantic_tokens`: `125`, used for LSP semantic token highlighting
• `diagnostics`: `150`, used for code analysis such as diagnostics
• `user`: `200`, used for user-triggered highlights such as LSP document
symbols or `on_yank` autocommands
@@ -711,25 +639,24 @@ vim.diff({a}, {b}, {opts}) *vim.diff()*
Run diff on strings {a} and {b}. Any indices returned by this function,
either directly or via callback arguments, are 1-based.
- Examples: >
-
+ Examples: >lua
vim.diff('a\n', 'b\nc\n')
- -->
- @@ -1 +1,2 @@
- -a
- +b
- +c
+ -- =>
+ -- @@ -1 +1,2 @@
+ -- -a
+ -- +b
+ -- +c
vim.diff('a\n', 'b\nc\n', {result_type = 'indices'})
- -->
- {
- {1, 1, 1, 2}
- }
+ -- =>
+ -- {
+ -- {1, 1, 1, 2}
+ -- }
<
Parameters: ~
- {a} First string to compare
- {b} Second string to compare
- {opts} Optional parameters:
+ • {a} First string to compare
+ • {b} Second string to compare
+ • {opts} Optional parameters:
• `on_hunk` (callback):
Invoked for each hunk in the diff. Return a negative number
to cancel the callback for any remaining hunks.
@@ -742,6 +669,9 @@ vim.diff({a}, {b}, {opts}) *vim.diff()*
• "unified": (default) String in unified format.
• "indices": Array of hunk locations.
Note: This option is ignored if `on_hunk` is used.
+ • `linematch` (boolean): Run linematch on the resulting hunks
+ from xdiff. Requires `result_type = indices`, ignored
+ otherwise.
• `algorithm` (string):
Diff algorithm to use. Values:
• "myers" the default algorithm
@@ -782,6 +712,22 @@ vim.mpack.decode({str}) *vim.mpack.decode*
Decodes (or "unpacks") the msgpack-encoded {str} to a Lua object.
------------------------------------------------------------------------------
+VIM.JSON *lua-json*
+
+The *vim.json* module provides encoding and decoding of Lua objects to and
+from JSON-encoded strings. Supports |vim.NIL| and |vim.empty_dict()|.
+
+vim.json.encode({obj}) *vim.json.encode*
+ Encodes (or "packs") Lua object {obj} as JSON in a Lua string.
+
+vim.json.decode({str}[, {opts}]) *vim.json.decode*
+ Decodes (or "unpacks") the JSON-encoded {str} to a Lua object.
+
+ {opts} is a table with the key `luanil = { object: bool, array: bool }`
+ that controls whether `null` in JSON objects or arrays should be converted
+ to Lua `nil` instead of `vim.NIL`.
+
+------------------------------------------------------------------------------
VIM.SPELL *lua-spell*
vim.spell.check({str}) *vim.spell.check()*
@@ -792,16 +738,15 @@ vim.spell.check({str}) *vim.spell.check()*
'spellfile', 'spellcapcheck' and 'spelloptions' which can all be local to
the buffer. Consider calling this with |nvim_buf_call()|.
- Example: >
-
+ Example: >lua
vim.spell.check("the quik brown fox")
- -->
- {
- {'quik', 'bad', 4}
- }
+ -- =>
+ -- {
+ -- {'quik', 'bad', 5}
+ -- }
<
Parameters: ~
- {str} String to spell check.
+ • {str} String to spell check.
Return: ~
List of tuples with three items:
@@ -818,7 +763,7 @@ VIM *lua-builtin*
vim.api.{func}({...}) *vim.api*
Invokes Nvim |API| function {func} with arguments {...}.
- Example: call the "nvim_get_current_line()" API function: >
+ Example: call the "nvim_get_current_line()" API function: >lua
print(tostring(vim.api.nvim_get_current_line()))
vim.version() *vim.version*
@@ -881,6 +826,22 @@ vim.str_byteindex({str}, {index} [, {use_utf16}]) *vim.str_byteindex()*
An {index} in the middle of a UTF-16 sequence is rounded upwards to
the end of that sequence.
+vim.iconv({str}, {from}, {to}[, {opts}]) *vim.iconv()*
+ The result is a String, which is the text {str} converted from
+ encoding {from} to encoding {to}. When the conversion fails `nil` is
+ returned. When some characters could not be converted they
+ are replaced with "?".
+ The encoding names are whatever the iconv() library function
+ can accept, see ":Man 3 iconv".
+
+ Parameters: ~
+ • {str} (string) Text to convert
+ • {from} (string) Encoding of {str}
+ • {to} (string) Target encoding
+
+ Returns: ~
+ Converted string if conversion succeeds, `nil` otherwise.
+
vim.schedule({callback}) *vim.schedule()*
Schedules {callback} to be invoked soon by the main event-loop. Useful
to avoid |textlock| or other temporary restrictions.
@@ -890,12 +851,12 @@ 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
+ Note: The {fn} is |vim.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}
+ • {fn} Callback to call once {timeout} expires
+ • {timeout} Time in ms to wait before calling {fn}
Returns: ~
|vim.loop|.new_timer() object
@@ -908,10 +869,10 @@ vim.wait({time} [, {callback}, {interval}, {fast_only}]) *vim.wait()*
this time.
Parameters: ~
- {time} Number of milliseconds to wait
- {callback} Optional callback. Waits until {callback} returns true
- {interval} (Approximate) number of milliseconds to wait between polls
- {fast_only} If true, only |api-fast| events will be processed.
+ • {time} Number of milliseconds to wait
+ • {callback} Optional callback. Waits until {callback} returns true
+ • {interval} (Approximate) number of milliseconds to wait between polls
+ • {fast_only} If true, only |api-fast| events will be processed.
If called from while in an |api-fast| event, will
automatically be set to `true`.
@@ -927,7 +888,7 @@ vim.wait({time} [, {callback}, {interval}, {fast_only}]) *vim.wait()*
If {callback} errors, the error is raised.
- Examples: >
+ Examples: >lua
---
-- Wait for 100 ms, allowing other events to process
@@ -951,6 +912,43 @@ vim.wait({time} [, {callback}, {interval}, {fast_only}]) *vim.wait()*
end
<
+vim.ui_attach({ns}, {options}, {callback}) *vim.ui_attach()*
+ Attach to ui events, similar to |nvim_ui_attach()| but receive events
+ as lua callback. Can be used to implement screen elements like
+ popupmenu or message handling in lua.
+
+ {options} should be a dictionary-like table, where `ext_...` options should
+ be set to true to receive events for the respective external element.
+
+ {callback} receives event name plus additional parameters. See |ui-popupmenu|
+ and the sections below for event format for respective events.
+
+ WARNING: This api is considered experimental. Usability will vary for
+ different screen elements. In particular `ext_messages` behavior is subject
+ to further changes and usability improvements. This is expected to be
+ used to handle messages when setting 'cmdheight' to zero (which is
+ likewise experimental).
+
+ Example (stub for a |ui-popupmenu| implementation): >lua
+
+ ns = vim.api.nvim_create_namespace('my_fancy_pum')
+
+ vim.ui_attach(ns, {ext_popupmenu=true}, function(event, ...)
+ if event == "popupmenu_show" then
+ local items, selected, row, col, grid = ...
+ print("display pum ", #items)
+ elseif event == "popupmenu_select" then
+ local selected = ...
+ print("selected", selected)
+ elseif event == "popupmenu_hide" then
+ print("FIN")<