Lua

Nvim 的 :help 页面,从 这里 生成,源自 这里,使用 tree-sitter-vimdoc 解析器。


Lua 引擎 Lua

简介 lua-intro

Lua 5.1 脚本引擎是内置的,并且始终可用。尝试以下命令以了解其背后的机制。
:lua vim.print(package.loaded)
Nvim 包含一个“标准库” lua-stdlib 用于 Lua。它补充了“编辑器标准库”(builtin-functionsEx-commands)和 API,所有这些都可以在 Lua 代码中使用 (lua-vimscript vim.api)。这些“命名空间”共同构成了 Nvim 编程接口。
Lua 插件和用户配置会自动发现和加载,就像 Vimscript 一样。请参阅 lua-guide 获取实际指导。
您还可以使用 -l 参数从 shell 中运行 Lua 脚本。
nvim -l foo.lua [args...]
lua-compat
Lua 5.1 是 Nvim Lua 的永久接口。插件应以 luaref 中指定的 Lua 5.1 为目标;不支持更高版本(实际上是不同的、不兼容的方言)。这包括一些 Lua 5.1 解释器(如 LuaJIT)可能支持的扩展,例如 goto
lua-luajit
虽然 Nvim 官方只要求 Lua 5.1 支持,但出于性能原因,它应该在受支持的平台上使用 LuaJIT 或兼容的分支构建。LuaJIT 还附带了一些有用的扩展,例如 ffilua-profile 和增强的标准库函数;这些不能被认为是可用的,在 init.lua 或插件中的 Lua 代码应在使用它们之前检查 jit 全局变量。
if jit then
  -- code for luajit
else
  -- code for plain lua 5.1
end
lua-bit
一个例外是 LuaJIT 的 bit 扩展,它始终可用:当使用 PUC Lua 构建时,Nvim 包含一个回退实现,它提供 require("bit")
lua-profile
如果 Nvim 使用 LuaJIT 构建,则可以通过以下方式对 Lua 代码进行分析。
-- Start a profiling session:
require('jit.p').start('ri1', '/tmp/profile')
-- Perform arbitrary tasks (use plugins, scripts, etc.) ...
-- Stop the session. Profile is written to /tmp/profile.
require('jit.p').stop()
请参阅 https://luajit.org/ext_profiler.htmlp.lua 源代码以获取详细信息。
:lua vim.cmd.edit(package.searchpath('jit.p', package.path))

Lua 概念和习语 lua-concepts

Lua 非常简单,并且 _一致_:虽然有一些怪癖,但是一旦你理解了这些怪癖,它们在任何地方都以相同的方式运作。特别是作用域(闭包)与 JavaScript 或大多数其他语言不同,非常一致。
Lua 有三种基本机制——分别用于“编程的每个主要方面”:表、闭包和协程。 https://lua.ac.cn/doc/cacm2018.pdf
表是“对象”或容器数据结构:它们同时代表列表和映射,您可以扩展它们来代表您自己的数据类型,并使用 元表(类似于 Python 的“数据模型”)来改变它们的行为。
Lua 中的每个作用域都是一个闭包:函数是一个闭包,模块是一个闭包,do 块 (lua-do) 是一个闭包——它们都以相同的方式工作。Lua 模块实际上只是一个在“路径”上发现的大型闭包(模块所在的位置:package.cpath)。
带堆栈的协程支持协作式多线程、生成器以及 Lua 及其宿主 (Nvim) 的通用控制。
lua-error-handling
Lua 函数可能会为异常(意外)故障抛出 lua-errors,您可以使用 pcall() 来处理它们。 lua-result-or-message
当故障是正常且预期的时,惯用做法是返回 nil,它向调用者发出信号表明故障不是“异常的”,必须进行处理。这种“结果或消息”模式表示为多值返回类型 any|nil,nil|string,或在 LuaLS 符号中表示为
---@return any|nil    # result on success, nil on failure.
---@return nil|string # nil on success, error message on failure.
“结果或消息”模式的示例
当调用者在失败时无法继续时,惯用做法是对“结果或消息”结果使用 assert()
local value = assert(fn())
指南:在以下情况下使用“结果或消息”模式...
预期会发生故障的函数,特别是当与外部世界进行通信时。例如,HTTP 请求或 LSP 请求经常因为服务器问题而失败,即使调用者做了所有正确的事情。
返回值的函数,例如 Foo:new()。
当存在可以作为第三个值返回的已知错误代码列表时(例如 luv-error-handling)。
iterator
迭代器只是一个函数,可以重复调用它来获取集合(或任何其他 可迭代对象)的“下一个”值。此接口是 for-in 循环所期望的,由 pairs() 生成,由 vim.iter 支持,等等。 https://lua.ac.cn/pil/7.1.html
iterable
“可迭代对象”是任何 vim.iter() 可以消耗的东西:表、字典、列表、迭代器函数、实现 __call() 元方法的表,以及 vim.iter() 对象。
list-iterator
lua-list 表上的迭代器有“中间”和“结束”,而一般的迭代器在逻辑上可能是无限的。因此,一些 vim.iter 操作(例如 Iter:rev())只对类似列表的表(它们在定义上是有限的)有意义。
lua-function-call
Lua 函数可以通过多种方式调用。考虑以下函数
local foo = function(a, b)
    print("A: ", a)
    print("B: ", b)
end
调用此函数的第一种方式是
foo(1, 2)
-- ==== Result ====
-- A: 1
-- B: 2
这种调用函数的方式在大多数脚本语言中都很熟悉。在 Lua 中,任何缺失的参数都作为 nil 传递,额外的参数会被静默丢弃。示例
foo(1)
-- ==== Result ====
-- A: 1
-- B: nil
kwargs
调用函数时,如果函数正好接受一个字符串字面量 ("foo") 或表字面量 ({1,2,3}),则可以省略括号。后者经常用于模拟“命名参数”(“kwargs”或“关键字参数”),就像 Python 和 C# 等语言一样。示例
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" }
这里没有什么特别之处,只是隐式地添加了括号。但是从视觉上看,这种微不足道的语法糖已经相当接近“关键字参数”接口。
lua-regex
Lua 故意不支持正则表达式,而是提供有限的 lua-patterns,以避免扩展正则表达式带来的性能问题。Lua 脚本也可以通过 vim.regex() 使用 Vim 正则表达式。
示例
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

导入 Lua 模块 lua-module-load

'runtimepath' 中指定的目录下搜索模块,按照它们出现的顺序进行搜索。模块名称中的任何“.”都将被视为目录分隔符,用于搜索。对于模块 foo.bar,每个目录都将搜索 lua/foo/bar.lua,然后搜索 lua/foo/bar/init.lua。如果未找到任何文件,则再次搜索这些目录以查找与 lua/foo/bar.? 匹配的共享库,其中 ? 是从 package.cpath 的初始值派生的后缀列表(例如 sodll)。如果仍然找不到任何文件,Nvim 将回退到 Lua 的默认搜索机制。找到的第一个脚本将被运行,require() 将返回脚本返回的值(如果有),否则返回 true
在对每个模块的第一个 require() 调用后,返回值将被缓存,后续的调用将返回缓存的值,而无需搜索或执行任何脚本。有关更多详细信息,请参阅 require()
例如,如果 'runtimepath'foo,bar 并且 package.cpath 在启动时是 ./?.so;./?.dll,则 require('mod') 会按顺序搜索这些路径并加载找到的第一个模块(“先找到的优先”)。
foo/lua/mod.lua
foo/lua/mod/init.lua
bar/lua/mod.lua
bar/lua/mod/init.lua
foo/lua/mod.so
foo/lua/mod.dll
bar/lua/mod.so
bar/lua/mod.dll
lua-package-path
Nvim 会根据有效的 'runtimepath' 值自动调整 package.pathpackage.cpath。调整将在每次更改 'runtimepath' 时发生。package.path 通过简单地将 /lua/?.lua/lua/?/init.lua 附加到 'runtimepath' 中的每个目录来进行调整(/ 实际上是 package.config 的第一个字符)。
package.path 类似,来自 'runtimepath' 的修改后的目录也会被添加到 package.cpath 中。在这种情况下,不是将 /lua/?.lua/lua/?/init.lua 附加到每个 runtimepath,而是使用现有 package.cpath 中所有唯一的包含 ? 的后缀。示例
1. 假设
'runtimepath' 包含 /foo/bar,/xxx;yyy/baz,/abc
初始 package.cpath(在编译时定义或从 $LUA_CPATH / $LUA_INIT 派生)包含 ./?.so;/def/ghi/a?d/j/g.elf;/def/?.so
2. 它按顺序找到包含 ? 的后缀 /?.so/a?d/j/g.elf/?.so:从第一个包含问号且在路径分隔符之前的路径组件开始的路径部分。
3. /def/?.so 的后缀,即 /?.so 不是唯一的,因为它与 package.path 中的第一个路径的后缀相同(即 ./?.so)。这留下了 /?.so/a?d/j/g.elf,按此顺序排列。
4. 'runtimepath' 有三条路径:/foo/bar/xxx;yyy/baz/abc。第二个包含一个分号,它是一个路径分隔符,所以它被排除在外,只留下 /foo/bar/abc,按此顺序排列。
5. 从 4. 中的路径和从 3. 中的后缀组成的笛卡尔积。在每个变体中,在路径和后缀之间插入一个 /lua 路径段,留下
/foo/bar/lua/?.so
/foo/bar/lua/a?d/j/g.elf
/abc/lua/?.so
/abc/lua/a?d/j/g.elf
6. 新路径被预先添加到原始 package.cpath 中。
结果将如下所示
/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
注意
为了跟踪 'runtimepath' 的更新,在之前的更新中添加的路径会被记住,并在下一次更新中删除,而所有从新的 'runtimepath' 派生的路径都会按照上述方式预先添加。这允许在从 'runtimepath' 中删除路径时删除路径,在添加路径时添加路径,以及如果 'runtimepath' 被重新排序,则重新排序 package.path/|package.cpath| 的内容。
虽然调整会自动发生,但 Nvim 不会跟踪 package.pathpackage.cpath 的当前值。如果您碰巧从中删除了一些路径,可以设置 'runtimepath' 来触发更新。
let &runtimepath = &runtimepath
跳过 'runtimepath' 中包含分号的路径,这适用于 package.pathpackage.cpath。鉴于有些使用 shell 的编写不好的插件无法使用包含分号的路径,因此最好不要在 'runtimepath' 中包含它们。

命令 lua-commands

这些命令从命令行 (:lua:luado) 或给定行 [范围] 的文件中执行 Lua 代码块。和 Lua 中一样,每个代码块都有自己的作用域(闭包),因此只有全局变量在命令调用之间共享。 lua-stdlib 模块、用户模块以及 package.path 上的任何其他内容都可用。
Lua 的 print() 函数将它的输出重定向到 Nvim 的消息区域,参数使用“ ”(空格)而不是“\t”(制表符)分隔。
:lua= :lua :lua {chunk} 执行 Lua 代码块 {chunk}。如果 {chunk} 以 "=" 开头,则代码块的其余部分将被评估为表达式并打印。:lua =expr:=expr 等同于 :lua vim.print(expr)
示例
:lua vim.api.nvim_command('echo "Hello, Nvim!"')
查看 Lua 版本
:lua print(_VERSION)
查看 LuaJIT 版本
:lua =jit.version
:{range}lua 将缓冲区中 {range} 行范围内的代码作为 Lua 代码执行。与 :source 不同,此命令始终将这些行视为 Lua 代码。
示例:选择以下代码并键入 ":lua<Enter>" 执行它
print(string.format(
    'unix time: %s', os.time()))
