Browse Source

fix typo and pretty doc (#5)

pull/7/head
Lin Yang 4 years ago
committed by GitHub
parent
commit
65b1acf134
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 170
      README.md

170
README.md

@ -6,11 +6,11 @@
## 目录
- [neovim 中使用 Lua](#在-neovim-中使用-lua)
- [Neovim 中使用 Lua](#在-neovim-中使用-lua)
- [目录](#目录)
- [简介](#简介)
- [学习 Lua](#学习-lua)
- [现有的一些在 neovim 中使用 Lua 的教程](#现有的一些在-neovim-中使用-lua-的教程)
- [现有的一些在 Neovim 中使用 Lua 的教程](#现有的一些在-neovim-中使用-lua-的教程)
- [相关插件](#相关插件)
- [Lua 文件位置](#lua-文件位置)
- [警告](#警告)
@ -59,23 +59,23 @@
## 简介
Lua 作为 Neovim 中的一等语言的集成正在成为它的杀手级特性之一。 然而,学习如何用 Lua 编写插件的教程数量并不像用 Vimscript 编写插件那样多。 这是一种尝试,试图提供一些基本信息,让人们可以使用 Lua 编写 neovim 插件。
本指南假定您使用的是最新的 Neovim[Nighly build](https://github.com/neovim/neovim/releases/tag/nightly)]。 由于 Neovim 的 0.5 版本是开发版本,请记住,正在积极开发的一些 API 并不十分稳定,
在发布之前可能会发生变化。
Lua 作为 Neovim 中的一等语言的集成正在成为它的杀手级特性之一。然而,学习如何用 Lua 编写插件的教程数量并不像用 Vimscript 编写插件那样多。这是一种尝试,试图提供一些基本信息,让人们可以使用 Lua 编写 Neovim 插件。
本指南假定您使用的是最新的 Neovim [Nighly build](https://github.com/neovim/neovim/releases/tag/nightly)。由于 Neovim 的 0.5 版本是开发版本,请记住,正在积极开发的一些 API 并不十分稳定,在发布之前可能会发生变化。
### 学习 Lua
不同于原版教程,下资源适用于国内用户:
不同于原版教程,下资源适用于国内用户:
- [在 Y 分钟内学习 X 关于 Lua 的页面](https://learnxinyminutes.com/docs/lua/)
- [Lua 菜鸟教程](https://www.runoob.com/lua/lua-tutorial.html)
- [Lua 用户维基](http://lua-users.org/wiki/LuaDirectory)
- [Lua 的官方参考手册](https://www.lua.org/manual/5.1/)
Lua 是一种非常干净和简单的语言。 它很容易学习,特别是如果你有其他编程语言基础的例如 typescript/javascript 等,会更加容易上手 Lua。注意:Neovim 嵌入的 Lua 版本是 LuaJIT 2.1.0,它与 Lua 5.1 保持兼容(带有几个 5.2 扩展)
Lua 是一种非常干净和简单的语言。它很容易学习,特别是如果你有其他编程语言基础的例如 TypeScript / JavaScript 等,会更加容易上手 Lua。注意:Neovim 嵌入的 Lua 版本是 LuaJIT 2.1.0,它与 Lua 5.1 保持兼容(带有几个 5.2 扩展)
### 现有的一些在 neovim 中使用 Lua 的教程
### 现有的一些在 Neovim 中使用 Lua 的教程
已经编写了一些教程来帮助人们用 Lua 编写插件。 他们中的一些人在写这本指南时提供了不少的帮助。 非常感谢它们的作者。
已经编写了一些教程来帮助人们用 Lua 编写插件。他们中的一些人在写这本指南时提供了不少的帮助。非常感谢它们的作者。
- [teukka.tech - 从 init.vim 转到 init.lua](https://teukka.tech/luanvim.html)
- [2n.pl - 如何使用 Lua 编写 neovim 插件](https://www.2n.pl/blog/how-to-write-neovim-plugins-in-lua.md)
@ -96,7 +96,7 @@ Lua 是一种非常干净和简单的语言。 它很容易学习,特别是如
## Lua 文件位置
Lua 文件通常位于您的`runtimepath`中的`lua/`文件夹中(对于大多数用户来说,在*nix 系统上为`~/.config/nvim/lua`,在 Windows 系统上为`~/appdata/Local/nvim/lua`)。 `Package.path``Package.cpath`全局变量会自动调整为包含该文件夹下的 Lua 文件。 这意味着您可以`require()`这些文件作为 Lua 模块
Lua 文件通常位于您的 `runtimepath` 中的 `lua/` 文件夹中(对于大多数用户来说,在 *nix 系统上为 `~/.config/nvim/lua`,在 Windows 系统上为 `~/appdata/Local/nvim/lua`)。`Package.path``Package.cpath` 全局变量会自动调整为包含该文件夹下的 Lua 文件。这意味着您可以 `require()` 这些文件作为 Lua 模块
我们以下面的文件夹结构为例:
@ -115,15 +115,15 @@ Lua 文件通常位于您的`runtimepath`中的`lua/`文件夹中(对于大多
└── 🇻 init.vim
```
下面的 Lua 代码将加载`myluamodule.lua`
下面的 Lua 代码将加载 `myluamodule.lua`
```lua
require('myluamodule')
```
注意没有`.lua`扩展名。
注意没有 `.lua` 扩展名。
类似地,加载`ther_module/anthermodule e.lua`的过程如下:
类似地,加载 `other_modules/anothermodule.lua` 的过程如下:
```lua
require('other_modules.anothermodule')
@ -131,9 +131,9 @@ require('other_modules.anothermodule')
require('other_modules/anothermodule')
```
路径分隔符可以用点`.`表示,也可以用斜杠`/`表示。
路径分隔符可以用点 `.` 表示,也可以用斜杠 `/` 表示。
文件夹如果包含`init.lua`文件,可以直接引用该文件夹而不必指定该文件的名称
文件夹如果包含 `init.lua` 文件,可以直接引用该文件夹而不必指定该文件的名称
```lua
require('other_modules') -- loads other_modules/init.lua
@ -143,32 +143,32 @@ require('other_modules') -- loads other_modules/init.lua
#### 警告
与.vim 文件不同,.lua 文件不会自动从您的`runtimepath`目录中获取。 相反,您必须从 Vimscript source/require 它们。 计划增加`init.lua`文件加载选项,替代`init.vim`:
.vim 文件不同,.lua 文件不会自动从您的 `runtimepath` 目录中获取。相反,您必须从 Vimscript source/require 它们。计划增加 `init.lua` 文件加载选项,替代 `init.vim`
- [Issue #7895](https://github.com/neovim/neovim/issues/7895)
- [Corresponding pull request](https://github.com/neovim/neovim/pull/12235)
#### 提示
多个 Lua 插件在它们的`lua/`文件夹中可能有相同的文件名。 这可能会导致命名空间冲突。如果两个不同的插件有一个`lua/main.lua`文件,那么执行`require('main')`是不明确的:我们想要加载哪个文件?最好将您的配置或插件命名为顶级文件夹,
多个 Lua 插件在它们的 `lua/` 文件夹中可能有相同的文件名。这可能会导致命名空间冲突。如果两个不同的插件有一个 `lua/main.lua` 文件,那么执行 `require('main')` 是不明确的:我们想要加载哪个文件?最好将您的配置或插件命名为顶级文件夹,
例如这样的形式:`lua/plugin_name/main.lua`。
#### 包说明
如果您是`package`特性的用户或基于它的插件管理器例如 [packer.nvim](https://github.com/wbthomason/packer.nvim),[minpac](https://github.com/k-takata/minpac) 或 [vim-packager](https://github.com/kristijanhusak/vim-packager/),那么在使用 Lua 插件时需要注意一些事情。`start`文件夹中的包只有在源化您的`init.vim`之后才会加载。 这意味着只有在 Neovim 处理完文件之后,才会将包添加到`runtimepath`中。如果插件期望
`require`一个 Lua 模块或调用自动加载的函数,这可能会导致问题。假设包`start/foo`有一个`lua/bar.lua`文件,从您的`init.vim`执行此操作将引发错误,因为`runtimepath`尚未更新。
如果您是 `package` 特性的用户或基于它的插件管理器例如 [packer.nvim](https://github.com/wbthomason/packer.nvim),[minpac](https://github.com/k-takata/minpac) 或 [vim-packager](https://github.com/kristijanhusak/vim-packager/),那么在使用 Lua 插件时需要注意一些事情。`start` 文件夹中的包只有在源化您的 `init.vim` 之后才会加载。这意味着只有在 Neovim 处理完文件之后,才会将包添加到 `runtimepath` 中。如果插件期望
`require` 一个 Lua 模块或调用自动加载的函数,这可能会导致问题。假设包 `start/foo` 有一个 `lua/bar.lua` 文件,从您的 `init.vim` 执行此操作将引发错误,因为 `runtimepath` 尚未更新。
```vim
lua require('bar')
```
你需要使用`packadd! foo`命令在`require` 这个模块之前
你需要使用 `packadd! foo` 命令在 `require` 这个模块之前
```vim
packadd! foo
lua require('bar')
```
`Packadd`后附加`!`表示 Neovim 会将包放在`runtimepath`中,而不会在其`plugin`或`ftDetect`目录下寻找任何脚本。
`Packadd` 后附加 `!` 表示 Neovim 会将包放在 `runtimepath` 中,而不会在其 `plugin``ftDetect` 目录下寻找任何脚本。
See also:
- `:help :packadd`
@ -208,19 +208,19 @@ See also:
#### 警告
vim 文件中编写 Lua 时,您不会得到正确的语法突出显示。 使用`:lua`命令作为需要外部 Lua 文件的入口点可能会更方便。
Vim 文件中编写 Lua 时,您不会得到正确的语法突出显示。使用 `:lua` 命令作为需要外部 Lua 文件的入口点可能会更方便。
### :luado
该命令执行一段 Lua 代码,该代码作用于当前缓冲区中的选中的行。 如果未指定范围,则改为使用整个缓冲区。 从块`return`的任何字符串都用于确定应该用什么替换每行。
该命令执行一段 Lua 代码,该代码作用于当前缓冲区中的选中的行。如果未指定范围,则改为使用整个缓冲区。从块 `return` 的任何字符串都用于确定应该用什么替换每行。
以下命令会将当前缓冲区中的每一行替换为文本`hello world`
以下命令会将当前缓冲区中的每一行替换为文本 `hello world`
```vim
:luado return 'hello world'
```
提供了两个隐式的`line`和`linenr`变量。 `line`是被迭代的行的文本,而`linenr`是它的编号。 以下命令将可以被 2 整数的行转成大写:
提供了两个隐式的 `line` `linenr` 变量。`line` 是被迭代的行的文本,而 `linenr` 是它的编号。以下命令将可以被 2 整数的行转成大写:
```vim
:luado if linenr % 2 == 0 then return line:upper() end
@ -238,7 +238,7 @@ See also:
:luafile ~/foo/bar/baz/myluafile.lua
```
类似于 vim 的`:source`命令或 Lua 内置的`dofile()`函数。
类似于 Vim 的 `:source` 命令或 Lua 内置的 `dofile()` 函数。
See also:
@ -246,18 +246,18 @@ See also:
#### luafile 对比 require():
您可能想知道`lua request()`和`luafile`之间的区别是什么,以及您是否应该使用其中一个而不是另一个。 它们有不同的使用情形:
您可能想知道 `lua request()` `luafile` 之间的区别是什么,以及您是否应该使用其中一个而不是另一个。它们有不同的使用情形:
- `require()`:
- 是内置的 Lua 函数,它允许你使用 Lua 的模块系统。
- 使用`Package.path`变量搜索模块(如前所述,您可以使用`runtimepath`中的`lua/`文件夹内的`required()`lua 脚本)
- 跟踪已加载的模块,并防止第二次解析和执行脚本。 如果您更改包含某个模块代码的文件,并在 Neovim 运行时再次尝试‘required()’,则该模块实际上不会更新。
- 使用 `Package.path` 变量搜索模块(如前所述,您可以使用 `runtimepath` 中的 `lua/` 文件夹内的 `required()` lua 脚本)
- 跟踪已加载的模块,并防止第二次解析和执行脚本。如果您更改包含某个模块代码的文件,并在 Neovim 运行时再次尝试 `required()`,则该模块实际上不会更新。
- `:luafile`:
- 是一个执行命令,它不支持模块。
- 采用相对于当前窗口的工作目录的绝对或相对路径
- 执行脚本的内容,而不管该脚本以前是否执行过
如果您想运行您正在处理的 Lua 文件,`:luafile`很有用:
如果您想运行您正在处理的 Lua 文件,`:luafile` 很有用:
```vim
:luafile %
@ -265,7 +265,7 @@ See also:
### luaeval()
`luaeval()`是内置的 Vimscript 函数计算 Lua 表达式字符串并返回它的值。 Lua 的数据类型自动转换为 Vimscript 类型(反之亦然)。
`luaeval()` 是内置的 Vimscript 函数计算 Lua 表达式字符串并返回它的值。Lua 的数据类型自动转换为 Vimscript 类型(反之亦然)。
```vim
" 你可以将结果存储到一个变量中
@ -276,15 +276,15 @@ let concat = luaeval('"Lua".." is ".."awesome"')
echo concat
" 'Lua is awesome'
" Lua 中的 table 数组转成成 vimscript 的 list
" Lua 中的 table 数组转成成 Vimscript 的 list
let list = luaeval('{1, 2, 3, 4}')
echo list[0]
" 1
echo list[1]
" 2
" 注意 vimscript 的数组索引下标与 Lua 不同是从 0 开始的,Lua 中是从 1 开始
" 注意 Vimscript 的数组索引下标与 Lua 不同是从 0 开始的,Lua 中是从 1 开始
" Lua 中类似 dict 的 table 会被转成 vimscript 中的 dict
" Lua 中类似 dict 的 table 会被转成 Vimscript 中的 dict
let dict = luaeval('{foo = "bar", baz = "qux"}')
echo dict.foo
" 'bar'
@ -307,7 +307,7 @@ lua X = function(k, v) return string.format("%s:%s", k, v) end
echo map([1, 2, 3], luaeval("X"))
```
`luaeval()`接受可选的第二个参数,该参数允许您将数据传递给表达式。 然后您可以使用全局的`_A`从 Lua 访问该数据:
`luaeval()` 接受可选的第二个参数,该参数允许您将数据传递给表达式。然后您可以使用全局的 `_A` 从 Lua 访问该数据:
```vim
echo luaeval('_A[1] + _A[2]', [1, 1])
@ -322,7 +322,7 @@ See also:
### v:lua
这个全局 Vim 变量允许您直接从 Vimscript 调用全局 Lua 函数。 同样 Vim 数据类型被转换为 Lua 类型,反之亦然。
这个全局 Vim 变量允许您直接从 Vimscript 调用全局 Lua 函数。同样 Vim 数据类型被转换为 Lua 类型,反之亦然。
```vim
call v:lua.print('Hello from Lua!')
@ -376,7 +376,7 @@ See also:
#### Caveats
此变量只能用于调用函数。 以下代码将始终引发错误:
此变量只能用于调用函数。以下代码将始终引发错误:
```vim
" Aliasing functions doesn't work
@ -391,22 +391,22 @@ echo map([1, 2, 3], v:lua.global_callback)
## Vim 命名空间
Neovim 会暴露一个全局的`vim`变量来作为 lua 调用 vim 的 APIs 的入口。它还提供给用户一些额外的函数和子模块“标准库”
Neovim 会暴露一个全局的 `vim` 变量来作为 Lua 调用 Vim 的 APIs 的入口。它还提供给用户一些额外的函数和子模块“标准库”
一些比较实用的函数和子模块如下:
- `vim.inspect`: 把 lua 对象以更易读的方式打印(在打印 lua table 是会很有用)
- `vim.regex`: 在 lua 中使用 vim 寄存器
- `vim.inspect`: 把 Lua 对象以更易读的方式打印(在打印 Lua table 时会很有用)
- `vim.regex`: 在 Lua 中使用 Vim 寄存器
- `vim.api`: 暴露 vim 的 API(`:h API`) 的模块(别的远程调用也是调用同样的 API)
- `vim.loop`: Neovim 的 event lopp 模块(使用 LibUV)
- `vim.lsp`: 控制内置 LSP 客户端的模块
- `vim.treesitter`: 暴露 tree-sitter 库中一些实用函数的模块
上面列举功能的并不全面。如果你想知道更多可行的操作可以看:`:help lua-stdlib`和`help lua-vim`。你也可以通过`:lua print(vim.inspect(vim))`所有可用模块
上面列举功能的并不全面。如果你想知道更多可行的操作可以看:`:help lua-stdlib` `help lua-vim`。你也可以通过 `:lua print(vim.inspect(vim))` 获得所有可用模块
#### Tips
每次你想检查一个对象时到要用`print(vim.inspect(x))`是相当繁琐的。你可以你的配置中写一个全局的包装器函数来替代这个繁琐的过程
每次你想检查一个对象时到要用 `print(vim.inspect(x))` 是相当繁琐的。你可以你的配置中写一个全局的包装器函数来替代这个繁琐的过程
```lua
function _G.dump(...)
@ -425,15 +425,15 @@ dump({1, 2, 3})
:lua dump(vim.loop)
```
另外要注意的是,你可能会发现 Lua 会比其他语言少一些实用的内置函数(例如:`os.clock()`,返回以秒为单位,而不是以毫秒为单位的值)。仔细阅读 Neovim 提供的标准库和`vim.fn`(后续还会有更多内容),里面可以会有你想要的东西。
另外要注意的是,你可能会发现 Lua 会比其他语言少一些实用的内置函数(例如:`os.clock()`,返回以秒为单位,而不是以毫秒为单位的值)。仔细阅读 Neovim 提供的标准库和 `vim.fn` (后续还会有更多内容),里面可以会有你想要的东西。
## 在 Lua 中使用 Vimscript
### vim.api.nvim_eval()
此函数计算 Vimscript 表达式字符串并返回其值。 Vimscript 数据类型自动转换为 Lua 类型(反之亦然)。
此函数计算 Vimscript 表达式字符串并返回其值。Vimscript 数据类型自动转换为 Lua 类型(反之亦然)。
它等同于 vimscript 中的`luaeval()`函数
它等同于 vimscript 中的 `luaeval()` 函数
```lua
-- Data types are converted correctly
@ -448,11 +448,11 @@ print(vim.api.nvim_eval('v:null')) -- nil
#### Caveats
与`luaeval()`不同,`vim.api.nvim_eval()`不提供隐式`_A`变量来传递数据给表达式。
`luaeval()` 不同,`vim.api.nvim_eval()` 不提供隐式 `_A` 变量来传递数据给表达式。
### vim.api.nvim_exec()
此函数用于计算 Vimscript 代码块。 它接受一个包含要执行的源代码的字符串和一个布尔值,以确定代码的输出是否应该由函数返回(例如,您可以将输出存储在变量中)。
此函数用于计算 Vimscript 代码块。它接受一个包含要执行的源代码的字符串和一个布尔值,以确定代码的输出是否应该由函数返回(例如,您可以将输出存储在变量中)。
```lua
local result = vim.api.nvim_exec(
@ -474,7 +474,7 @@ print(result) -- 'hello world'
### vim.api.nvim_command()
此函数执行一个 EX 命令。 它接受包含要执行的命令的字符串。
此函数执行一个 EX 命令。它接受包含要执行的命令的字符串。
```lua
vim.api.nvim_command('new')
@ -521,7 +521,7 @@ Neovim 提供了一组 API 函数来设置选项或获取其当前值:
它们接受一个字符串,其中包含要设置或者要获取的选项的名称以及要将其设置为的值。
布尔选项(如`(no)number`) 必须设置为`true`或`false`:
布尔选项(如 `(no)number`) 必须设置为 `true` `false`
```lua
vim.api.nvim_set_option('smarttab', false)
@ -542,7 +542,7 @@ vim.api.nvim_set_option('updatetime', 3000)
print(vim.api.nvim_get_option('updatetime')) -- 3000
```
Buffer-local 和 Window-local 选项还需要缓冲区编号或窗口编号(使用`0`将设置 / 获取当前缓冲区 / 窗口的选项):
Buffer-local 和 Window-local 选项还需要缓冲区编号或窗口编号(使用 `0` 将设置 / 获取当前缓冲区 / 窗口的选项):
```lua
vim.api.nvim_win_set_option(0, 'number', true)
@ -553,7 +553,7 @@ print(vim.api.nvim_buf_get_option(10, 'shiftwidth')) -- 4
### 使用元访问器
如果您想以更“惯用”的方式设置选项,可以使用一些元访问器。 它们本质上包装了上述 API 函数,并允许您像处理变量一样操作选项:
如果您想以更“惯用”的方式设置选项,可以使用一些元访问器。它们本质上包装了上述 API 函数,并允许您像处理变量一样操作选项:
- `vim.o.{option}`: 全局选项
- `vim.bo.{option}`: buffer-local 选项
@ -567,7 +567,7 @@ vim.bo.shiftwidth = 4
print(vim.bo.shiftwidth) -- 4
```
您可以为缓冲区本地和窗口本地选项指定一个数字。 如果未给出编号,则使用当前缓冲区 / 窗口:
您可以为缓冲区本地和窗口本地选项指定一个数字。如果未给出编号,则使用当前缓冲区 / 窗口:
```lua
vim.bo[4].expandtab = true -- same as vim.api.nvim_buf_set_option(4, 'expandtab', true)
@ -579,17 +579,17 @@ See also:
#### Caveats
**WARNING**:以下部分基于我做的几个实验。 文档似乎没有提到这种行为,我也没有检查源代码来验证我的声明。
**WARNING**:以下部分基于我做的几个实验。文档似乎没有提到这种行为,我也没有检查源代码来验证我的声明。
**TODO**:有谁能确认一下吗?
如果您只使用`:set`命令处理过选项,那么某些选项的行为可能会让您大吃一惊。
如果您只使用 `:set` 命令处理过选项,那么某些选项的行为可能会让您大吃一惊。
本质上,选项可以是全局的、缓冲区 / 窗口的局部的,或者同时具有全局和局部值。
`:setglobal`命令用于设置选项的全局值。
`:setlocal`命令用于设置选项的本地值。
`:set`命令用于设置选项的全局和局部值。
`:setglobal` 命令用于设置选项的全局值。
`:setlocal` 命令用于设置选项的本地值。
`:set` 命令用于设置选项的全局和局部值。
这是`:help:setglobal`的简易表格:
这是 `:help :setglobal` 的简易表格:
| Command | global value | local value |
|-------------------------|--------------|-------------|
@ -597,21 +597,21 @@ See also:
| :setlocal option=value | - | set |
| :setglobal option=value | set | - |
Lua 中没有`:set`命令的等价命令,可以全局设置,也可以本地设置。
您可能认为`number‘选项是全局的,但文档将其描述为`Windows-local`。 这样的选项实际上是“粘性的”:当您打开一个新窗口时,它们的值是从当前窗口复制过来的。
因此,如果您要从您的`init.lua`设置选项,您应该这样做:
Lua 中没有 `:set` 命令的等价命令,可以全局设置,也可以本地设置。
您可能认为 `number` 选项是全局的,但文档将其描述为 `Windows-local`这样的选项实际上是“粘性的”:当您打开一个新窗口时,它们的值是从当前窗口复制过来的。
因此,如果您要从您的 `init.lua` 设置选项,您应该这样做:
```lua
vim.wo.number = true
```
`shiftwidth`、`expandtab`、`undofile`等`本地到缓冲区`的选项更容易混淆。 假设您的`init.lua`包含以下代码:
`shiftwidth`、`expandtab`、`undofile` 等本地到缓冲区的选项更容易混淆。假设您的 `init.lua` 包含以下代码:
```lua
vim.bo.expandtab = true
```
当你启动 Neovim 并开始编辑时,一切都很好:按下`<Tab>`键会插入空格,而不是制表符。 打开另一个缓冲区,您会突然返回到选项卡...
当你启动 Neovim 并开始编辑时,一切都很好:按下 `<Tab>` 键会插入空格,而不是制表符。打开另一个缓冲区,您会突然返回到选项卡...
在全局设置它具有相反的问题:
@ -619,7 +619,7 @@ vim.bo.expandtab = true
vim.o.expandtab = true
```
这次,您在第一次启动 Neovim 时插入选项卡。 打开另一个缓冲区,然后按`<Tab>`即可实现预期效果。
这次,您在第一次启动 Neovim 时插入选项卡。打开另一个缓冲区,然后按 `<Tab>` 即可实现预期效果。
简而言之,如果您想要正确的行为,“本地到缓冲区”的选项必须这样设置:
```lua
@ -659,8 +659,8 @@ See also:
- `vim.api.nvim_set_vvar()`
- `vim.api.nvim_get_vvar()`
除了预定义的 Vim 变量外,还可以删除它们(等同于 vimscript 中的`:unlet`)。 局部变量 (`l:`)、脚本变量 (s:`) 和函数参数 (`a:`) 不能操作,因为它们只在 Vim 脚本上下文中有意义,Lua 有自己的作用域规则。
如果您不熟悉这些变量的作用,请参考`:help internal-variables`对其进行详细介绍。
除了预定义的 Vim 变量外,还可以删除它们(等同于 Vimscript 中的 `:unlet`)。局部变量 (`l:`)、脚本变量 (`s:`) 和函数参数 (`a:`) 不能操作,因为它们只在 Vim 脚本上下文中有意义,Lua 有自己的作用域规则。
如果您不熟悉这些变量的作用,请参考 `:help internal-variables` 对其进行详细介绍。
这些函数接受一个字符串,该字符串包含要设置 / 获取 / 删除的变量的名称以及要将其设置为的值。
```lua
@ -728,7 +728,7 @@ echo g:variable
### vim.call()
`vim.call()`调用 Vimscript 函数。 这可以是内置 Vim 函数,也可以是用户函数。 同样,数据类型在 Lua 和 Vimscript 之间来回转换。它接受函数名,后跟要传递给该函数的参数:
`vim.call()` 调用 Vimscript 函数。这可以是内置 Vim 函数,也可以是用户函数。同样,数据类型在 Lua 和 Vimscript 之间来回转换。它接受函数名,后跟要传递给该函数的参数:
```lua
print(vim.call('printf', 'Hello from %s', 'Lua'))
@ -750,7 +750,7 @@ See also:
### vim.fn.{function}()
`vim.fn`的功能与`vim.call()`完全相同,但看起来更像是原生 Lua 函数调用
`vim.fn` 的功能与 `vim.call()` 完全相同,但看起来更像是原生 Lua 函数调用
```lua
print(vim.fn.printf('Hello from %s', 'Lua'))
@ -765,7 +765,7 @@ end
vim.fn.jobstart('ls', { on_stdout = print_stdout })
```
Hashes `#`不是 Lua 中识别符的有效字符,因此必须使用以下语法调用 autoload 函数:
Hashes `#` 不是 Lua 中识别符的有效字符,因此必须使用以下语法调用 autoload 函数:
```lua
vim.fn['my#autoload#function']()
@ -776,11 +776,11 @@ See also:
#### Tips
Neovim 有一个强大的内置函数库,这些函数对插件非常有用。 按字母顺序排列的函数列表参见`:help vim-function`,按主题分组的函数列表参见`:help function-list`
Neovim 有一个强大的内置函数库,这些函数对插件非常有用。按字母顺序排列的函数列表参见 `:help vim-function`,按主题分组的函数列表参见 `:help function-list`
#### Caveats
一些应该返回布尔值的 Vim 函数返回`1`或`0`。 这在 Vimscript 中不是问题,因为`1‘是真的,而`0’是假的,支持如下结构:
一些应该返回布尔值的 Vim 函数返回 `1``0`。这在 Vimscript 中不是问题,因为 `1` 是真的,而 `0` 是假的,支持如下结构:
```vim
if has('nvim')
@ -788,7 +788,7 @@ if has('nvim')
endif
```
然而,在 Lua 中,只有`false`和`nil`被认为是假的,数字的计算结果总是`true`,无论它们的值是什么。 您必须显式检查`1`或`0`:
然而,在 Lua 中,只有 `false` `nil` 被认为是假的,数字的计算结果总是 `true`,无论它们的值是什么。您必须显式检查 `1` `0`
```lua
if vim.fn.has('nvim') == 1 then
@ -809,7 +809,7 @@ Neovim 提供了一系列的 api 函数来设置获取和删除映射:
- `vim.api.nvim_buf_get_keymap()`
- `vim.api.nvim_buf_del_keymap()`
让我们从`vim.api.nvim_set_keymap()`和`vim.api.nvim_buf_set_keymap()`开始,传递给函数的第一个参数是一个包含映射生效模式名称的字符串:
让我们从 `vim.api.nvim_set_keymap()` `vim.api.nvim_buf_set_keymap()` 开始,传递给函数的第一个参数是一个包含映射生效模式名称的字符串:
| String value | Help page | Affected modes | Vimscript equivalent |
|------------------------|---------------|------------------------------------------|----------------------|
@ -825,13 +825,13 @@ Neovim 提供了一系列的 api 函数来设置获取和删除映射:
| `'c'` | `mapmode-c` | Command-line | `:cmap` |
| `'t'` | `mapmode-t` | Terminal | `:tmap` |
第二个参数是包含映射左侧的字符串(触发映射中定义的命令的键或键集)。 空字符串相当于`<Nop>`,表示禁用键位。
第二个参数是包含映射左侧的字符串(触发映射中定义的命令的键或键集)。空字符串相当于 `<Nop>`,表示禁用键位。
第三个参数是包含映射右侧(要执行的命令)的字符串。
最后一个参数是一个表,包含`:help:map-arguments`中定义的映射的布尔值选项(包括`noremap`,不包括`buffer`)。
最后一个参数是一个表,包含 `:help :map-arguments` 中定义的映射的布尔值选项(包括 `noremap`,不包括 `buffer`)。
缓冲区-本地映射也将缓冲区编号作为其第一个参数 (`0`设置当前缓冲区的映射)。
缓冲区-本地映射也将缓冲区编号作为其第一个参数(`0` 设置当前缓冲区的映射)。
```lua
vim.api.nvim_set_keymap('n', '<leader><Space>', ':set hlsearch!<CR>', { noremap = true, silent = true })
@ -841,28 +841,28 @@ vim.api.nvim_buf_set_keymap(0, '', 'cc', 'line(".") == 1 ? "cc" : "ggcc"', { nor
-- :noremap <buffer> <expr> cc line('.') == 1 ? 'cc' : 'ggcc'
```
`vim.api.nvim_get_keymap()`接受一个字符串,该字符串包含您想要映射列表的模式的短名称(见上表)。 返回值是包含该模式的所有全局映射的表。
`vim.api.nvim_get_keymap()` 接受一个字符串,该字符串包含您想要映射列表的模式的短名称(见上表)。返回值是包含该模式的所有全局映射的表。
```lua
print(vim.inspect(vim.api.nvim_get_keymap('n')))
-- :verbose nmap
```
`vim.api.nvim_buf_get_keymap()`将缓冲区编号作为其第一个参数 (`0`将获取当前缓冲区的映射)
`vim.api.nvim_buf_get_keymap()` 将缓冲区编号作为其第一个参数 (`0` 将获取当前缓冲区的映射)
```lua
print(vim.inspect(vim.api.nvim_buf_get_keymap(0, 'i')))
-- :verbose imap <buffer>
```
`vim.api.nvim_del_keymap()`获取映射左侧的模式。
`vim.api.nvim_del_keymap()` 获取映射左侧的模式。
```lua
vim.api.nvim_del_keymap('n', '<leader><Space>')
-- :nunmap <leader><Space>
```
同样,`vim.api.nvim_buf_del_keymap()`以缓冲区编号作为第一个参数,其中`0`表示当前缓冲区。
同样,`vim.api.nvim_buf_del_keymap()` 以缓冲区编号作为第一个参数,其中 `0` 表示当前缓冲区。
```lua
vim.api.nvim_buf_del_keymap(0, 'i', '<Tab>')
@ -871,7 +871,7 @@ vim.api.nvim_buf_del_keymap(0, 'i', '<Tab>')
## 定义用户命令
目前在 Lua 中没有创建用户命令的接口。 不过已经在计划内:
目前在 Lua 中没有创建用户命令的接口。不过已经在计划内:
- [Pull request #11613](https://github.com/neovim/neovim/pull/11613)
@ -879,11 +879,11 @@ vim.api.nvim_buf_del_keymap(0, 'i', '<Tab>')
## 定义自动命令
AUGROUP 和 AUTOCOMMAND 还没有接口,但正在处理
AUGROUP 和 AUTOCOMMAND 还没有接口,但正在处理
- [Pull request #12378](https://github.com/neovim/neovim/pull/12378)
不过你可以使用`vim.api.nvim_command`来创建自动命令,例如:
不过你可以使用 `vim.api.nvim_command` 来创建自动命令,例如:
```lua
-- Create autocmd
@ -899,7 +899,7 @@ vim.api.nvim_command('augroup end')
`vim.api.nvim_buf_add_highlight` 为 buffer 指定的行和位置添加高亮
neovim 0.5 集成 treesitter,对于语法高亮相比之前使用正则的方式更加的高效,[nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter)
Neovim 0.5 集成 treesitter,对于语法高亮相比之前使用正则的方式更加的高效,[nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter)
- `:help lua-treesitter`
@ -918,7 +918,7 @@ neovim 0.5 集成 treesitter,对于语法高亮相比之前使用正则的方
### vim.loop
`vim.loop`是暴露 LibUV 接口的模块。
`vim.loop` 是暴露 LibUV 接口的模块。
```lua
local stop_signal = false

Loading…
Cancel
Save