:lua-heredoc
:lua << [trim] [{endmarker}] {script} {endmarker} 在 Vimscript 中执行 Lua 脚本 {script}。您可以在 "<<" 后省略 [endmarker] 并使用 {script} 后面的点 "."(类似于 :append:insert)。有关更多信息,请参阅 :let-heredoc
示例
function! CurrentLineInfo()
lua << EOF
local linenr = vim.api.nvim_win_get_cursor(0)[1]
local curline = vim.api.nvim_buf_get_lines(0, linenr - 1, linenr, false)[1]
print(string.format('Line [%d] has %d bytes', linenr, #curline))
EOF
endfunction
请注意,local 变量在代码块结束时将消失,但全局变量不会消失。
:luado
:[range]luado {body} 对于缓冲区中 [range] 行范围内的每一行,执行 Lua 代码块 "function(line, linenr) {body} end",其中 line 是当前行文本(不包含 <EOL>),linenr 是当前行号。如果函数返回字符串,该字符串将成为对应缓冲区行的文本。默认 [range] 是整个文件:"1,$"。
示例
: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
:luafile {file} 执行 {file} 中的 Lua 脚本。整个参数将用作文件名(类似于 :edit),空格无需转义。或者,您可以 :source Lua 文件。
示例
:luafile script.lua
:luafile %

luaeval() lua-eval

用于将 Lua 值传递到 Nvim 的 "vim.eval" 的(双重)等效项是 "luaeval"。"luaeval" 接受一个表达式字符串和一个可选参数,用于在表达式中使用 _A,并返回表达式的结果。在 Lua 中,它在语义上等效于
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 中的 nil、数字、字符串、表和布尔值将转换为它们各自的 Vimscript 类型。如果 Lua 字符串包含 NUL 字节,它将被转换为 Blob。转换其他 Lua 类型会导致错误。
魔术全局变量 "_A" 包含 luaeval() 的第二个参数。
示例
:echo luaeval('_A[1] + _A[2]', [40, 2])
" 42
:echo luaeval('string.match(_A, "[a-z]+")', 'XYXfoo123')
" foo
lua-table-ambiguous
Lua 表既用作字典又用作列表,因此无法确定空表是列表还是字典。此外,Lua 没有整数。为了消除这些歧义,我们定义:lua-list
0. 空表是列表。使用 vim.empty_dict() 来表示空字典。1. 具有 N 个连续(没有 nil 值,即“空洞”)整数键 1…N 的表是列表。另请参阅 list-iteratorlua-dict
2. 具有字符串键且没有一个包含 NUL 字节的表是字典。3. 具有字符串键且至少有一个包含 NUL 字节的表也被认为是字典,但这一次它被转换为 msgpack-special-maplua-special-tbl
4. 具有 vim.type_idx 键的表可能是字典、列表或浮点数
{[vim.type_idx]=vim.types.float, [vim.val_idx]=1} 被转换为浮点数 1.0。请注意,默认情况下,整数 Lua 数字被转换为 Number,非整数被转换为 Float。此变体允许整数 Float
{[vim.type_idx]=vim.types.dictionary} 被转换为一个空字典,{[vim.type_idx]=vim.types.dictionary, [42]=1, a=2} 被转换为一个字典 {'a': 42}:非字符串键将被忽略。如果没有 vim.type_idx 键,则具有不符合 1.、2. 或 3. 的键的表将导致错误。
{[vim.type_idx]=vim.types.array} 被转换为一个空列表。以及 {[vim.type_idx]=vim.types.array, [42]=1}:不构成从 1 到 N 的一步序列的整数键将被忽略,所有非整数键也将被忽略。
示例
: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)
注意:luaeval 的第二个参数将从 Vimscript 转换为 Lua,因此对 Lua 容器的更改不会影响 Vimscript 中的值。返回值也总是被转换。转换时,msgpack-special-dict 将被特殊处理。

Vimscript v:lua 接口 v:lua-call

在 Vimscript 中,可以使用特殊的 v:lua 前缀调用 Lua 函数,这些函数是全局的或可以通过全局表访问。表达式
call v:lua.func(arg1, arg2)
等同于 Lua 代码块
return func(...)
其中参数被转换为 Lua 值。表达式
call v:lua.somemod.func(args)
等同于 Lua 代码块
return somemod.func(...)
此外,可以像这样访问包的函数
call v:lua.require'mypack'.func(arg1, arg2)
call v:lua.require'mypack.submod'.func(arg1, arg2)
注意:只允许单引号形式,没有括号。使用 require"mypack"require('mypack') 作为前缀不起作用(后者仍然有效,因为它本身的函数调用,以防 require 返回有用的值)。
v:lua 前缀可用于将 Lua 函数作为 方法 调用。例如
:eval arg1->v:lua.somemod.func(arg2)
您可以在 "func" 选项中使用 v:lua,例如 'tagfunc''omnifunc' 等。例如,考虑以下 Lua omnifunc 处理程序
function mymod.omnifunc(findstart, base)
  if findstart == 1 then
    return 0
  else
    return {'stuff', 'steam', 'strange things'}
  end
end
vim.bo[buf].omnifunc = 'v:lua.mymod.omnifunc'
注意:该模块(在上面的示例中为 "mymod")必须是 Lua 全局变量,或者使用 require()(如上所示)从包中访问它。
注意:在 Vimscript 表达式中不允许使用不带调用的 v:luaFuncref 无法表示 Lua 函数。以下操作会导致错误
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 标准模块 lua-stdlib

Nvim Lua "标准库"(stdlib)是 vim 模块,它公开各种函数和子模块。它始终被加载,因此 require("vim") 是不必要的。
您可以查看模块属性
:lua vim.print(vim)
结果类似于以下内容
{
  _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>,
  ...
}
要查找有关例如 "deepcopy" 函数的文档
:help vim.deepcopy()
请注意,以下划线开头的函数(例如 "_os_proc_children")是内部的/私有的,插件不得使用它们。

VIM.UV lua-loop vim.uv

vim.uv 公开用于 Nvim 使用的 libUV 库的 "luv" Lua 绑定,用于网络、文件系统和进程管理,请参阅 luvref.txt。特别是,它允许与主 Nvim luv-event-loop 交互。
E5560 lua-loop-callbacksvim.uv 回调中直接调用 vim.api 函数(除了 api-fast)会导致错误。例如,以下操作会导致错误
local timer = vim.uv.new_timer()
timer:start(1000, 0, function()
  vim.api.nvim_command('echomsg "test"')
end)
要避免错误,请使用 vim.schedule_wrap() 推迟回调
local timer = vim.uv.new_timer()
timer:start(1000, 0, vim.schedule_wrap(function()
  vim.api.nvim_command('echomsg "test"')
end))
(对于一次性计时器,请参阅 vim.defer_fn(),它会自动添加包装。)
示例:重复计时器 1. 将此代码保存到文件中。2. 使用 ":luafile %" 执行它。
-- Create a timer handle (implementation detail: uv_timer_t).
local timer = vim.uv.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');
示例:文件更改检测 watch-file
1. 将此代码保存到文件中。2. 使用 ":luafile %" 执行它。3. 使用 ":Watch %" 监视任何文件。4. 尝试使用另一个文本编辑器编辑该文件。5. 观察 Nvim 中的文件是否重新加载(因为 on_change() 调用 :checktime)。
local w = vim.uv.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>'))")
inotify-limitations
在 Linux 上,您可能需要增加 inotify 监视和排队事件的最大数量,因为默认限制可能过低。要增加限制,请运行
sysctl fs.inotify.max_user_watches=494462
这将把限制增加到 494462 个监视和排队事件。这些行可以添加到 /etc/sysctl.conf 中以使更改持久化。
请注意,每个监视都是内核中的一个结构,因此可用内存也是使用 inotify 的瓶颈。实际上,一个监视可能占用高达 1KB 的空间。这意味着一百万个监视可能会导致额外使用 1GB 的 RAM。
示例:TCP 回声服务器 tcp-server
1. 将此代码保存到文件中。2. 使用 ":luafile %" 执行它。3. 注意端口号。4. 从任何 TCP 客户端连接(例如 "nc 0.0.0.0 36795")
local function create_server(host, port, on_connect)
  local server = vim.uv.new_tcp()
  server:bind(host, port)
  server:listen(128, function(err)
    assert(not err, err)  -- Check for errors.
    local sock = vim.uv.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)
插件可以使用 luv 中的多线程 API(例如 vim.uv.new_thread)在单独的(操作系统级别)线程中执行工作。请注意,每个线程都获得它自己的单独 Lua 解释器状态,无法访问主线程中的 Lua 全局变量。编辑器状态(缓冲区、窗口等)也不能直接从线程中访问。
vim.* API 的一个子集在线程中可用。这包括
vim.uv,每个线程都有一个单独的事件循环。
vim.mpackvim.json(用于在线程之间序列化消息)
线程中的 require 可以使用全局 package.path 中的 Lua 包
print()vim.inspect
vim.diff
vim.* 中的大多数实用程序函数,用于处理纯 Lua 值,例如 vim.splitvim.tbl_*vim.list_* 等等。
vim.is_thread() 从非主线程返回 true。

VIM.HL vim.hl

vim.hl.on_yank({opts}) vim.hl.on_yank()
TextYankPost 事件期间突出显示被粘贴的文本。
将以下内容添加到您的 init.vim
autocmd TextYankPost * silent! lua vim.hl.on_yank {higroup='Visual', timeout=300}
参数
{opts} (table?) 可选参数
higroup 被粘贴区域的突出显示组(默认值为 "IncSearch")
timeout 突出显示清除之前的毫秒数(默认值为 150)
on_macro 执行宏时突出显示(默认值为 false)
on_visual 粘贴视觉选择时突出显示(默认值为 true)
event 事件结构(默认值为 vim.v.event)
priority 整数优先级(默认值为 vim.hl.priorities.user
vim.hl.priorities vim.hl.priorities
包含用于突出显示的默认优先级的表
syntax: 50,用于标准语法突出显示
treesitter: 100,用于基于 treesitter 的突出显示
semantic_tokens: 125,用于 LSP 语义标记突出显示
diagnostics: 150,用于代码分析,例如诊断
user: 200,用于用户触发的突出显示,例如 LSP 文档符号或 on_yank 自动命令
vim.hl.range()
vim.hl.range({bufnr}, {ns}, {higroup}, {start}, {finish}, {opts}) 将突出显示组应用于文本范围。
参数
{bufnr} (integer) 要应用突出显示的缓冲区编号
{ns} (integer) 要添加突出显示的命名空间
{higroup} (string) 用于突出显示的突出显示组
{start} (integer[]|string) 区域的起点,作为 (行,列) 元组或 getpos() 接受的字符串
{finish} (integer[]|string) 区域的终点,作为 (行,列) 元组或 getpos() 接受的字符串
{opts} (table?) 包含以下字段的表
{regtype} (string, default: 'v' i.e. charwise) 范围的类型。请参阅 getregtype()
{inclusive} (boolean, default: false) 指示范围是否为端点包含
{priority} (integer, default: vim.hl.priorities.user) 突出显示优先级

VIM.DIFF vim.diff

vim.diff({a}, {b}, {opts}) vim.diff()
对字符串 {a}{b} 运行 diff。此函数直接或通过回调参数返回的任何索引都是 1 为基数的。
示例
vim.diff('a\n', 'b\nc\n')
-- =>
-- @@ -1 +1,2 @@
-- -a
-- +b
-- +c
vim.diff('a\n', 'b\nc\n', {result_type = 'indices'})
-- =>
-- {
--   {1, 1, 1, 2}
-- }
参数
{a} (string) 要比较的第一个字符串
{b} (string) 要比较的第二个字符串
{opts} (table?) 可选参数
{on_hunk} (fun(start_a: integer, count_a: integer, start_b: integer, count_b: integer): integer?) 针对 diff 中的每个 hunk 调用。返回一个负数来取消对任何剩余 hunk 的回调。参数
start_a (integer): {a} 中 hunk 的起始行。
count_a (integer): {a} 中 hunk 的大小。
start_b (integer): {b} 中 hunk 的起始行。
count_b (integer): {b} 中 hunk 的大小。
{result_type} ('unified'|'indices', 默认: 'unified') 返回的 diff 的形式
unified: 统一格式的字符串。
indices: hunk 位置的数组。 注意: 如果使用 on_hunk,则会忽略此选项。
{linematch} (boolean|integer) 对来自 xdiff 的结果 hunk 运行 linematch。如果为整数,则只对行数不超过此大小的 hunk 运行 linematch。需要 result_type = indices,否则会忽略。
{algorithm} ('myers'|'minimal'|'patience'|'histogram', 默认: 'myers') 要使用的 diff 算法。值
myers: 默认算法
minimal: 花费额外时间生成尽可能小的 diff
patience: patience diff 算法
histogram: histogram diff 算法
{ctxlen} (integer) 上下文长度
{interhunkctxlen} (integer) hunk 间上下文长度
{ignore_whitespace} (boolean) 忽略空白
{ignore_whitespace_change} (boolean) 忽略空白变化
{ignore_whitespace_change_at_eol} (boolean) 忽略行尾的空白变化。
{ignore_cr_at_eol} (boolean) 忽略行尾的回车符
{ignore_blank_lines} (boolean) 忽略空行
{indent_heuristic} (boolean) 对内部 diff 库使用缩进启发式方法。
返回
(string|integer[][]?) 查看 {opts.result_type}。如果给出了 {opts.on_hunk},则为 nil

VIM.MPACK vim.mpack

此模块提供 Lua 对象与 msgpack 编码字符串之间的编码和解码功能。支持 vim.NILvim.empty_dict()
vim.mpack.decode({str}) vim.mpack.decode()
将 msgpack 编码的 {str} 解码(或“解包”)为 Lua 对象。
参数
{str} (string)
返回
(any)
vim.mpack.encode({obj}) vim.mpack.encode()
将 Lua 对象 {obj} 编码(或“打包”)为 msgpack,并将结果存储在 Lua 字符串中。
参数
{obj} (any)
返回
(string)

VIM.JSON vim.json

此模块提供 Lua 对象与 JSON 编码字符串之间的编码和解码功能。支持 vim.NILvim.empty_dict()
vim.json.decode({str}, {opts}) vim.json.decode()
将 JSON 编码的 {str} 解码(或“解包”)为 Lua 对象。
将 JSON 中的 "null" 解码为 vim.NIL(可由 {opts} 控制,见下文)。
将空对象解码为 vim.empty_dict()
将空数组解码为 {}(空的 Lua 表)。
示例
vim.print(vim.json.decode('{"bar":[],"foo":{},"zub":null}'))
-- { bar = {}, foo = vim.empty_dict(), zub = vim.NIL }
参数
{str} (string) 字符串化的 JSON 数据。
{opts} (table<string,any>?) 选项表,包含键
luanil: (table) 表包含键
object: (boolean) 当为真时,将 JSON 对象中的 null 转换为 Lua nil,而不是 vim.NIL
array: (boolean) 当为真时,将 JSON 数组中的 null 转换为 Lua nil,而不是 vim.NIL
返回
(any)
vim.json.encode({obj}) vim.json.encode()
将 Lua 对象 {obj} 编码(或“打包”)为 JSON,并将结果存储在 Lua 字符串中。
参数
{obj} (any)
返回
(string)

VIM.BASE64 vim.base64

vim.base64.decode({str}) vim.base64.decode()
解码 Base64 编码的字符串。
参数
{str} (string) Base64 编码的字符串
返回
(string) 解码后的字符串
vim.base64.encode({str}) vim.base64.encode()
使用 Base64 编码 {str}
参数
{str} (string) 要编码的字符串
返回
(string) 编码后的字符串

VIM.SPELL vim.spell

vim.spell.check({str}) vim.spell.check()
检查 {str} 中是否存在拼写错误。类似于 Vimscript 函数 spellbadword()
注意: 此函数的行为取决于: 'spelllang''spellfile''spellcapcheck''spelloptions',这些选项都可能在缓冲区内是局部的。考虑使用 nvim_buf_call() 调用此函数。
示例
vim.spell.check("the quik brown fox")
-- =>
-- {
--     {'quik', 'bad', 5}
-- }
参数
{str} (string)
返回
([string, 'bad'|'rare'|'local'|'caps', integer][]) 包含三个项目的元组列表
拼写错误的单词。
拼写错误的类型: "bad" 拼写错误 "rare" 罕见词 "local" 仅在其他区域有效的词 "caps" 单词应该以大写字母开头
{str} 中单词开始的位置。
vim.api.{func}({...}) vim.api
使用参数 {...} 调用 Nvim API 函数 {func}。示例: 调用 "nvim_get_current_line()" API 函数
print(tostring(vim.api.nvim_get_current_line()))
vim.NIL vim.NIL
代表 RPC 中的 NIL 和 Vimscript 转换中的 v:null 的特殊值,以及类似的情况。 Lua nil 不能用作代表字典或数组的 Lua 表的一部分,因为它被视为缺失: {"foo", nil}{"foo"} 相同。
vim.type_idx vim.type_idx
用于 lua-special-tbl 的类型索引。指定 vim.types 中的值之一可以对空表进行类型化(不清楚空的 Lua 表是代表空列表还是空数组)并将整数强制转换为 Float。有关更多详细信息,请参阅 lua-special-tbl
vim.val_idx vim.val_idx
代表 Float 的表的数值索引。代表浮点数 1.0 的表如下所示
{
  [vim.type_idx] = vim.types.float,
  [vim.val_idx] = 1.0,
}
另请参阅 vim.type_idxlua-special-tbl
vim.types vim.types
包含 vim.type_idx 可能值的表。包含两组键值对: 第一组将 vim.type_idx 的可能值映射到人类可读的字符串,第二组将人类可读的类型名称映射到 vim.type_idx 的值。当前包含 floatarraydictionary 类型的键值对。
注意: 必须预期与 vim.types.floatvim.types.arrayvim.types.dictionary 相对应的值只遵循以下两个假设: 1. 值可以在表中同时用作键和值。考虑到 Lua 表的属性,这基本上意味着“值不是 nil”。 2. 对于 vim.types 表中的每个值 vim.types[vim.types[value]]value 相同。对类型没有其他限制,不能保证与 vim.types.floatvim.types.arrayvim.types.dictionary 相对应的值不会改变,或者 vim.types 表只会包含这三种类型的值。
log_levels vim.log.levels 日志级别是 vim.log.levels 中定义的值之一
vim.log.levels.DEBUG vim.log.levels.ERROR vim.log.levels.INFO vim.log.levels.TRACE vim.log.levels.WARN vim.log.levels.OFF
vim.empty_dict() vim.empty_dict()
创建一个特殊的空表(使用元表标记),Nvim 在将 Lua 值转换为 Vimscript 或 API 类型时将其转换为空字典。默认情况下,Nvim 将没有此元表的空表 {} 转换为列表/数组。
注意: 如果表中存在数字键,Nvim 会忽略元表标记,并将字典转换为列表/数组。
返回
(table)
vim.iconv({str}, {from}, {to}) vim.iconv()
结果是一个字符串,它是将文本 {str} 从编码 {from} 转换为编码 {to} 的结果。如果转换失败,则返回 nil。如果某些字符无法转换,则用 "?" 替换它们。编码名称是 iconv() 库函数可以接受的任何名称,请参阅 ":Man 3 iconv"。
参数
{str} (string) 要转换的文本
{from} (string) {str} 的编码
{to} (string) 目标编码
返回
(string?) 如果转换成功,则为转换后的字符串,否则为 nil
vim.in_fast_event() vim.in_fast_event()
如果代码正在“快速”事件处理程序中执行,则返回 true,在“快速”事件处理程序中,大多数 API 都被禁用。这些是低级事件(例如 lua-loop-callbacks),可以在 Nvim 轮询输入时随时调用。当此值为 false 时,大多数 API 函数都可以调用(但可能受到其他限制,例如 textlock)。
vim.rpcnotify({channel}, {method}, {...}) vim.rpcnotify()
通过 RPC{event} 发送到 {channel},并立即返回。如果 {channel} 为 0,则将事件广播到所有频道。
此函数也在快速回调 lua-loop-callbacks 中有效。
参数
{channel} (integer)
{method} (string)
{...} (any?)
vim.rpcrequest({channel}, {method}, {...}) vim.rpcrequest()
通过 RPC 发送请求到 {channel} 以调用 {method},并在收到响应之前阻塞。
注意: 返回值中的 NIL 值用 vim.NIL 特殊值表示
参数
{channel} (integer)
{method} (string)
{...} (any?)
vim.schedule({fn}) vim.schedule()
安排 {fn} 尽快由主事件循环调用。这对于避免 textlock 或其他临时限制很有用。
参数
{fn} (fun())
vim.str_utf_end({str}, {index}) vim.str_utf_end()
获取 {index} 指向的代码点(字符)的最后一个字节与该位置之间的距离(以字节为单位)。
示例
-- The character 'æ' is stored as the bytes '\xc3\xa6' (using UTF-8)
-- Returns 0 because the index is pointing at the last byte of a character
vim.str_utf_end('æ', 2)
-- Returns 1 because the index is pointing at the penultimate byte of a character
vim.str_utf_end('æ', 1)
参数
{str} (string)
{index} (integer)
返回
(integer)
vim.str_utf_pos({str}) vim.str_utf_pos()
获取给定字符串中每个 UTF-8 代码点的起始字节位置列表。
嵌入的 NUL 字节被视为字符串的终止符。
参数
{str} (string)
返回
(integer[])
vim.str_utf_start({str}, {index}) vim.str_utf_start()
获取代码点(字符)的起始字节与 {index} 指向的代码点(字符)的起始字节之间的距离(以字节为单位)。
结果可以加到 {index} 上,得到字符的起始字节。
示例
-- The character 'æ' is stored as the bytes '\xc3\xa6' (using UTF-8)
-- Returns 0 because the index is pointing at the first byte of a character
vim.str_utf_start('æ', 1)
-- Returns -1 because the index is pointing at the second byte of a character
vim.str_utf_start('æ', 2)
参数
{str} (string)
{index} (integer)
返回
(integer)
vim.stricmp({a}, {b}) vim.stricmp()
不区分大小写地比较字符串。
参数
{a} (string)
{b} (string)
返回
(0|1|-1) 分别表示字符串相等,{a} 大于 {b}{a} 小于 {b}
vim.ui_attach({ns}, {options}, {callback}) vim.ui_attach()
警告: 此功能处于实验/不稳定状态。
连接到 ui-events,类似于 nvim_ui_attach(),但接收事件作为 Lua 回调。可用于在 Lua 中实现弹出菜单或消息处理等屏幕元素。
{options} 应为类似字典的表,其中 ext_... 选项应设置为 true 以接收相应外部元素的事件。
{callback} 接收事件名称以及其他参数。请参阅 ui-popupmenu 以及以下部分,了解相应事件的事件格式。
警告: 此 API 被认为是实验性的。可用性将因不同的屏幕元素而异。特别是 ext_messages 的行为可能会发生进一步变化和可用性改进。预计这将用于在将 'cmdheight' 设置为零(同样是实验性的)时处理消息。
示例(ui-popupmenu 实现的存根)
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")
  end
end)
参数
{ns} (integer)
{options} (table<string, any>)
{callback} (fun())
vim.ui_detach({ns}) vim.ui_detach()
分离之前使用 vim.ui_attach() 为给定命名空间 {ns} 连接的回调。
参数
{ns} (integer)
vim.wait({time}, {callback}, {interval}, {fast_only}) vim.wait()
等待 {time} 毫秒,直到 {callback} 返回 true
立即执行 {callback},并在大约 {interval} 毫秒(默认 200)后执行。在此期间,Nvim 仍然处理其他事件。
不能在 api-fast 事件中调用。
示例
---
-- 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
参数
{time} (integer) 等待的毫秒数
{callback} (fun(): boolean?) 可选回调。等待 {callback} 返回 true
{interval} (integer?) 轮询之间等待的(近似)毫秒数
{fast_only} (boolean?) 如果为 true,则只处理 api-fast 事件。
返回(多个)
(boolean) (-1|-2?)
如果 {callback}{time} 内返回 truetrue, nil
如果 {callback}{time} 内从未返回 truefalse, -1
如果 {callback}{time} 内被打断:false, -2
如果 {callback} 出现错误,则会抛出该错误。

LUA-VIMSCRIPT 桥接 lua-vimscript

Nvim Lua 提供了与 Vimscript 变量和函数以及编辑器命令和选项的接口或“桥接”。
通过此桥接传递的对象会被复制(封送):没有“引用”。lua-guide-variables 例如,在 Lua 列表上使用 vim.fn.remove() 会将列表对象复制到 Vimscript,而不会修改 Lua 列表。
local list = { 1, 2, 3 }
vim.fn.remove(list, 0)
vim.print(list)  --> "{ 1, 2, 3 }"
vim.call({func}, {...}) vim.call()
使用参数 {...} 调用 vim-functionuser-function {func}。另请参阅 vim.fn。等效于
vim.fn[func]({...})
vim.cmd({command}) 请参阅 vim.cmd()
vim.fn.{func}({...}) vim.fn
使用参数 {...} 调用 vim-functionuser-function {func}。要调用自动加载函数,请使用语法
vim.fn['some#function']({...})
与 vim.api.|nvim_call_function()| 不同,它直接在 Vim 对象和 Lua 对象之间转换。如果 Vim 函数返回一个浮点数,它将直接表示为 Lua 数字。空列表和字典都表示为空表。
注意: 返回值中包含的 v:null 值将表示为 vim.NIL 特殊值。
注意: vim.fn 密钥是延迟生成的,因此 pairs(vim.fn) 仅枚举至少调用过一次的函数。
注意: 大多数函数不能在 api-fast 回调中运行,但有一些未记录的例外情况是允许的。
lua-vim-variables
Vim 编辑器全局字典 g: w: b: t: v: 可以通过引用下面描述的 vim.* Lua 表从 Lua 方便地和惯用地访问。这样,您可以轻松地从 Lua 读取和修改全局 Vimscript 变量。
示例
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.b[2].foo = 6  -- Set b:foo for buffer 2
请注意,直接设置字典字段不会将它们写回 Nvim。这是因为对命名空间的索引只返回一个副本。相反,必须将整个字典作为一个整体写入。这可以通过创建一个短暂的临时变量来实现。
示例
vim.g.my_dict.field1 = 'value'  -- Does not work
local my_dict = vim.g.my_dict   --
my_dict.field1 = 'value'        -- Instead do
vim.g.my_dict = my_dict         --
vim.g vim.g
全局 (g:) 编辑器变量。没有值的键返回 nil
vim.b vim.b
缓冲区范围 (b:) 变量,适用于当前缓冲区。无效或未设置的键返回 nil。可以使用整数索引来访问特定缓冲区的变量。
vim.w vim.w
窗口范围 (w:) 变量,适用于当前窗口。无效或未设置的键返回 nil。可以使用整数索引来访问特定窗口的变量。
vim.t vim.t
标签页范围 (t:) 变量,适用于当前标签页。无效或未设置的键返回 nil。可以使用整数索引来访问特定标签页的变量。
vim.v vim.v
v: 变量。无效或未设置的键返回 nil
Vim 选项可以通过 vim.o 访问,其行为类似于 Vimscript 的 :set
示例
要设置布尔值切换:Vimscript:set number Lua:vim.o.number = true
要设置字符串值:Vimscript:set wildignore=*.o,*.a,__pycache__ Lua:vim.o.wildignore = '*.o,*.a,__pycache__'
类似地,还有 vim.bovim.wo,用于设置缓冲区范围和窗口范围的选项。请注意,这不能与 local-options:setlocal 混淆。还有 vim.go,它只访问 全局局部 选项的全局值,请参阅 :setglobal
有一个特殊的接口 vim.opt,它允许您从 Lua 方便地与列表式和映射式选项进行交互:它允许您将它们作为 Lua 表访问,并提供面向对象的添加和删除条目方法。
示例
以下设置列表式选项的方法是等效的:在 Vimscript 中
set wildignore=*.o,*.a,__pycache__
在 Lua 中使用 vim.o
vim.o.wildignore = '*.o,*.a,__pycache__'
在 Lua 中使用 vim.opt
vim.opt.wildignore = { '*.o', '*.a', '__pycache__' }
要复制 :set+= 的行为,请使用
vim.opt.wildignore:append { "*.pyc", "node_modules" }
要复制 :set^= 的行为,请使用
vim.opt.wildignore:prepend { "new_first_value" }
要复制 :set-= 的行为,请使用
vim.opt.wildignore:remove { "node_modules" }
以下设置映射式选项的方法是等效的:在 Vimscript 中
set listchars=space:_,tab:>~
在 Lua 中使用 vim.o
vim.o.listchars = 'space:_,tab:>~'
在 Lua 中使用 vim.opt
vim.opt.listchars = { space = '_', tab = '>~' }
请注意,vim.opt 返回一个 Option 对象,而不是选项的值,该值可以通过 vim.opt:get() 访问。
示例
以下获取列表式选项的方法是等效的:在 Vimscript 中
echo wildignore
在 Lua 中使用 vim.o
print(vim.o.wildignore)
在 Lua 中使用 vim.opt
vim.print(vim.opt.wildignore:get())
在上述任何示例中,要复制 :setlocal 的行为,请使用 vim.opt_local。此外,要复制 :setglobal 的行为,请使用 vim.opt_global
Option:append({value}) vim.opt:append()
将值追加到字符串式选项。请参阅 :set+=
这些是等效的
vim.opt.formatoptions:append('j')
vim.opt.formatoptions = vim.opt.formatoptions + 'j'
参数
{value} (string) 要追加的值
Option:get() vim.opt:get()
返回选项的 Lua 表示形式。布尔值、数字和字符串值将以完全相同的方式返回。
对于逗号分隔列表的值,将返回一个数组,其中值作为数组中的条目。
vim.cmd [[set wildignore=*.pyc,*.o]]
vim.print(vim.opt.wildignore:get())
-- { "*.pyc", "*.o", }
for _, ignore_pattern in ipairs(vim.opt.wildignore:get()) do
    print("Will ignore:", ignore_pattern)
end
-- Will ignore: *.pyc
-- Will ignore: *.o
对于逗号分隔映射的值,将返回一个表,其中名称作为键,值作为条目。
vim.cmd [[set listchars=space:_,tab:>~]]
vim.print(vim.opt.listchars:get())
--  { space = "_", tab = ">~", }
for char, representation in pairs(vim.opt.listchars:get()) do
    print(char, "=>", representation)
end
对于标记列表的值,将返回一个集合,其中标记作为键,true 作为条目。
vim.cmd [[set formatoptions=njtcroql]]
vim.print(vim.opt.formatoptions:get())
-- { n = true, j = true, c = true, ... }
local format_opts = vim.opt.formatoptions:get()
if format_opts.j then
    print("J is enabled!")
end
返回
(string|integer|boolean?) 选项的值
Option:prepend({value}) vim.opt:prepend()
将值前置到字符串式选项。请参阅 :set^=
这些是等效的
vim.opt.wildignore:prepend('*.o')
vim.opt.wildignore = vim.opt.wildignore ^ '*.o'
参数
{value} (string) 要前置的值
Option:remove({value}) vim.opt:remove()
从字符串式选项中删除一个值。请参阅 :set-=
这些是等效的
vim.opt.wildignore:remove('*.pyc')
vim.opt.wildignore = vim.opt.wildignore - '*.pyc'
参数
{value} (string) 要删除的值
vim.bo[{bufnr}] vim.bo
获取或设置编号为 {bufnr} 的缓冲区的缓冲区范围 选项。类似于 :setlocal。如果省略 {bufnr},则使用当前缓冲区。无效的 {bufnr} 或键是错误。
示例
local bufnr = vim.api.nvim_get_current_buf()
vim.bo[bufnr].buflisted = true    -- same as vim.bo.buflisted = true
print(vim.bo.comments)
print(vim.bo.baz)                 -- error: invalid key
vim.env vim.env
在编辑器会话中定义的环境变量。请参阅 expand-env:let-environment,了解 Vimscript 的行为。无效或未设置的键返回 nil
示例
vim.env.FOO = 'bar'
print(vim.env.TERM)
vim.go vim.go
获取或设置全局 选项。类似于 :setglobal。无效的键是错误。
注意: 这与 vim.o 不同,因为这会访问全局选项值,因此主要用于 全局局部 选项。
示例
vim.go.cmdheight = 4
print(vim.go.columns)
print(vim.go.bar)     -- error: invalid key
vim.o vim.o
获取或设置 选项。类似于 :set。无效的键是错误。
注意: 这适用于使用当前缓冲区和窗口的缓冲区范围和窗口范围选项。
示例
vim.o.cmdheight = 4
print(vim.o.columns)
print(vim.o.foo)     -- error: invalid key
vim.wo[{winid}][{bufnr}] vim.wo
获取或设置具有句柄 {winid} 的窗口和编号为 {bufnr} 的缓冲区的窗口范围 选项。如果设置 全局局部 选项或提供 {bufnr},则类似于 :setlocal,否则类似于 :set。如果省略 {winid},则使用当前窗口。无效的 {winid}{bufnr} 或键是错误。
注意: 只支持值为 0{bufnr}(窗口中的当前缓冲区)。
示例
local winid = vim.api.nvim_get_current_win()
vim.wo[winid].number = true    -- same as vim.wo.number = true
print(vim.wo.foldmarker)
print(vim.wo.quux)             -- error: invalid key
vim.wo[winid][0].spell = false -- like ':setlocal nospell'

Lua 模块:vim lua-vim

vim.cmd({command}) vim.cmd()
执行 Vim 脚本命令。
请注意,vim.cmd 可以使用命令名称索引,返回该命令的可调用函数。
示例
vim.cmd('echo 42')
vim.cmd([[
  augroup My_group
    autocmd!
    autocmd FileType c setlocal cindent
  augroup END
]])
-- Ex command :echo "foo"
-- Note string literals need to be double quoted.
vim.cmd('echo "foo"')
vim.cmd { cmd = 'echo', args = { '"foo"' } }
vim.cmd.echo({ args = { '"foo"' } })
vim.cmd.echo('"foo"')
-- Ex command :write! myfile.txt
vim.cmd('write! myfile.txt')
vim.cmd { cmd = 'write', args = { "myfile.txt" }, bang = true }
vim.cmd.write { args = { "myfile.txt" }, bang = true }
vim.cmd.write { "myfile.txt", bang = true }
-- Ex command :colorscheme blue
vim.cmd('colorscheme blue')
vim.cmd.colorscheme('blue')
参数
{command} (string|table) 要执行的命令。如果为字符串,则一次执行多行 Vim 脚本。在这种情况下,它等效于 nvim_exec2(),其中 opts.output 设置为 false。因此,它与 :source 的工作方式相同。如果为表,则执行单个命令。在这种情况下,它等效于 nvim_cmd(),其中 opts 为空。
另请参阅
vim.defer_fn({fn}, {timeout}) vim.defer_fn()
延迟调用 {fn} 直到 {timeout} 毫秒过去。
用于执行一次性计时器,并在 {timeout} 到期后调用 {fn} 注意:{fn} 会自动通过 vim.schedule_wrap() 包装,因此 API 函数可以安全地调用。
参数
{fn} (function) 当 timeout 到期时要调用的回调函数
{timeout} (integer) 在调用 fn 之前等待的毫秒数
返回
(table) 计时器 luv 计时器对象
vim.deprecate()
vim.deprecate({name}, {alternative}, {version}, {plugin}, {backtrace}) 向用户显示弃用消息。
参数
{name} (string) 已弃用 特性(函数、API 等)。
{alternative} (string?) 建议的替代特性。
{version} (string) 将删除弃用函数的版本。
{plugin} (string?) 拥有弃用特性的插件名称。默认为“Nvim”。
{backtrace} (boolean?) 打印堆栈跟踪。默认为 true。
返回
(string?) 已弃用 消息,如果未显示消息则为 nil。
vim.inspect() vim.inspect()
获取给定对象的易于理解的表示形式。
返回
(string)
vim.keycode({str}) vim.keycode()
翻译键码。
示例
local k = vim.keycode
vim.g.mapleader = k'<bs>'
参数
{str} (string) 要转换的字符串。
返回
(string)
vim.lua_omnifunc({find_start}) vim.lua_omnifunc()
用于从运行时 Lua 解释器完成 Lua 值的 omnifunc,类似于 :lua 命令的内置完成。
在 Lua 缓冲区中使用 set omnifunc=v:lua.vim.lua_omnifunc 激活。
参数
{find_start} (1|0)
vim.notify({msg}, {level}, {opts}) vim.notify()
向用户显示通知。
此函数可以被插件覆盖,以便使用自定义提供程序(例如系统通知提供程序)显示通知。默认情况下,写入 :messages
参数
{msg} (string) 要向用户显示的通知内容。
{level} (integer?) 来自 vim.log.levels 的值之一。
{opts} (table?) 可选参数。默认情况下未被使用。
vim.notify_once({msg}, {level}, {opts}) vim.notify_once()
仅显示一次通知。
vim.notify() 相似,但使用相同消息的后续调用不会显示通知。
参数
{msg} (string) 要向用户显示的通知内容。
{level} (integer?) 来自 vim.log.levels 的值之一。
{opts} (table?) 可选参数。默认情况下未被使用。
返回
(boolean) 如果消息已显示,则为 true,否则为 false
vim.on_key({fn}, {ns_id}, {opts}) vim.on_key()
将具有命名空间 ID {ns_id} 的 Lua 函数 {fn} 添加为每个输入键的监听器,没错,是每个输入键。
Nvim 命令行选项 -w 相关但不支持回调,也不能动态切换。
注意
{fn} 将在发生错误时被移除。
{fn} 不会递归调用,即如果 {fn} 本身消耗输入,则不会针对那些键调用它。
{fn} 不会被 nvim_buf_clear_namespace() 清理。
参数
{fn} (fun(key: string, typed: string): string??) 针对每个输入键调用的函数,在应用映射后但进行进一步处理之前调用。参数 {key}{typed} 是原始键码,其中 {key} 是应用映射后的键,而 {typed} 是应用映射之前的键。如果 {key} 由非类型键或与产生先前 {key} 的相同类型键产生,则 {typed} 可能为空。如果 {fn} 返回空字符串,则 {key} 将被丢弃/忽略。当 {fn}nil 时,将移除与命名空间 {ns_id} 关联的回调。
{ns_id} (integer?) 命名空间 ID。如果为 nil 或 0,则会生成并返回新的 nvim_create_namespace() ID。
{opts} (table?) 可选参数
返回
(integer) 与 {fn} 关联的命名空间 ID。或者,如果 on_key() 在没有参数的情况下调用,则为所有回调的计数。
另请参阅
vim.paste({lines}, {phase}) vim.paste()
粘贴处理程序,由 nvim_paste() 调用。
注意:这仅作为“钩子”提供,不要直接调用它;请改为调用 nvim_paste(),它会安排重做(点重复)并调用 vim.paste
示例:在粘贴时删除 ANSI 颜色代码
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
    return overridden(lines, phase)
  end
end)(vim.paste)
参数
{lines} (string[]) 要粘贴的行的 readfile() 样式列表。 通道行
{phase} (-1|1|2|3) -1:“非流式”粘贴:调用包含所有行。如果粘贴是“流式”的,则 phase 表示流状态
1:开始粘贴(仅执行一次)
2:继续粘贴(零次或多次)
3:结束粘贴(仅执行一次)
返回
(boolean) 如果客户端应取消粘贴,则结果为 false。
另请参阅
vim.print({...}) vim.print()
“漂亮打印”给定参数并以未修改的形式返回它们。
示例
local hl_normal = vim.print(vim.api.nvim_get_hl(0, { name = 'Normal' }))
参数
{...} (any)
返回
(any) 给定的参数。
另请参阅
:=
vim.schedule_wrap({fn}) vim.schedule_wrap()
返回一个函数,该函数通过 vim.schedule() 调用 {fn}
返回的函数将所有参数传递给 {fn}
示例
function notify_readable(_err, readable)
  vim.notify("readable? " .. tostring(readable))
end
vim.uv.fs_access(vim.fn.stdpath("config"), "R", vim.schedule_wrap(notify_readable))
参数
{fn} (function)
返回
(function)
vim.str_byteindex()
vim.str_byteindex({s}, {encoding}, {index}, {strict_indexing}) 将 UTF-32、UTF-16 或 UTF-8 {index} 转换为字节索引。如果 {strict_indexing} 为 false,则超出范围的索引将返回字节长度,而不是抛出错误。
无效的 UTF-8 和 NUL 的处理方式与 vim.str_utfindex() 中相同。UTF-16 序列中间的 {index} 将向上舍入到该序列的末尾。
参数
{s} (string)
{encoding} ("utf-8"|"utf-16"|"utf-32")
{index} (integer)
{strict_indexing} (boolean?) 默认值:true
返回
(integer)
vim.str_utfindex()
vim.str_utfindex({s}, {encoding}, {index}, {strict_indexing}) 将字节索引转换为 UTF-32、UTF-16 或 UTF-8 索引。如果未提供 {index},则使用字符串的长度。所有索引都是从零开始的。
如果 {strict_indexing} 为 false,则超出范围的索引将返回字符串长度,而不是抛出错误。无效的 UTF-8 字节和嵌入的代理都计为一个代码点。UTF-8 序列中间的 {index} 将向上舍入到该序列的末尾。
参数
{s} (string)
{encoding} ("utf-8"|"utf-16"|"utf-32")
{index} (integer?)
{strict_indexing} (boolean?) 默认值:true
返回
(integer)
vim.system({cmd}, {opts}, {on_exit}) vim.system()
运行系统命令,如果无法运行 {cmd} 则抛出错误。
示例
local on_exit = function(obj)
  print(obj.code)
  print(obj.signal)
  print(obj.stdout)
  print(obj.stderr)
end
-- Runs asynchronously:
vim.system({'echo', 'hello'}, { text = true }, on_exit)
-- Runs synchronously:
local obj = vim.system({'echo', 'hello'}, { text = true }):wait()
-- { code = 0, signal = 0, stdout = 'hello', stderr = '' }
有关详细信息,请参阅 uv.spawn() 注意:uv.spawn() 不同,如果无法运行 {cmd},则 vim.system 会抛出错误。
参数
{cmd} (string[]) 要执行的命令
{opts} (vim.SystemOpts?) 选项
cwd: (string) 设置子进程的当前工作目录。
env: table<string,string> 设置新进程的环境变量。继承当前环境,并将 NVIM 设置为 v:servername
clear_env: (boolean) env 精确定义作业环境,而不是合并当前环境。
stdin: (string|string[]|boolean) 如果为 true,则会打开一个通向 stdin 的管道,并且可以通过 write() 方法写入 SystemObj。如果为字符串或字符串数组,则会写入 stdin 并关闭。默认为 false
stdout: (boolean|function) 处理 stdout 的输出。当作为函数传递时,必须具有签名 fun(err: string, data: string)。默认为 true
stderr: (boolean|function) 处理 stderr 的输出。当作为函数传递时,必须具有签名 fun(err: string, data: string)。默认为 true
text: (boolean) 将 stdout 和 stderr 作为文本处理。将 \r\n 替换为 \n
timeout: (integer) 在时间限制内运行命令。超时后,进程将被发送 TERM 信号 (15),退出代码将被设置为 124。
detach: (boolean) 如果为 true,则在分离状态下生成子进程 - 这将使其成为进程组领导者,并且将有效地使子进程在父进程退出后继续运行。请注意,子进程将仍然保持父进程的事件循环处于活动状态,除非父进程在子进程的进程句柄上调用 uv.unref()
{on_exit} (fun(out: vim.SystemCompleted)?) 在子进程退出时调用。当提供时,命令会异步运行。接收 SystemCompleted 对象,请参阅 SystemObj:wait() 的返回值。
返回
(vim.SystemObj) 具有以下字段的对象
cmd (string[]) 命令名称和参数
pid (integer) 进程 ID
wait (fun(timeout: integer|nil): SystemCompleted) 等待进程完成。超时后,进程将被发送 KILL 信号 (9),退出代码将被设置为 124。不能在 api-fast 中调用。
SystemCompleted 是一个具有以下字段的对象
code: (integer)
signal: (integer)
stdout: (string),如果传递了 stdout 参数,则为 nil
stderr: (string),如果传递了 stderr 参数,则为 nil
kill (fun(signal: integer|string))
write (fun(data: string|nil)) 需要 stdin=true。传递 nil 以关闭流。
is_closing (fun(): boolean)

Lua 模块:vim.inspector vim.inspector

vim.inspect_pos({bufnr}, {row}, {col}, {filter}) vim.inspect_pos()
获取给定缓冲区位置的所有项。
也可以使用 :Inspect! 进行漂亮打印。 :Inspect!
属性
自:0.9.0
参数
{bufnr} (integer?) 默认值为当前缓冲区
{row} (integer?) 要检查的行,从 0 开始。默认为当前光标的行
{col} (integer?) 要检查的列,从 0 开始。默认为当前光标的列
{filter} (table?) 具有键值对的表,用于过滤项
{syntax} (boolean,默认值:true) 包含基于语法的突出显示组。
{treesitter} (boolean,默认值:true) 包含基于 treesitter 的突出显示组。
{extmarks} (boolean|"all",默认值:true) 包含 extmarks。当为 all 时,则还将包含没有 hl_group 的 extmarks。
{semantic_tokens} (boolean,默认值:true) 包含语义标记突出显示。
返回
(table) 具有以下键值对的表。项按“遍历顺序”排列
treesitter:treesitter 捕获的列表
syntax:语法组的列表
semantic_tokens:语义标记的列表
extmarks:extmarks 的列表
buffer:用于获取项目的缓冲区
row:用于获取项目的行
col:用于获取项目的列
vim.show_pos({bufnr}, {row}, {col}, {filter}) vim.show_pos()
显示给定缓冲区位置的所有项。
也可以使用 :Inspect 显示。 :Inspect
属性
自:0.9.0
参数
{bufnr} (integer?) 默认值为当前缓冲区
{row} (integer?) 要检查的行,从 0 开始。默认为当前光标的行
{col} (integer?) 要检查的列,从 0 开始。默认为当前光标的列
{filter} (table?) 具有以下字段的表
{syntax} (boolean,默认值:true) 包含基于语法的突出显示组。
{treesitter} (boolean,默认值:true) 包含基于 treesitter 的突出显示组。
{extmarks} (boolean|"all",默认值:true) 包含 extmarks。当为 all 时,则还将包含没有 hl_group 的 extmarks。
{semantic_tokens} (boolean,默认值:true) 包含语义标记突出显示。
字段
{clear} (fun()) 清理所有项目
{push} (fun(item: T)) 添加项目,如果缓冲区已满,则覆盖最旧的项目。
{pop} (fun(): T?) 移除并返回第一个未读项目
{peek} (fun(): T?) 返回第一个未读项目,但不移除它
Ringbuf:clear() Ringbuf:clear()
清除所有项目
Ringbuf:peek() Ringbuf:peek()
返回第一个未读项目,但不删除它
返回
(any?)
Ringbuf:pop() Ringbuf:pop()
删除并返回第一个未读项目
返回
(any?)
Ringbuf:push({item}) Ringbuf:push()
添加一个项目,如果缓冲区已满,则覆盖最旧的项目。
参数
{item} (any)
vim.deep_equal({a}, {b}) vim.deep_equal()
深度比较值以确定是否相等
除非两个表都提供了eq元方法,否则递归地比较表。所有其他类型都使用相等运算符==进行比较。
参数
{a} (any) 第一个值
{b} (any) 第二个值
返回
(boolean) 如果值相等,则为true,否则为false
vim.deepcopy({orig}, {noref}) vim.deepcopy()
返回给定对象的深层副本。非表对象按典型的 Lua 赋值方式进行复制,而表对象则递归地进行复制。函数是简单复制的,因此复制表中的函数指向与输入表中的相同函数。用户数据和线程不会被复制,将引发错误。
注意:对于具有唯一表字段的表,noref=true 的性能要高得多,而对于重复使用表字段的表,noref=false 的性能要高得多。
参数
{orig} (table) 要复制的表
{noref} (boolean?) 当为false(默认值)时,仅复制一次包含的表,所有引用都指向此单个副本。当为true 时,每个表出现都会导致一个新的副本。这也意味着循环引用会导致deepcopy()失败。
返回
(table) 复制的键和(嵌套)值的表。
vim.defaulttable({createfn}) vim.defaulttable()
创建一个表,其缺少的键由{createfn}提供(类似于 Python 的“defaultdict”)。
如果{createfn}nil,则默认为defaulttable()本身,因此访问嵌套键会创建嵌套表
local a = vim.defaulttable()
a.b.c = 1
参数
{createfn} (fun(key:any):any?) 为缺少的key提供值。
返回
(table) 带有__index元方法的空表。
vim.endswith({s}, {suffix}) vim.endswith()
测试s是否以suffix结尾。
参数
{s} (string) 字符串
{suffix} (string) 要匹配的后缀
返回
(boolean) 如果suffixs的后缀,则为true
vim.gsplit({s}, {sep}, {opts}) vim.gsplit()
获取一个迭代器,该迭代器以“延迟”方式(与vim.split()不同,它是“急切”的)在分隔符的每个实例处分割字符串。
示例
for s in vim.gsplit(':aa::b:', ':', {plain=true}) do
  print(s)
end
如果要检查分隔符本身(而不是丢弃它),请使用string.gmatch()。示例
for word, num in ('foo111bar222'):gmatch('([^0-9]*)(%d*)') do
  print(('word: %s num: %s'):format(word, num))
end
参数
{s} (string) 要分割的字符串
{sep} (string) 分隔符或模式
{opts} (table?) 关键字参数 kwargs
{plain} (boolean) 按字面意思使用sep(如 string.find 中)。
{trimempty} (boolean) 丢弃序列开头和结尾的空段。
返回
(fun():string?) 对分割组件的迭代器
vim.is_callable({f}) vim.is_callable()
如果对象f可以作为函数调用,则返回true。
参数
{f} (any) 任何对象
返回
(boolean) 如果f是可调用的,则为true,否则为false
vim.isarray({t}) vim.isarray()
测试t是否为“数组”:仅由整数(可能是非连续的)索引的表。
如果索引从 1 开始并且是连续的,则数组也是列表。 vim.islist()
空表{}是数组,除非它是由vim.empty_dict()创建的,或作为类似字典的 API 或 Vimscript 结果返回的,例如来自rpcrequest()vim.fn
参数
{t} (table?)
返回
(boolean) 如果是类似数组的表,则为true,否则为false
vim.islist({t}) vim.islist()
测试t是否为“列表”:仅由从 1 开始的连续整数索引的表(lua-length 称为“常规数组”)。
空表{}是列表,除非它是由vim.empty_dict()创建的,或作为类似字典的 API 或 Vimscript 结果返回的,例如来自rpcrequest()vim.fn
参数
{t} (table?)
返回
(boolean) 如果是类似列表的表,则为true,否则为false
另请参阅
vim.list_contains({t}, {value}) vim.list_contains()
检查类似列表的表(没有间隙的整数键)是否包含value
参数
{t} (table) 要检查的表(必须是类似列表的,不会被验证)
{value} (any) 要比较的值
返回
(boolean) 如果t包含value,则为true
另请参阅
vim.tbl_contains() 用于检查一般表中的值
vim.list_extend({dst}, {src}, {start}, {finish}) vim.list_extend()
用另一个类似列表的表的元素扩展类似列表的表。
注意:这会修改 dst!
参数
{dst} (table) 将被修改和附加到的列表
{src} (table) 将从中插入值的列表
{start} (integer?) src 上的起始索引。默认为 1
{finish} (integer?) src 上的最终索引。默认为#src
返回
(table) dst
另请参阅
vim.list_slice({list}, {start}, {finish}) vim.list_slice()
创建一个包含从开始到结束(含)的元素的表的副本
参数
{list} (any[]) 表
{start} (integer?) 切片的起始范围
{finish} (integer?) 切片的结束范围
返回
(any[]) 从开始到结束(含)切片的表的副本
vim.pesc({s}) vim.pesc()
转义 lua-patterns 中的魔法字符。
参数
{s} (string) 要转义的字符串
返回
(string) %-转义的模式字符串
vim.ringbuf({size}) vim.ringbuf()
创建一个限制为最大项目数的环形缓冲区。缓冲区满后,添加新条目会覆盖最旧的条目。
local ringbuf = vim.ringbuf(4)
ringbuf:push("a")
ringbuf:push("b")
ringbuf:push("c")
ringbuf:push("d")
ringbuf:push("e")    -- overrides "a"
print(ringbuf:pop()) -- returns "b"
print(ringbuf:pop()) -- returns "c"
-- Can be used as iterator. Pops remaining items:
for val in ringbuf do
  print(val)
end
返回一个 Ringbuf 实例,它具有以下方法
参数
{size} (integer)
返回
(vim.Ringbuf) ringbuf 请参见 vim.Ringbuf
vim.spairs({t}) vim.spairs()
枚举表的键值对,按键排序。
参数
{t} (table) 类似字典的表
返回(多个)
(fun(table: table<K, V>, index?: K):K, V) for-in 迭代器,用于遍历排序后的键及其值(table
vim.split({s}, {sep}, {opts}) vim.split()
在分隔符的每个实例处分割字符串,并将结果作为表返回(与vim.gsplit()不同)。
示例
split(":aa::b:", ":")                   --> {'','aa','','b',''}
split("axaby", "ab?")                   --> {'','x','y'}
split("x*yz*o", "*", {plain=true})      --> {'x','yz','o'}
split("|x|y|z|", "|", {trimempty=true}) --> {'x', 'y', 'z'}
参数
{s} (string) 要分割的字符串
{sep} (string) 分隔符或模式
{opts} (table?) 关键字参数 kwargs
{plain} (boolean) 按字面意思使用sep(如 string.find 中)。
{trimempty} (boolean) 丢弃序列开头和结尾的空段。
返回
(string[]) 分割组件列表
vim.startswith({s}, {prefix}) vim.startswith()
测试s是否以prefix开头。
参数
{s} (string) 字符串
{prefix} (string) 要匹配的前缀
返回
(boolean) 如果prefixs的前缀,则为true
vim.tbl_contains({t}, {value}, {opts}) vim.tbl_contains()
检查表是否包含给定值,该值可以通过直接指定或通过针对每个值检查的谓词来指定。
示例
vim.tbl_contains({ 'a', { 'b', 'c' } }, function(v)
  return vim.deep_equal(v, { 'b', 'c' })
end, { predicate = true })
-- true
参数
{t} (table) 要检查的表
{value} (any) 要比较的值或谓词函数引用
{opts} (table?) 关键字参数 kwargs
{predicate} (boolean) value 是要检查的函数引用(默认为 false)
返回
(boolean) 如果t包含value,则为true
另请参阅
vim.list_contains() 用于检查类似列表的表中的值
vim.tbl_count({t}) vim.tbl_count()
计算表t中非 nil 值的数量。
vim.tbl_count({ a=1, b=2 })  --> 2
vim.tbl_count({ 1, 2 })      --> 2
参数
{t} (table) 表
返回
(integer) 表中非 nil 值的数量
vim.tbl_deep_extend({behavior}, {...}) vim.tbl_deep_extend()
递归地合并两个或多个表。
仅将为空表或不是 lua-list(由从 1 开始的连续整数索引)的表递归地合并。这对于合并嵌套表(如默认配置和用户配置)很有用,在这些配置中,列表应被视为文字(即被覆盖而不是合并)。
参数
{behavior} ('error'|'keep'|'force') 决定如果在多个映射中找到一个键,该怎么办
"error": 抛出错误
"keep": 使用最左侧映射中的值
"force": 使用最右侧映射中的值
{...} (table) 两个或多个表
返回
(table) 合并的表
另请参阅
vim.tbl_extend({behavior}, {...}) vim.tbl_extend()
合并两个或多个表。
参数
{behavior} ('error'|'keep'|'force') 决定如果在多个映射中找到一个键,该怎么办
"error": 抛出错误
"keep": 使用最左侧映射中的值
"force": 使用最右侧映射中的值
{...} (table) 两个或多个表
返回
(table) 合并的表
另请参阅
vim.tbl_filter({func}, {t}) vim.tbl_filter()
使用谓词函数过滤表
参数
{func} (function) 函数
{t} (table) 表
返回
(any[]) 过滤后的值表
vim.tbl_get({o}, {...}) vim.tbl_get()
通过作为后续参数传递的字符串键索引表(第一个参数)。如果键不存在,则返回nil
示例
vim.tbl_get({ key = { nested_key = true }}, 'key', 'nested_key') == true
vim.tbl_get({ key = {}}, 'key', 'nested_key') == nil
参数
{o} (table) 要索引的表
{...} (any) 可选键(0 个或多个,可变),通过这些键对表进行索引
返回
(any) 由键索引的嵌套值(如果存在),否则为 nil
vim.tbl_isempty({t}) vim.tbl_isempty()
检查表是否为空。
参数
{t} (table) 要检查的表
返回
(boolean) 如果t为空,则为true
vim.tbl_keys({t}) vim.tbl_keys()
返回表中使用的所有键的列表。但是,返回键的表顺序不保证。
参数
{t} (table) 表
返回
(any[]) 键列表
vim.tbl_map({func}, {t}) vim.tbl_map()
将函数应用于表的每个值。
参数
{func} (fun(value: T): any) 函数
{t} (table<any, T>) 表格
返回
(table) 转换后的值表格
vim.tbl_values({t}) vim.tbl_values()
返回表格中所有使用的值列表。但是,返回值表格的顺序无法保证。
参数
{t} (table) 表
返回
(any[]) 值列表
vim.trim({s}) vim.trim()
从字符串的两侧删除空白字符(Lua 模式 "%s")。
参数
{s} (string) 要修剪的字符串
返回
(string) 从开头和结尾删除空白字符后的字符串
vim.validate()
vim.validate({name}, {value}, {validator}, {optional}, {message}) 验证函数参数。
此函数有两种有效形式:1. vim.validate(name, value, validator[, optional][, message]) 验证参数 {name} 的值 {value} 是否满足 {validator}。如果 {optional} 给定且为 true,则 {value} 可以为 nil。如果给定 {message},则它将用作错误消息中的预期类型。示例
 function vim.startswith(s, prefix)
  vim.validate('s', s, 'string')
  vim.validate('prefix', prefix, 'string')
  ...
end
2. vim.validate(spec) (已弃用)其中 spec 的类型为 table<string,[value:any, validator: vim.validate.Validator, optional_or_msg? : boolean|string]>) 验证参数规范。规范按字母数字顺序进行评估,直到第一个失败为止。示例
 function user.new(name, age, hobbies)
  vim.validate{
    name={name, 'string'},
    age={age, 'number'},
    hobbies={hobbies, 'table'},
  }
  ...
end
使用显式参数值的示例(可以直接运行)
vim.validate('arg1', {'foo'}, 'table')
   --> NOP (success)
vim.validate('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')
如果多个类型有效,则可以将它们作为列表给出。
vim.validate('arg1', {'foo'}, {'table', 'string'})
vim.validate('arg2', 'foo', {'table', 'string'})
-- NOP (success)
vim.validate('arg1', 1, {'string', 'table'})
-- error('arg1: expected string|table, got number')
注意
validator 设置为 lua-type() 返回的值可以提供最佳性能。
参数
{name} (string) 参数名称
{value} (string) 参数值
{validator} (vim.validate.Validator)
(string|string[]): 除 'callable' 之外,还可以从 lua-type() 返回的任何值:'boolean', 'callable', 'function', 'nil', 'number', 'string', 'table', 'thread', 'userdata'
(fun(val:any): boolean, string?) 返回布尔值和可选字符串消息的函数。
{optional} (boolean?) 参数是可选的(可以省略)
{message} (string?) 验证失败时的消息

Lua 模块:vim.loader vim.loader

vim.loader.disable() vim.loader.disable()
警告: 此功能处于实验/不稳定状态。
禁用实验性的 Lua 模块加载器
删除加载器
添加默认的 Nvim 加载器
vim.loader.enable() vim.loader.enable()
警告: 此功能处于实验/不稳定状态。
启用实验性的 Lua 模块加载器
覆盖 loadfile
添加使用字节编译缓存的 Lua 加载器
添加 libs 加载器
删除默认的 Nvim 加载器
vim.loader.find({modname}, {opts}) vim.loader.find()
警告: 此功能处于实验/不稳定状态。
查找给定模块名的 Lua 模块。
参数
{modname} (string) 模块名称,或 "*" 用于查找顶级模块
{opts} (table?) 查找模块的选项
{rtp} (boolean, 默认值:true) 在运行时路径中搜索 modname。
{paths} (string[], 默认值:{}) 搜索 modname 的额外路径
{patterns} (string[], 默认值:{"/init.lua", ".lua"}) 搜索模块时使用的模式列表。模式是添加到正在搜索的 Lua 模块基本名的字符串。
{all} (boolean, 默认值:false) 搜索所有匹配项。
返回
(table[]) 包含以下字段的对象列表
{modpath} (string) 模块的路径
{modname} (string) 模块的名称
{stat} (uv.fs_stat.result) 模块路径的 fs_stat。不会为 modname="*" 返回
vim.loader.reset({path}) vim.loader.reset()
警告: 此功能处于实验/不稳定状态。
重置路径的缓存,如果 path 为 nil,则重置所有路径。
参数
{path} (string?) 要重置的路径

Lua 模块:vim.uri vim.uri

vim.uri_decode({str}) vim.uri_decode()
URI 解码包含百分比转义的字符串。
参数
{str} (string) 要解码的字符串
返回
(string) 解码后的字符串
vim.uri_encode({str}, {rfc}) vim.uri_encode()
使用百分比转义对字符串进行 URI 编码。
参数
{str} (string) 要编码的字符串
{rfc} ("rfc2396"|"rfc2732"|"rfc3986"?)
返回
(string) 编码后的字符串
vim.uri_from_bufnr({bufnr}) vim.uri_from_bufnr()
从 bufnr 获取 URI。
参数
{bufnr} (integer)
返回
(string) URI
vim.uri_from_fname({path}) vim.uri_from_fname()
从文件路径获取 URI。
参数
{path} (string) 文件路径
返回
(string) URI
vim.uri_to_bufnr({uri}) vim.uri_to_bufnr()
获取 uri 的缓冲区。如果 uri 的缓冲区不存在,则创建新的未加载缓冲区。
参数
{uri} (string)
返回
(integer) bufnr
vim.uri_to_fname({uri}) vim.uri_to_fname()
从 URI 获取文件名。
参数
{uri} (string)
返回
(string) 文件名或非文件 URI 的未更改 URI

Lua 模块:vim.ui vim.ui

vim.ui.input({opts}, {on_confirm}) vim.ui.input()
提示用户输入,允许任意(可能异步)工作,直到 on_confirm 为止。
示例
vim.ui.input({ prompt = 'Enter value for shiftwidth: ' }, function(input)
    vim.o.shiftwidth = tonumber(input)
end)
参数
{opts} (table?) 额外的选项。请参阅 input()
prompt (string|nil) 提示文本
default (string|nil) 对输入的默认回复
completion (string|nil) 指定对输入支持的完成类型。支持的类型与使用 "-complete=" 参数提供给用户定义命令的类型相同。请参阅 :command-completion
highlight (function) 用于突出显示用户输入的函数。
{on_confirm} (function) ((input|nil) -> ()) 用户确认或中止输入后调用。input 是用户输入的内容(如果未输入任何内容,它可能为空字符串),或者如果用户中止了对话框,则为 nil
vim.ui.open({path}, {opt}) vim.ui.open()
使用系统默认处理程序打开 path(macOS open、Windows explorer.exe、Linux xdg-open 等),或者返回(但不会显示)失败时的错误消息。
在文件系统路径中扩展 "~/" 和环境变量。
示例
-- Asynchronous.
vim.ui.open("https://neovim.fullstack.org.cn/")
vim.ui.open("~/path/to/file")
-- Use the "osurl" command to handle the path or URL.
vim.ui.open("gh#neovim/neovim!29490", { cmd = { 'osurl' } })
-- Synchronous (wait until the process exits).
local cmd, err = vim.ui.open("$VIMRUNTIME")
if cmd then
  cmd:wait()
end
参数
{path} (string) 要打开的路径或 URL
{opt} ({ cmd?: string[] }?) 选项
cmd string[]|nil 用于打开路径或 URL 的命令。
返回(多个)
(vim.SystemObj?) 命令对象,如果未找到,则为 nil。 (string?) 失败时的错误消息,成功时为 nil。
另请参阅
vim.ui.select({items}, {opts}, {on_choice}) vim.ui.select()
提示用户从项目列表中选择,允许任意(可能异步)工作,直到 on_choice 为止。
示例
vim.ui.select({ 'tabs', 'spaces' }, {
    prompt = 'Select tabs or spaces:',
    format_item = function(item)
        return "I'd like to choose " .. item
    end,
}, function(choice)
    if choice == 'spaces' then
        vim.o.expandtab = true
    else
        vim.o.expandtab = false
    end
end)
参数
{items} (any[]) 任意项目
{opts} (table) 额外的选项
prompt (string|nil) 提示文本。默认值为 Select one of:
format_item (function item -> text) 用于格式化 items 中单个项目的函数。默认值为 tostring
kind (string|nil) 指示项目形状的任意提示字符串。重新实现 vim.ui.select 的插件可能希望使用它来推断 items 的结构或语义,或者调用 select() 的上下文。
{on_choice} (fun(item: T?, idx: integer?)) 用户做出选择后调用。idxitemsitem 的 1 索引。如果用户中止了对话框,则为 nil

Lua 模块:vim.filetype vim.filetype

vim.filetype.add({filetypes}) vim.filetype.add()
添加新的文件类型映射。
可以通过扩展名或文件名(文件“尾部”或完整文件路径)添加文件类型映射。首先检查完整文件路径,然后检查文件名。如果使用文件名没有找到匹配项,则将文件名与 lua-patterns 列表(按优先级排序)进行匹配,直到找到匹配项。最后,如果模式匹配未找到文件类型,则使用文件扩展名。
文件类型可以是字符串(在这种情况下,它直接用作文件类型),也可以是函数。如果是函数,它将以文件的完整路径和缓冲区号作为参数(以及来自匹配模式的捕获,如果有的话),并应返回一个字符串,该字符串将用作缓冲区的文件类型。可选地,该函数可以返回第二个函数值,该值在调用时修改缓冲区的状态。例如,这可用于设置特定于文件类型的缓冲区变量。Nvim 将在设置缓冲区的文件类型之前调用此函数。
文件名模式可以指定可选优先级,以解决文件路径与多个模式匹配的情况。优先级更高的模式首先匹配。省略时,优先级默认为 0。模式可以包含形式为 "${SOME_VAR}" 的环境变量,这些变量将自动扩展。如果未设置环境变量,则模式将不会匹配。
有关更多示例,请参阅 $VIMRUNTIME/lua/vim/filetype.lua。
示例
vim.filetype.add({
  extension = {
    foo = 'fooscript',
    bar = function(path, bufnr)
      if some_condition() then
        return 'barscript', function(bufnr)
          -- Set a buffer variable
          vim.b[bufnr].barscript_version = 2
        end
      end
      return 'bar'
    end,
  },
  filename = {
    ['.foorc'] = 'toml',
    ['/etc/foo/config'] = 'toml',
  },
  pattern = {
    ['.*/etc/foo/.*'] = 'fooscript',
    -- Using an optional priority
    ['.*/etc/foo/.*%.conf'] = { 'dosini', { priority = 10 } },
    -- A pattern containing an environment variable
    ['${XDG_CONFIG_HOME}/foo/git'] = 'git',
    ['.*README.(%a+)'] = function(path, bufnr, ext)
      if ext == 'md' then
        return 'markdown'
      elseif ext == 'rst' then
        return 'rst'
      end
    end,
  },
})
要在内容上添加后备匹配,请使用
vim.filetype.add {
  pattern = {
    ['.*'] = {
      function(path, bufnr)
        local content = vim.api.nvim_buf_get_lines(bufnr, 0, 1, false)[1] or ''
        if vim.regex([[^#!.*\\<mine\\>]]):match_str(content) ~= nil then
          return 'mine'
        elseif vim.regex([[\\<drawing\\>]]):match_str(content) ~= nil then
          return 'drawing'
        end
      end,
      { priority = -math.huge },
    },
  },
}
参数
{filetypes} (table) 包含新的文件类型映射的表格(请参阅示例)。
{pattern} (vim.filetype.mapping)
{extension} (vim.filetype.mapping)
{filename} (vim.filetype.mapping)
vim.filetype.get_option()
vim.filetype.get_option({filetype}, {option}) 获取 {filetype} 的默认选项值。
返回值是在设置 'filetype' 后将在新缓冲区中设置的值,这意味着它应尊重所有 FileType 自动命令和 ftplugin 文件。
示例
vim.filetype.get_option('vim', 'commentstring')
注意:这使用 nvim_get_option_value() 但缓存了结果。这意味着 ftpluginFileType 自动命令仅触发一次,可能无法反映之后的更改。
属性
自:0.9.0
参数
{filetype} (string) 文件类型
{option} (string) 选项名称
返回
(string|boolean|integer) 选项值
vim.filetype.match({args}) vim.filetype.match()
执行文件类型检测。
可以使用三种方法之一检测文件类型:1. 使用现有缓冲区 2. 仅使用文件名 3. 仅使用文件内容
在这三种选项中,选项 1 提供了最准确的结果,因为它使用缓冲区的文件名和(可选)缓冲区内容。选项 2 和 3 可以无需现有缓冲区使用,但在文件名(或内容)无法明确确定文件类型的情况下,可能无法始终提供匹配结果。
这三个选项中的每一个都使用此函数的单个参数的键来指定。示例
-- Using a buffer number
vim.filetype.match({ buf = 42 })
-- Override the filename of the given buffer
vim.filetype.match({ buf = 42, filename = 'foo.c' })
-- Using a filename without a buffer
vim.filetype.match({ filename = 'main.lua' })
-- Using file contents
vim.filetype.match({ contents = {'#!/usr/bin/env bash'} })
参数
{args} (table) 指定使用哪种匹配策略的表。接受的键为
{buf} (integer) 用于匹配的缓冲区编号。与 {contents} 互斥
{filename} (string) 用于匹配的文件名。当给出 {buf} 时,默认为给定缓冲区编号的文件名。该文件不必实际存在于文件系统中。当不使用 {buf} 时,仅使用文件的名称来进行文件类型匹配。这可能导致在文件名本身不足以区分文件类型的情况下无法检测到文件类型。
{contents} (string[]) 表示用于匹配的文件内容的字符串数组。可以与 {filename} 一起使用。与 {buf} 互斥。
返回(多个)
(string?) 如果找到匹配项,则为匹配的文件类型。 (function?) 当调用时修改缓冲区状态的函数(例如,设置一些特定于文件类型的缓冲区变量)。该函数接受缓冲区编号作为其唯一参数。

Lua 模块: vim.keymap vim.keymap

vim.keymap.del({modes}, {lhs}, {opts}) vim.keymap.del()
删除现有映射。示例
vim.keymap.del('n', 'lhs')
vim.keymap.del({'n', 'i', 'v'}, '<leader>w', { buffer = 5 })
参数
{modes} (string|string[])
{lhs} (string)
{opts} (table?) 包含以下字段的表
{buffer} (integer|boolean) 从给定缓冲区中删除映射。当为 0true 时,使用当前缓冲区。
另请参阅
vim.keymap.set({mode}, {lhs}, {rhs}, {opts}) vim.keymap.set()
定义映射 键码 到函数或键码。
示例
-- Map "x" to a Lua function:
vim.keymap.set('n', 'x', function() print("real lua function") end)
-- Map "<leader>x" to multiple modes for the current buffer:
vim.keymap.set({'n', 'v'}, '<leader>x', vim.lsp.buf.references, { buffer = true })
-- Map <Tab> to an expression (|:map-<expr>|):
vim.keymap.set('i', '<Tab>', function()
  return vim.fn.pumvisible() == 1 and "<C-n>" or "<Tab>"
end, { expr = true })
-- Map "[%%" to a <Plug> mapping:
vim.keymap.set('n', '[%%', '<Plug>(MatchitNormalMultiBackward)')
参数
{mode} (string|string[]) 模式“简称”(参见 nvim_set_keymap()),或其列表。
{lhs} (string) 映射的左侧 {lhs}
{rhs} (string|function) 映射的右侧 {rhs},可以是 Lua 函数。
{opts} (table?) :map-arguments 的表。与 nvim_set_keymap() {opts} 相同,除了
如果“expr”为 true,则 {replace_keycodes} 默认为 true
还接受
{buffer} (integer|boolean) 创建缓冲区局部映射,0true 用于当前缓冲区。
{remap} (boolean, 默认值: false) 使映射递归。是 {noremap} 的反义词。

Lua 模块: vim.fs vim.fs

vim.fs.basename({file}) vim.fs.basename()
返回给定路径的基名
属性
自: 0.8.0
参数
{file} (string?) 路径
返回
(string?) {file} 的基名
vim.fs.dir({path}, {opts}) vim.fs.dir()
返回位于 {path} 中的项目的迭代器
属性
自: 0.8.0
参数
{path} (string) 要迭代的目录的绝对或相对路径。该路径首先被标准化 vim.fs.normalize()
{opts} (table?) 可选的关键字参数
depth: integer|nil 遍历深度(默认 1)
skip: (fun(dir_name: string): boolean)|nil 用于控制遍历的谓词。返回 false 以停止搜索当前目录。仅当深度 > 1 时才有用
返回
(Iterator) {path} 中的项目。每次迭代都会产生两个值:“name”和“type”。“name”是相对于 {path} 的项目的基名。“type”是以下内容之一:“file”、“directory”、“link”、“fifo”、“socket”、“char”、“block”、“unknown”。
vim.fs.dirname({file}) vim.fs.dirname()
返回给定路径的父目录
属性
自: 0.8.0
参数
{file} (string?) 路径
返回
(string?) {file} 的父目录
vim.fs.find({names}, {opts}) vim.fs.find()
在给定路径中查找文件或目录(或由 opts.type 指定的其他项目)。
{path} 开始查找 {names} 中给出的项目。如果 {upward} 为“true”,则搜索将向上遍历父目录;否则,搜索将向下遍历。请注意,向下搜索是递归的,可能会搜索多个目录!如果 {stop} 非空,则当到达 {stop} 中给出的目录时,搜索停止。当找到 {limit}(默认 1)个匹配项时,搜索终止。可以将 {type} 设置为“file”、“directory”、“link”、“socket”、“char”、“block”或“fifo”以将搜索范围缩小到仅查找该类型。
示例
-- list all test directories under the runtime directory
local test_dirs = vim.fs.find(
  {'test', 'tst', 'testdir'},
  {limit = math.huge, type = 'directory', path = './runtime/'}
)
-- get all files ending with .cpp or .hpp inside lib/
local cpp_hpp = vim.fs.find(function(name, path)
  return name:match('.*%.[ch]pp$') and path:match('[/\\\\]lib$')
end, {limit = math.huge, type = 'file'})
属性
自: 0.8.0
参数
{names} (string|string[]|fun(name: string, path: string): boolean) 要查找的项目的名称。必须是基名,路径和通配符在 {names} 为字符串或表时不受支持。如果 {names} 是一个函数,则会为每个遍历的项目调用它,并带有参数
name: 当前项目的基名
path: 当前项目的完整路径 该函数应在给定项目被视为匹配项时返回 true
{opts} (table) 可选的关键字参数
{path} (string) 从中开始搜索的路径。如果省略,则使用 当前目录
{upward} (boolean, 默认值: false) 向上搜索父目录。否则,搜索子目录(递归地)。
{stop} (string) 当到达此目录时停止搜索。该目录本身不会被搜索。
{type} (string) 仅查找给定类型的项目。如果省略,则包括所有与 {names} 匹配的项目。
{limit} (number, 默认值: 1) 在找到此数量的匹配项后停止搜索。使用 math.huge 对匹配项数量不设限制。
返回
(string[]) 所有匹配项目的标准化路径 vim.fs.normalize()
vim.fs.joinpath({...}) vim.fs.joinpath()
将目录和/或文件路径连接成单个路径,并进行标准化(例如,"foo/""bar" 会连接到 "foo/bar"
属性
自: 0.10.0
参数
{...} (string)
返回
(string)
vim.fs.normalize({path}, {opts}) vim.fs.normalize()
将路径标准化为标准格式。路径开头的波浪号(~)字符将扩展到用户的 home 目录,环境变量也会扩展。"." 和 ".." 组件也会被解析,除非路径是相对路径,并且解析会导致绝对路径。
“.” 作为相对路径中唯一的组成部分
"." => "."
"././" => "."
“..” 当它导致超出当前目录时
“foo/../../bar” => “../bar”
“../../foo” => “../../foo”
“..” 在根目录中返回根目录。
"/../../" => "/"
在 Windows 上,反斜杠 (\) 字符将转换为正斜杠 (/)。
示例
[[C:\Users\jdoe]]                         => "C:/Users/jdoe"
"~/src/neovim"                            => "/home/jdoe/src/neovim"
"$XDG_CONFIG_HOME/nvim/init.vim"          => "/Users/jdoe/.config/nvim/init.vim"
"~/src/nvim/api/../tui/./tui.c"           => "/home/jdoe/src/nvim/tui/tui.c"
"./foo/bar"                               => "foo/bar"
"foo/../../../bar"                        => "../../bar"
"/home/jdoe/../../../bar"                 => "/bar"
"C:foo/../../baz"                         => "C:../baz"
"C:/foo/../../baz"                        => "C:/baz"
[[\\?\UNC\server\share\foo\..\..\..\bar]] => "//?/UNC/server/share/bar"
属性
自: 0.8.0
参数
{path} (string) 要标准化的路径
{opts} (table?) 包含以下字段的表
{expand_env} (boolean, 默认值: true) 扩展环境变量。
{win} (boolean, 默认值: 在 Windows 中为 true,在其他系统中为 false) 路径是 Windows 路径。
返回
(string) 标准化的路径
vim.fs.parents({start}) vim.fs.parents()
迭代给定路径的所有父级。
示例
local root_dir
for dir in vim.fs.parents(vim.api.nvim_buf_get_name(0)) do
  if vim.fn.isdirectory(dir .. "/.git") == 1 then
    root_dir = dir
    break
  end
end
if root_dir then
  print("Found git repository at", root_dir)
end
属性
自: 0.8.0
参数
{start} (string) 初始路径。
返回(多个)
(fun(_, dir: string): string?) 迭代器 (nil) (string?)
vim.fs.rm({path}, {opts}) vim.fs.rm()
警告: 此功能处于实验/不稳定状态。
删除文件或目录
参数
{path} (string) 要删除的路径
{opts} (table?) 包含以下字段的表
{recursive} (boolean) 递归删除目录及其内容
{force} (boolean) 忽略不存在的文件和参数
vim.fs.root({source}, {marker}) vim.fs.root()
查找第一个包含特定“marker”的父目录,相对于文件路径或缓冲区。
如果缓冲区未命名(没有备份文件)或具有非空的 'buftype',则搜索将从 Nvim 的 当前目录 开始。
示例
-- Find the root of a Python project, starting from file 'main.py'
vim.fs.root(vim.fs.joinpath(vim.env.PWD, 'main.py'), {'pyproject.toml', 'setup.py' })
-- Find the root of a git repository
vim.fs.root(0, '.git')
-- Find the parent directory containing any file with a .csproj extension
vim.fs.root(0, function(name, path)
  return name:match('%.csproj$') ~= nil
end)
属性
自: 0.10.0
参数
{source} (integer|string) 缓冲区编号(当前缓冲区为 0)或文件路径(绝对路径或相对于 当前目录)从中开始搜索。
{marker} (string|string[]|fun(name: string, path: string): boolean) 要搜索的标记或标记列表。如果为函数,则会为每个评估的项目调用该函数,如果 {name}{path} 匹配,则应返回 true。
返回
(string?) 包含给定标记之一的目录路径,如果没有找到目录,则为 nil。

Lua 模块: vim.glob vim.glob

vim.glob.to_lpeg({pattern}) vim.glob.to_lpeg()
将原始通配符解析为 lua-lpeg 模式。
通配符模式可以具有以下语法
* 匹配路径段中的一个或多个字符
? 匹配路径段中的一个字符
** 匹配任意数量的路径段,包括零个
{} 用于对条件进行分组(例如 *.{ts,js} 匹配 TypeScript 和 JavaScript 文件)
[] 用于声明路径段中要匹配的字符范围(例如,example.[0-9] 匹配 example.0example.1 等)
[!...] 用于否定路径段中要匹配的字符范围(例如,example.[!0-9] 匹配 example.aexample.b,但不匹配 example.0
参数
{pattern} (string) 原始通配符模式
返回
(vim.lpeg.Pattern) pattern lua-lpeg 对模式的表示

VIM.LPEG vim.lpeg

LPeg 是 Lua 的一个模式匹配库,基于解析表达式语法 (PEG)。 https://bford.info/packrat/
lua-lpeg vim.lpeg.Pattern 用于解析表达式语法的 LPeg 库包含在 vim.lpeg 中 (https://www.inf.puc-rio.br/~roberto/lpeg/)。
此外,其类似正则表达式的接口可作为 vim.re 使用 (https://www.inf.puc-rio.br/~roberto/lpeg/re.html)。
Pattern:match({subject}, {init}, {...}) Pattern:match()
将给定的patternsubject字符串进行匹配。如果匹配成功,则返回匹配后第一个字符在subject中的索引,或者返回捕获的值(如果pattern捕获了任何值)。可选的数值参数init可以使匹配从subject字符串中的该位置开始。与 Lua 库中的惯例一样,负值从末尾开始计数。与典型的模式匹配函数不同,match仅在锚定模式下工作;也就是说,它尝试将模式与给定subject字符串的前缀(位于位置init处)匹配,而不是与subject的任意子字符串匹配。因此,如果我们想在字符串中的任何位置找到一个模式,我们必须要么在 Lua 中写一个循环,要么写一个在任何位置都匹配的模式。
示例
local pattern = lpeg.R('az') ^ 1 * -1
assert(pattern:match('hello') == 6)
assert(lpeg.match(pattern, 'hello') == 6)
assert(pattern:match('1 hello') == nil)
参数
{subject} (string)
{init} (integer?)
{...} (any)
返回
(any) ...
vim.lpeg.B({pattern}) vim.lpeg.B()
返回一个模式,该模式仅在当前位置的输入字符串之前是patt时才匹配。模式patt必须仅匹配具有固定长度的字符串,并且不能包含捕获。与and谓词一样,此模式永远不会消耗任何输入,无论成功与否。
参数
{pattern} (vim.lpeg.Pattern|string|integer|boolean|table)
返回
(vim.lpeg.Pattern)
vim.lpeg.C({patt}) vim.lpeg.C()
创建一个简单的捕获,它捕获与patt匹配的subject的子字符串。捕获的值是一个字符串。如果patt有其他捕获,则它们的返回值将在此值之后返回。
示例
local function split (s, sep)
  sep = lpeg.P(sep)
  local elem = lpeg.C((1 - sep) ^ 0)
  local p = elem * (sep * elem) ^ 0
  return lpeg.match(p, s)
end
local a, b, c = split('a,b,c', ',')
assert(a == 'a')
assert(b == 'b')
assert(c == 'c')
参数
{patt} (vim.lpeg.Pattern|string|integer|boolean|table|function)
返回
(vim.lpeg.Capture)
vim.lpeg.Carg({n}) vim.lpeg.Carg()
创建一个参数捕获。此模式匹配空字符串,并生成在调用lpeg.match时作为第 n 个额外参数给出的值。
参数
{n} (integer)
返回
(vim.lpeg.Capture)
vim.lpeg.Cb({name}) vim.lpeg.Cb()
创建一个回溯捕获。此模式匹配空字符串,并生成由最近命名的组捕获name生成的值(其中name可以是任何 Lua 值)。最近表示具有给定名称的最后一个完整的最外层组捕获。完整捕获意味着与捕获相对应的整个模式已匹配。最外层捕获意味着捕获不在另一个完整捕获内部。与 LPeg 不指定何时评估捕获一样,它也不指定是否重用先前由组生成的值或重新评估它们。
参数
{name} (any)
返回
(vim.lpeg.Capture)
vim.lpeg.Cc({...}) vim.lpeg.Cc()
创建一个常量捕获。此模式匹配空字符串,并生成所有给定值作为其捕获值。
参数
{...} (any)
返回
(vim.lpeg.Capture)
vim.lpeg.Cf({patt}, {func}) vim.lpeg.Cf()
创建一个折叠捕获。如果patt生成一个捕获 C1 C2 ... Cn 的列表,此捕获将生成值func(...func(func(C1, C2), C3)...,Cn),也就是说,它将使用函数func折叠(或累积或减少)来自patt的捕获。此捕获假设patt应该至少产生一个具有至少一个值(任何类型)的捕获,这将成为累加器的初始值。(如果您需要一个特定的初始值,您可以在patt前面添加一个常量捕获。)对于每个后续捕获,LPeg 使用此累加器作为第一个参数调用func,并将捕获生成的所有值作为额外参数;此调用中的第一个结果将成为累加器的新的值。累加器的最终值将成为捕获的值。
示例
local number = lpeg.R('09') ^ 1 / tonumber
local list = number * (',' * number) ^ 0
local function add(acc, newvalue) return acc + newvalue end
local sum = lpeg.Cf(list, add)
assert(sum:match('10,30,43') == 83)
参数
{patt} (vim.lpeg.Pattern|string|integer|boolean|table|function)
{func} (fun(acc, newvalue))
返回
(vim.lpeg.Capture)
vim.lpeg.Cg({patt}, {name}) vim.lpeg.Cg()
创建一个组捕获。它将由patt返回的所有值分组到单个捕获中。该组可以是匿名的(如果未给出名称)或使用给定名称命名(可以是任何非空 Lua 值)。
参数
{patt} (vim.lpeg.Pattern|string|integer|boolean|table|function)
{name} (string?)
返回
(vim.lpeg.Capture)
vim.lpeg.Cmt({patt}, {fn}) vim.lpeg.Cmt()
创建一个匹配时捕获。与所有其他捕获不同,此捕获在匹配发生时立即评估(即使它是稍后失败的更大模式的一部分)。它强制立即评估其所有嵌套捕获,然后调用function。给定的函数将整个主题、当前位置(在匹配patt之后)以及由patt产生的任何捕获值作为参数。由function返回的第一个值定义了匹配发生的方式。如果调用返回一个数字,则匹配成功,并且返回的数字将成为新的当前位置。(假设主题和当前位置为i,则返回的数字必须在范围[i, len(s) + 1]内。)如果调用返回true,则匹配成功,但不会消耗任何输入(因此,返回 true 等同于返回i)。如果调用返回falsenil或没有值,则匹配失败。由函数返回的任何额外值将成为捕获产生的值。
参数
{patt} (vim.lpeg.Pattern|string|integer|boolean|table|function)
{fn} (fun(s: string, i: integer, ...: any)) (position: boolean|integer, ...: any)
返回
(vim.lpeg.Capture)
vim.lpeg.Cp() vim.lpeg.Cp()
创建一个位置捕获。它匹配空字符串,并捕获匹配发生的主题中的位置。捕获的值是一个数字。
示例
local I = lpeg.Cp()
local function anywhere(p) return lpeg.P({I * p * I + 1 * lpeg.V(1)}) end
local match_start, match_end = anywhere('world'):match('hello world!')
assert(match_start == 7)
assert(match_end == 12)
返回
(vim.lpeg.Capture)
vim.lpeg.Cs({patt}) vim.lpeg.Cs()
创建一个替换捕获。此函数创建一个替换捕获,它捕获与patt匹配的主题的子字符串,并进行替换。对于patt内部具有值的任何捕获,与捕获匹配的子字符串将被捕获值(应该是字符串)替换。最终的捕获值是所有替换后得到的字符串。
示例
local function gsub (s, patt, repl)
  patt = lpeg.P(patt)
  patt = lpeg.Cs((patt / repl + 1) ^ 0)
  return lpeg.match(patt, s)
end
assert(gsub('Hello, xxx!', 'xxx', 'World') == 'Hello, World!')
参数
{patt} (vim.lpeg.Pattern|string|integer|boolean|table|function)
返回
(vim.lpeg.Capture)
vim.lpeg.Ct({patt}) vim.lpeg.Ct()
创建一个表捕获。此捕获返回一个表,其中包含由patt在此表内以连续的整数键(从 1 开始)进行的所有匿名捕获的值。此外,对于由patt创建的每个命名捕获组,该组的第一个值将使用组名称作为其键放入表中。捕获的值仅是该表。
参数
{patt} (vim.lpeg.Pattern|string|integer|boolean|table|function)
返回
(vim.lpeg.Capture)
vim.lpeg.locale({tab}) vim.lpeg.locale()
返回一个表,其中包含根据当前区域设置匹配某些字符类的模式。该表具有名为alnumalphacntrldigitgraphlowerprintpunctspaceupperxdigit的字段,每个字段都包含一个相应的模式。每个模式都匹配属于其类的任何单个字符。如果调用时带有参数table,则它将在给定的表中创建这些字段,并返回该表。
示例
lpeg.locale(lpeg)
local space = lpeg.space ^ 0
local name = lpeg.C(lpeg.alpha ^ 1) * space
local sep = lpeg.S(',;') * space
local pair = lpeg.Cg(name * '=' * space * name) * sep ^ -1
local list = lpeg.Cf(lpeg.Ct('') * pair ^ 0, rawset)
local t = list:match('a=b, c = hi; next = pi')
assert(t.a == 'b')
assert(t.c == 'hi')
assert(t.next == 'pi')
local locale = lpeg.locale()
assert(type(locale.digit) == 'userdata')
参数
{tab} (table?)
返回
(vim.lpeg.Locale)
vim.lpeg.match({pattern}, {subject}, {init}, {...}) vim.lpeg.match()
将给定的patternsubject字符串进行匹配。如果匹配成功,则返回匹配后第一个字符在subject中的索引,或者返回捕获的值(如果pattern捕获了任何值)。可选的数值参数init可以使匹配从subject字符串中的该位置开始。与 Lua 库中的惯例一样,负值从末尾开始计数。与典型的模式匹配函数不同,match仅在锚定模式下工作;也就是说,它尝试将模式与给定subject字符串的前缀(位于位置init处)匹配,而不是与subject的任意子字符串匹配。因此,如果我们想在字符串中的任何位置找到一个模式,我们必须要么在 Lua 中写一个循环,要么写一个在任何位置都匹配的模式。
示例
local pattern = lpeg.R('az') ^ 1 * -1
assert(pattern:match('hello') == 6)
assert(lpeg.match(pattern, 'hello') == 6)
assert(pattern:match('1 hello') == nil)
参数
{pattern} (vim.lpeg.Pattern|string|integer|boolean|table|function)
{subject} (string)
{init} (integer?)
{...} (any)
返回
(any) ...
vim.lpeg.P({value}) vim.lpeg.P()
将给定值转换为适当的模式。将应用以下规则
如果参数是一个模式,则它将被不修改地返回。
如果参数是一个字符串,则它将被转换为一个匹配字符串字面值的模式。
如果参数是一个非负数n,则结果是一个匹配恰好n个字符的模式。
如果参数是一个负数-n,则结果是一个模式,该模式仅在输入字符串的剩余字符少于n个时才成功:lpeg.P(-n)等效于-lpeg.P(n)(参见一元减运算符)。
如果参数是一个布尔值,则结果是一个模式,该模式始终成功或始终失败(根据布尔值),而不消耗任何输入。
如果参数是一个表,则它将被解释为一个语法(参见语法)。
如果参数是一个函数,则返回一个等效于对空字符串进行匹配时捕获的模式。
参数
{value} (vim.lpeg.Pattern|string|integer|boolean|table|function)
返回
(vim.lpeg.Pattern)
vim.lpeg.R({...}) vim.lpeg.R()
返回一个模式,该模式匹配属于给定范围之一的任何单个字符。每个range是一个长度为 2 的字符串xy,表示所有代码介于xy(包括两者)的代码之间的字符。例如,模式lpeg.R('09')匹配任何数字,而lpeg.R('az', 'AZ')匹配任何 ASCII 字母。
示例
local pattern = lpeg.R('az') ^ 1 * -1
assert(pattern:match('hello') == 6)
参数
{...} (string)
返回
(vim.lpeg.Pattern)
vim.lpeg.S({string}) vim.lpeg.S()
返回一个模式,该模式匹配出现在给定字符串中的任何单个字符(S代表集合)。例如,模式lpeg.S('+-*/')匹配任何算术运算符。请注意,如果s是一个字符(即长度为 1 的字符串),则lpeg.P(s)等效于lpeg.S(s),而lpeg.S(s)等效于lpeg.R(s..s)。还要注意,lpeg.S('')lpeg.R()都是始终失败的模式。
参数
{string} (string)
返回
(vim.lpeg.Pattern)
vim.lpeg.setmaxstack({max}) vim.lpeg.setmaxstack()
为 LPeg 用于跟踪调用和选择的回溯堆栈的大小设置限制。默认限制为400。大多数编写良好的模式只需要很少的回溯级别,因此您很少需要更改此限制;在更改它之前,您应该尝试重写您的模式以避免对额外空间的需要。但是,一些有用的模式可能会溢出。此外,对于递归语法,具有深度递归的主题可能也需要更大的限制。
参数
{max} (integer)
vim.lpeg.type({value}) vim.lpeg.type()
如果给定值为一个模式,则返回字符串"pattern",否则返回nil
参数
{value} (vim.lpeg.Pattern|string|integer|boolean|table|function)
返回
("pattern"?)
vim.lpeg.V({v}) vim.lpeg.V()
为语法创建一个非终结符(变量)。此操作为语法创建一个非终结符(变量)。创建的非终结符引用封闭语法中索引为v的规则。
示例
local b = lpeg.P({'(' * ((1 - lpeg.S '()') + lpeg.V(1)) ^ 0 * ')'})
assert(b:match('((string))') == 11)
assert(b:match('(') == nil)
参数
{v} (boolean|string|number|function|table|thread|userdata|lightuserdata)
返回
(vim.lpeg.Pattern)
vim.lpeg.version() vim.lpeg.version()
返回一个包含 LPeg 运行版本的字符串。
返回
(string)

VIM.RE vim.re

vim.re 模块为 LPeg vim.lpeg 中的模式使用提供了一种传统的类似正则表达式的语法。(与 vim.regex 无关,vim.regex 从 Lua 提供 Vim regexp。)
有关原始文档(包括正则表达式语法和示例),请参见 https://www.inf.puc-rio.br/~roberto/lpeg/re.html
vim.re.compile({string}, {defs}) vim.re.compile()
编译给定的{string},并返回一个等效的 LPeg 模式。给定的字符串可以定义表达式或语法。可选的{defs}表提供额外的 Lua 值供模式使用。
参数
{string} (string)
{defs} (table?)
返回
(vim.lpeg.Pattern)
vim.re.find({subject}, {pattern}, {init}) vim.re.find()
在给定的{subject}中搜索给定的{pattern}。如果找到匹配项,则返回该匹配项开始的索引和结束的索引。否则返回 nil。
可选的数字参数{init} 使搜索从主题字符串中的该位置开始。与 Lua 库中通常一样,负值从末尾开始计数。
参数
{subject} (string)
{pattern} (vim.lpeg.Pattern|string)
{init} (integer?)
返回(多个)
(integer?) 匹配项开始的索引,如果未匹配则为 nil (integer?) 匹配项结束的索引,如果未匹配则为 nil
vim.re.gsub({subject}, {pattern}, {replacement}) vim.re.gsub()
执行全局替换,将给定{subject}中的所有{pattern} 替换为{replacement}
参数
{subject} (string)
{pattern} (vim.lpeg.Pattern|string)
{replacement} (string)
返回
(string)
vim.re.match({subject}, {pattern}, {init}) vim.re.match()
将给定的{pattern} 与给定的{subject} 匹配,返回所有捕获。
参数
{subject} (string)
{pattern} (vim.lpeg.Pattern|string)
{init} (integer?)
返回
(integer|vim.lpeg.Capture?)
另请参阅
vim.lpeg.match()
vim.re.updatelocale() vim.re.updatelocale()
将预定义的字符类更新到当前区域设置。

VIM.REGEX vim.regex

Vim 正则表达式可以直接从 Lua 中使用。目前它们只允许在单行内匹配。
regex:match_line()
regex:match_line({bufnr}, {line_idx}, {start}, {end_}) 匹配缓冲区bufnrline_idx (基于零) 处的行。如果给定,则匹配限制在字节索引范围startend_ 内,否则参见regex:match_str()。如果给定,则返回的字节索引相对于start
参数
{bufnr} (integer)
{line_idx} (integer)
{start} (integer?)
{end_} (integer?)
返回(多个)
(integer?) 匹配开始 (字节索引),相对于start,或如果未匹配则为nil (integer?) 匹配结束 (字节索引),相对于start,或如果未匹配则为nil
regex:match_str({str}) regex:match_str()
将字符串str 与该正则表达式匹配。要精确匹配字符串,请在正则表达式周围加上 "^" 和 "$"。返回匹配项的开始和结束的字节索引,或者如果未匹配则返回nil。因为任何整数都是 "truthy",所以regex:match_str() 可以直接用作 if 语句中的条件。
参数
{str} (string)
返回(多个)
(integer?) 匹配开始 (字节索引),或如果未匹配则为nil (integer?) 匹配结束 (字节索引),或如果未匹配则为nil
vim.regex({re}) vim.regex()
解析 Vim 正则表达式re 并返回一个正则表达式对象。正则表达式默认情况下是 "magic" 且区分大小写,无论'magic''ignorecase' 是什么。它们可以用标志控制,参见/magic/ignorecase
参数
{re} (string)
返回
(vim.regex)

Lua 模块:vim.secure vim.secure

vim.secure.read({path}) vim.secure.read()
尝试读取{path} 处的文件,如果需要信任该文件,则提示用户。用户的选择将保存在 $XDG_STATE_HOME/nvim/trust 中的信任数据库中。
属性
自:0.9.0
参数
{path} (string) 要读取的文件的路径。
返回
(string?) 如果给定文件存在且受信任,则为该文件的内容,否则为 nil。
另请参阅
vim.secure.trust({opts}) vim.secure.trust()
管理信任数据库。
信任数据库位于 $XDG_STATE_HOME/nvim/trust。
属性
自:0.9.0
参数
{opts} (table) 包含以下字段的表
{action} ('allow'|'deny'|'remove') - 'allow' 将文件添加到信任数据库并信任它,
'deny' 将文件添加到信任数据库并拒绝它,
'remove' 从信任数据库中删除文件
{path} (string) 要更新的文件的路径。与{bufnr} 互斥。当{action} 为 "allow" 时不可使用。
{bufnr} (integer) 要更新的缓冲区编号。与{path} 互斥。
返回(多个)
(boolean) 成功 如果操作成功 (string) msg 如果操作成功,则为完整路径,否则为错误消息

Lua 模块:vim.version vim.version

vim.version 模块提供了用于比较版本和符合 https://semver.org 规范的范围的函数。插件和插件管理器可以使用它来检查当前系统上可用的工具和依赖项。
示例
local v = vim.version.parse(vim.fn.system({'tmux', '-V'}), {strict=false})
if vim.version.gt(v, {3, 2, 0}) then
  -- ...
end
vim.version() 返回当前 Nvim 进程的版本。

版本范围规范 version-range

版本 "范围规范" 定义了一个语义版本范围,可以使用 vim.version.range() 对其进行测试。
支持的范围规范显示在下表中。注意: 后缀版本 (1.2.3-rc1) 不匹配。
1.2.3             is 1.2.3
=1.2.3            is 1.2.3
>1.2.3            greater than 1.2.3
<1.2.3            before 1.2.3
>=1.2.3           at least 1.2.3
~1.2.3            is >=1.2.3 <1.3.0       "reasonably close to 1.2.3"
^1.2.3            is >=1.2.3 <2.0.0       "compatible with 1.2.3"
^0.2.3            is >=0.2.3 <0.3.0       (0.x.x is special)
^0.0.1            is =0.0.1               (0.0.x is special)
^1.2              is >=1.2.0 <2.0.0       (like ^1.2.0)
~1.2              is >=1.2.0 <1.3.0       (like ~1.2.0)
^1                is >=1.0.0 <2.0.0       "compatible with 1"
~1                same                    "reasonably close to 1"
1.x               same
1.*               same
1                 same
*                 any version
x                 same
1.2.3 - 2.3.4     is >=1.2.3 <=2.3.4
Partial right: missing pieces treated as x (2.3 => 2.3.x).
1.2.3 - 2.3       is >=1.2.3 <2.4.0
1.2.3 - 2         is >=1.2.3 <3.0.0
Partial left: missing pieces treated as 0 (1.2 => 1.2.0).
1.2 - 2.3.0       is 1.2.0 - 2.3.0
vim.version.cmp({v1}, {v2}) vim.version.cmp()
解析并比较两个版本对象(vim.version.parse() 的结果,或直接指定为{major, minor, patch} 元组,例如 {1, 0, 3})。
示例
if vim.version.cmp({1,0,3}, {0,2,1}) == 0 then
  -- ...
end
local v1 = vim.version.parse('1.0.3-pre')
local v2 = vim.version.parse('0.2.1')
if vim.version.cmp(v1, v2) == 0 then
  -- ...
end
注意
根据 semver,在比较两个否则等效的版本时,会忽略构建元数据。
属性
自:0.9.0
参数
{v1} (vim.Version|number[]|string) 版本对象。
{v2} (vim.Version|number[]|string) 要与v1 比较的版本。
返回
(integer) -1 如果v1 < v2,0 如果v1 == v2,1 如果v1 > v2
vim.version.eq({v1}, {v2}) vim.version.eq()
如果给定的版本相等,则返回true。有关用法,请参见 vim.version.cmp()
属性
自:0.9.0
参数
{v1} (vim.Version|number[]|string)
{v2} (vim.Version|number[]|string)
返回
(boolean)
vim.version.ge({v1}, {v2}) vim.version.ge()
如果v1 >= v2,则返回true。有关用法,请参见 vim.version.cmp()
属性
自: 0.10.0
参数
{v1} (vim.Version|number[]|string)
{v2} (vim.Version|number[]|string)
返回
(boolean)
vim.version.gt({v1}, {v2}) vim.version.gt()
如果v1 > v2,则返回true。有关用法,请参见 vim.version.cmp()
属性
自:0.9.0
参数
{v1} (vim.Version|number[]|string)
{v2} (vim.Version|number[]|string)
返回
(boolean)
vim.version.last({versions}) vim.version.last()
TODO:将此功能泛化,移动到 func.lua
参数
{versions} (vim.Version[])
返回
(vim.Version?)
vim.version.le({v1}, {v2}) vim.version.le()
如果v1 <= v2,则返回true。有关用法,请参见 vim.version.cmp()
属性
自: 0.10.0
参数
{v1} (vim.Version|number[]|string)
{v2} (vim.Version|number[]|string)
返回
(boolean)
vim.version.lt({v1}, {v2}) vim.version.lt()
如果v1 < v2,则返回true。有关用法,请参见 vim.version.cmp()
属性
自:0.9.0
参数
{v1} (vim.Version|number[]|string)
{v2} (vim.Version|number[]|string)
返回
(boolean)
vim.version.parse({version}, {opts}) vim.version.parse()
解析语义版本字符串并返回一个版本对象,该对象可以与其他vim.version 函数一起使用。例如 "1.0.1-rc1+build.2" 返回
{ major = 1, minor = 0, patch = 1, prerelease = "rc1", build = "build.2" }
属性
自:0.9.0
参数
{version} (string) 要解析的版本字符串。
{opts} (table?) 可选的关键字参数
strict (boolean):默认值为 false。如果true,则不会对不符合 semver v2.0.0 的输入进行强制转换。如果falseparse() 将尝试对 "1.0"、"0-x"、"tmux 3.2a" 等输入进行强制转换,使其成为有效的版本。
返回
(vim.Version?) parsed_version 版本对象,如果输入无效则为nil
vim.version.range({spec}) vim.version.range()
解析 semver version-range "规范" 并返回一个范围对象
{
  from: Version
  to: Version
  has(v: string|Version)
}
:has() 检查版本是否在范围内(包含from,不包含to)。
示例
local r = vim.version.range('1.0.0 - 2.0.0')
print(r:has('1.9.9'))       -- true
print(r:has('2.0.0'))       -- false
print(r:has(vim.version())) -- check against current Nvim version
或者使用 cmp()、le()、lt()、ge()、gt() 和/或 eq() 直接将版本与.to.from 进行比较
local r = vim.version.range('1.0.0 - 2.0.0') -- >=1.0, <2.0
print(vim.version.ge({1,0,3}, r.from) and vim.version.lt({1,0,3}, r.to))
属性
自:0.9.0
参数
{spec} (string) 版本范围 "规范"
返回
(table?) 包含以下字段的表
{from} (vim.Version)
{to} (vim.Version)

Lua 模块:vim.iter vim.iter

vim.iter()iterable 的接口:它将表或函数参数包装到一个 Iter 对象中,该对象具有方法(例如 Iter:filter()Iter:map()),这些方法可以转换底层源数据。这些方法可以链接起来创建迭代器 "管道":每个管道阶段的输出都是下一个阶段的输入。第一个阶段取决于传递给vim.iter() 的类型
列表或数组 (lua-list) 只生成每个元素的值。
允许存在空洞 (nil 值) (但会被丢弃)。
使用 pairs() 将数组/列表表视为字典 (保留空洞和非连续整数键):vim.iter(pairs(…))
使用 Iter:enumerate() 将索引也传递给下一个阶段。
或者使用 ipairs() 初始化:vim.iter(ipairs(…))
非列表表 (lua-dict) 同时生成每个元素的键和值。
函数 iterator 生成底层函数返回的所有值。
具有 __call() 元方法的表将被视为函数迭代器。
当底层 iterable 耗尽时,迭代器管道将终止 (对于函数迭代器,这意味着它返回了 nil)。
注意: vim.iter() 扫描表输入以确定它是一个列表还是一个字典;为了避免这种成本,可以使用迭代器包装表,例如 vim.iter(ipairs({…})),但这将阻止使用 list-iterator 操作,例如 Iter:rev())。
示例
local it = vim.iter({ 1, 2, 3, 4, 5 })
it:map(function(v)
  return v * 3
end)
it:rev()
it:skip(2)
it:totable()
-- { 9, 6, 3 }
-- ipairs() is a function iterator which returns both the index (i) and the value (v)
vim.iter(ipairs({ 1, 2, 3, 4, 5 })):map(function(i, v)
  if i > 2 then return v end
end):totable()
-- { 3, 4, 5 }
local it = vim.iter(vim.gsplit('1,2,3,4,5', ','))
it:map(function(s) return tonumber(s) end)
for i, d in it:enumerate() do
  print(string.format("Column %d is %d", i, d))
end
-- Column 1 is 1
-- Column 2 is 2
-- Column 3 is 3
-- Column 4 is 4
-- Column 5 is 5
vim.iter({ a = 1, b = 2, c = 3, z = 26 }):any(function(k, v)
  return k == 'z'
end)
-- true
local rb = vim.ringbuf(3)
rb:push("a")
rb:push("b")
vim.iter(rb):totable()
-- { "a", "b" }
Iter:all({pred}) Iter:all()
如果迭代器中的所有项目都与给定的谓词匹配,则返回 true。
参数
{pred} (fun(...):boolean) 谓词函数。将管道中前一阶段返回的所有值作为参数,如果谓词匹配则返回 true。
Iter:any({pred}) Iter:any()
如果迭代器中的任何项目都与给定的谓词匹配,则返回 true。
参数
{pred} (fun(...):boolean) 谓词函数。将管道中前一阶段返回的所有值作为参数,如果谓词匹配则返回 true。
Iter:each({f}) Iter:each()
对管道中的每个项目调用一次函数,清空迭代器。
对于具有副作用的函数。要修改迭代器中的值,请使用 Iter:map()
参数
{f} (fun(...)) 要对管道中的每个项目执行的函数。将管道中前一阶段返回的所有值作为参数。
Iter:enumerate() Iter:enumerate()
为迭代器管道的每个项目生成项目索引 (计数) 和值。
对于列表表,这更有效率
vim.iter(ipairs(t))
而不是
vim.iter(t):enumerate()
示例
local it = vim.iter(vim.gsplit('abc', '')):enumerate()
it:next()
-- 1        'a'
it:next()
-- 2        'b'
it:next()
-- 3        'c'
返回
(Iter)
Iter:filter({f}) Iter:filter()
过滤迭代器管道。
示例
local bufs = vim.iter(vim.api.nvim_list_bufs()):filter(vim.api.nvim_buf_is_loaded)
参数
{f} (fun(...):boolean) 获取管道中前一阶段返回的所有值,如果当前迭代器元素应该被移除,则返回 false 或 nil。
返回
(Iter)
Iter:find({f}) Iter:find()
在迭代器中查找第一个满足给定谓词的值。
前进迭代器。如果未找到值,则返回 nil 并清空迭代器。
示例
local it = vim.iter({ 3, 6, 9, 12 })
it:find(12)
-- 12
local it = vim.iter({ 3, 6, 9, 12 })
it:find(20)
-- nil
local it = vim.iter({ 3, 6, 9, 12 })
it:find(function(v) return v % 4 == 0 end)
-- 12
参数
{f} (any)
返回
(any)
Iter:flatten({depth}) Iter:flatten()
将一个 列表迭代器 展平,将嵌套的值解开到给定的 {depth}。如果尝试展平类似字典的值,则会报错。
示例
vim.iter({ 1, { 2 }, { { 3 } } }):flatten():totable()
-- { 1, 2, { 3 } }
vim.iter({1, { { a = 2 } }, { 3 } }):flatten():totable()
-- { 1, { a = 2 }, 3 }
vim.iter({ 1, { { a = 2 } }, { 3 } }):flatten(math.huge):totable()
-- error: attempt to flatten a dict-like table
参数
{depth} (number?) 列表迭代器 应展平到的深度(默认为 1)
返回
(Iter)
Iter:fold({init}, {f}) Iter:fold()
将一个迭代器折叠(“归约”)成一个值。 Iter:reduce()
示例
-- Create a new table with only even values
vim.iter({ a = 1, b = 2, c = 3, d = 4 })
  :filter(function(k, v) return v % 2 == 0 end)
  :fold({}, function(acc, k, v)
    acc[k] = v
    return acc
  end) --> { b = 2, d = 4 }
-- Get the "maximum" item of an iterable.
vim.iter({ -99, -4, 3, 42, 0, 0, 7 })
  :fold({}, function(acc, v)
    acc.max = math.max(v, acc.max or v)
    return acc
  end) --> { max = 42 }
参数
{init} (any) 累加器的初始值。
{f} (fun(acc:A, ...):A) 累加函数。
返回
(any)
Iter:join({delim}) Iter:join()
将迭代器收集成一个带分隔符的字符串。
迭代器中的每个元素都被连接到一个字符串中,用 {delim} 分隔。
消耗迭代器。
参数
{delim} (string) 分隔符
返回
(string)
Iter:last() Iter:last()
清空迭代器并返回最后一项。
示例
local it = vim.iter(vim.gsplit('abcdefg', ''))
it:last()
-- 'g'
local it = vim.iter({ 3, 6, 9, 12, 15 })
it:last()
-- 15
返回
(any)
另请参阅
Iter.rpeek
Iter:map({f}) Iter:map()
将迭代器管道的项映射到 f 返回的值。
如果映射函数返回 nil,则该值将从迭代器中过滤掉。
示例
local it = vim.iter({ 1, 2, 3, 4 }):map(function(v)
  if v % 2 == 0 then
    return v * 3
  end
end)
it:totable()
-- { 6, 12 }
参数
{f} (fun(...):...:any) 映射函数。将管道中前一阶段返回的所有值作为参数,并返回一个或多个新值,这些值将在管道下一阶段使用。Nil 返回值将从输出中过滤掉。
返回
(Iter)
Iter:next() Iter:next()
从迭代器中获取下一个值。
示例
local it = vim.iter(string.gmatch('1 2 3', '%d+')):map(tonumber)
it:next()
-- 1
it:next()
-- 2
it:next()
-- 3
返回
(any)
Iter:nth({n}) Iter:nth()
获取迭代器的第 n 个值(并前进到它)。
如果 n 为负数,则从 列表迭代器 的末尾偏移。
示例
local it = vim.iter({ 3, 6, 9, 12 })
it:nth(2)
-- 6
it:nth(2)
-- 12
local it2 = vim.iter({ 3, 6, 9, 12 })
it2:nth(-2)
-- 9
it2:nth(-2)
-- 3
参数
{n} (number) 要返回的值的索引。如果源是 列表迭代器,则可以为负数。
返回
(any)
Iter:peek() Iter:peek()
获取 列表迭代器 中的下一个值,而不消耗它。
示例
local it = vim.iter({ 3, 6, 9, 12 })
it:peek()
-- 3
it:peek()
-- 3
it:next()
-- 3
返回
(any)
Iter:pop() Iter:pop()
列表迭代器 中“弹出”一个值(获取最后一个值并递减尾部)。
示例
local it = vim.iter({1, 2, 3, 4})
it:pop()
-- 4
it:pop()
-- 3
返回
(any)
Iter:rev() Iter:rev()
反转 列表迭代器 管道。
示例
local it = vim.iter({ 3, 6, 9, 12 }):rev()
it:totable()
-- { 12, 9, 6, 3 }
返回
(Iter)
Iter:rfind({f}) Iter:rfind()
列表迭代器 的末尾获取第一个满足谓词的值。
前进迭代器。如果未找到值,则返回 nil 并清空迭代器。
示例
local it = vim.iter({ 1, 2, 3, 2, 1 }):enumerate()
it:rfind(1)
-- 5        1
it:rfind(1)
-- 1        1
参数
{f} (any)
返回
(any)
另请参阅
Iter.find
Iter:rpeek() Iter:rpeek()
获取 列表迭代器 中的最后一个值,而不消耗它。
示例
local it = vim.iter({1, 2, 3, 4})
it:rpeek()
-- 4
it:rpeek()
-- 4
it:pop()
-- 4
返回
(any)
另请参阅
Iter.last
Iter:rskip({n}) Iter:rskip()
列表迭代器 管道末尾丢弃 n 个值。
示例
local it = vim.iter({ 1, 2, 3, 4, 5 }):rskip(2)
it:next()
-- 1
it:pop()
-- 3
参数
{n} (number) 要跳过的值的数量。
返回
(Iter)
Iter:skip({n}) Iter:skip()
跳过迭代器管道的 n 个值。
示例
local it = vim.iter({ 3, 6, 9, 12 }):skip(2)
it:next()
-- 9
参数
{n} (number) 要跳过的值的数量。
返回
(Iter)
Iter:slice({first}, {last}) Iter:slice()
设置 列表迭代器 管道的开始和结束。
等效于 :skip(first - 1):rskip(len - last + 1)
参数
{first} (number)
{last} (number)
返回
(Iter)
Iter:take({n}) Iter:take()
将迭代器转换为仅生成前 n 个值的迭代器。
示例
local it = vim.iter({ 1, 2, 3, 4 }):take(2)
it:next()
-- 1
it:next()
-- 2
it:next()
-- nil
参数
{n} (integer)
返回
(Iter)
Iter:totable() Iter:totable()
将迭代器收集到一个表中。
生成的表取决于迭代器管道中的初始源。类似数组的表和函数迭代器将被收集到类似数组的表中。如果迭代器管道中最后一阶段返回多个值,则每个值都将包含在表中。
示例
vim.iter(string.gmatch('100 20 50', '%d+')):map(tonumber):totable()
-- { 100, 20, 50 }
vim.iter({ 1, 2, 3 }):map(function(v) return v, 2 * v end):totable()
-- { { 1, 2 }, { 2, 4 }, { 3, 6 } }
vim.iter({ a = 1, b = 2, c = 3 }):filter(function(k, v) return v % 2 ~= 0 end):totable()
-- { { 'a', 1 }, { 'c', 3 } }
生成的表是一个类似数组的表,具有连续的数字索引。要创建具有任意键的类似映射的表,请使用 Iter:fold()
返回
(table)

Lua 模块:vim.snippet vim.snippet

字段
{direction} (vim.snippet.Direction) 导航方向。-1 表示上一个,1 表示下一个。
vim.snippet.active({filter}) vim.snippet.active()
如果当前缓冲区中存在活动片段,则返回 true,如果提供了给定的过滤器,则应用该过滤器。
您可以使用此函数以如下方式导航片段
vim.keymap.set({ 'i', 's' }, '<Tab>', function()
   if vim.snippet.active({ direction = 1 }) then
     return '<Cmd>lua vim.snippet.jump(1)<CR>'
   else
     return '<Tab>'
   end
 end, { expr = true })
参数
{filter} (vim.snippet.ActiveFilter?) 用于限制搜索的过滤器
direction (vim.snippet.Direction):导航方向。如果可以在给定方向上跳转片段,则将返回 true。请参阅 vim.snippet.ActiveFilter
返回
(boolean)
vim.snippet.expand({input}) vim.snippet.expand()
展开给定的片段文本。有关有效输入的规范,请参阅 https://microsoft.github.io/language-server-protocol/specification/#snippet_syntax
制表符使用 hl-SnippetTabstop 进行高亮显示。
参数
{input} (string)
vim.snippet.jump({direction}) vim.snippet.jump()
如果可能,跳转到当前片段中的下一个(或上一个)占位符。
例如,将 <Tab> 映射到片段处于活动状态时跳转
vim.keymap.set({ 'i', 's' }, '<Tab>', function()
   if vim.snippet.active({ direction = 1 }) then
     return '<Cmd>lua vim.snippet.jump(1)<CR>'
   else
     return '<Tab>'
   end
 end, { expr = true })
参数
{direction} (vim.snippet.Direction) 导航方向。-1 表示上一个,1 表示下一个。
vim.snippet.stop() vim.snippet.stop()
退出当前片段。

Lua 模块:vim.text vim.text

vim.text.hexdecode({enc}) vim.text.hexdecode()
对字符串进行十六进制解码。
参数
{enc} (string) 要解码的字符串
返回(多个)
(string?) 解码后的字符串 (string?) 错误消息(如果有)
vim.text.hexencode({str}) vim.text.hexencode()
对字符串进行十六进制编码。
参数
{str} (string) 要编码的字符串
返回
(string) 十六进制编码的字符串

Lua 模块:tohtml vim.tohtml

:[range]TOhtml {file} :TOhtml
将当前窗口中显示的缓冲区转换为 HTML,在新拆分的窗口中打开生成的 HTML,并将内容保存到 {file}。如果没有给出 {file},则使用一个临时文件(由 tempname() 创建)。
tohtml.tohtml({winid}, {opt}) tohtml.tohtml.tohtml()
将窗口 {winid} 中显示的缓冲区转换为 HTML,并以字符串列表的形式返回输出。
参数
{winid} (integer?) 要转换的窗口(默认为当前窗口)
{opt} (table?) 可选参数。
{title} (string|false, 默认:缓冲区名称) 在生成的 HTML 代码中设置的标题标签。
{number_lines} (boolean, 默认:false) 显示行号。
{font} (string[]|string, 默认:guifont) 要使用的字体。
{width} (integer, 默认:如果 'textwidth' 不为零,则使用它,否则使用窗口宽度) 用于右对齐或无限重复字符的项目的宽度。
{range} (integer[], 默认:整个缓冲区) 要使用的行范围。
返回
(string[])
主要
命令索引
快速参考