66RING
c85718d191
|
4 years ago | |
---|---|---|
LICENSE | 4 years ago | |
README.md | 4 years ago |
README.md
在neovim中使用Lua
nvim-lua-guide 中文版.
目录
- 简介
- Lua文件的位置
- 在Vim文件中调用Lua
- Vim命名空间
- 在Lua中调用vimscript
- 管理vim设置选项
- 管理vim内部变量
- 调用vimscript函数
- 定义键位映射
- 定义用户命令
- 定义自动命令
- 定义语法高亮
- 一般提示和备注
- 杂项
简介
Lua作为Neovim中的一流语言的集成正在成为它的杀手级特性之一。 然而,学习如何用Lua编写插件的教程数量并不像用Vimscript编写插件那样多。 这是一种尝试,试图提供一些基本信息,让人们可以使用Lua编写neovim插件。 本指南假定您使用的是最新的NeovimNighly build]。 由于Neovim的0.5版本是开发版本,请记住,正在积极开发的一些API并不十分稳定, 在发布之前可能会发生变化。
学习Lua
不同于原版教程,一下资源适用于国内用户:
Lua是一种非常干净和简单的语言。 它很容易学习,特别是如果你有其他编程语言基础的例如typescript/javascript等,会更加容易上手Lua。注意:Neovim嵌入的Lua版本是LuaJIT 2.1.0,它与Lua 5.1保持兼容(带有几个5.2扩展)
现有的一些在neovim中使用Lua的教程
已经编写了一些教程来帮助人们用Lua编写插件。 他们中的一些人在写这本指南时提供了不少的帮助。 非常感谢它们的作者。
- teukka.tech - 从init.vim转到init.lua
- 2n.pl - 如何使用Lua编写neovim插件
- 2n.pl - 如何使用Lua制作neovim UI
- ms-jpq - NeoVim 异步教程
相关插件
- Vimpeccable - Plugin to help write your .vimrc in Lua
- plenary.nvim - All the lua functions I don't want to write twice
- popup.nvim - An implementation of the Popup API from vim in Neovim
- nvim_utils
- nvim-luadev - REPL/debug console for nvim lua plugins
- nvim-luapad - Interactive real time neovim scratchpad for embedded lua engine
- nlua.nvim - Lua Development for Neovim
- galaxyline.nvim - neovim statusline plugin written in lua
- BetterLua.vim - Better Lua syntax highlighting in Vim/NeoVim
Lua 文件位置
Lua文件通常位于您的runtimepath
中的lua/
文件夹中(对于大多数用户来说,在*nix系统上为~/.config/nvim/lua
,在Windows系统上为~/appdata/Local/nvim/lua
)。 Package.path
和Package.cpath
全局变量会自动调整为包含该文件夹下的Lua文件。 这意味着您可以require()
这些文件作为Lua模块
我们以下面的文件夹结构为例:
📂 ~/.config/nvim
├── 📁 after
├── 📁 ftplugin
├── 📂 lua
│ ├── 🌑 myluamodule.lua
│ └── 📂 other_modules
│ ├── 🌑 anothermodule.lua
│ └── 🌑 init.lua
├── 📁 pack
├── 📁 plugin
├── 📁 syntax
└── 🇻 init.vim
下面的Lua代码将加载myluamodule.lua
require('myluamodule')
注意没有.lua
扩展名。
类似地,加载ther_module/anthermodule e.lua
的过程如下:
require('other_modules.anothermodule')
-- or
require('other_modules/anothermodule')
路径分隔符可以用点.
表示,也可以用斜杠/
表示。
文件夹如果包含init.lua
文件,可以直接引用该文件夹而不必指定该文件的名称
require('other_modules') -- loads other_modules/init.lua
更多信息 :help lua-require
警告
与.vim文件不同,.lua文件不会自动从您的runtimepath
目录中获取。 相反,您必须从Vimscript source/require 它们。 计划增加init.lua
文件加载选项,替代init.vim
:
提示
多个Lua插件在它们的lua/
文件夹中可能有相同的文件名。 这可能会导致命名空间冲突。如果两个不同的插件有一个lua/main.lua
文件,那么执行require('main')
是不明确的:我们想要加载哪个文件?最好将您的配置或插件命名为顶级文件夹,
例如这样的形式:lua/plugin_name/main.lua
。
包说明
如果您是package
特性的用户或基于它的插件管理器例如packer.nvim,minpac或vim-packager,那么在使用Lua插件时需要注意一些事情。start
文件夹中的包只有在源化您的init.vim
之后才会加载。 这意味着只有在Neovim处理完文件之后,才会将包添加到runtimepath
中。如果插件期望
require
一个Lua模块或调用自动加载的函数,这可能会导致问题。假设包start/foo
有一个lua/bar.lua
文件,从您的init.vim
执行此操作将引发错误,因为runtimepath
尚未更新。
lua require('bar')
你需要使用packadd! foo
命令在require
这个模块之前
packadd! foo
lua require('bar')
在Packadd
后附加!
表示Neovim会将包放在runtimepath
中,而不会在其plugin
或ftDetect
目录下寻找任何脚本。
See also:
:help :packadd
- Issue #11409
在Vimscript中使用Lua
:lua
该命令执行一段Lua代码
:lua require('myluamodule')
可以使用以下语法编写多行脚本:
echo "Here's a bigger chunk of Lua code"
lua << EOF
local mod = require('mymodule')
local tbl = {1, 2, 3}
for k, v in ipairs(tbl) do
mod.method(v)
end
print(tbl)
EOF
See also:
:help :lua
:help :lua-heredoc
警告
在vim文件中编写Lua时,您不会得到正确的语法突出显示。 使用:lua
命令作为需要外部Lua文件的入口点可能会更方便。
:luado
该命令执行一段Lua代码,该代码作用于当前缓冲区中的选中的行。 如果未指定范围,则改为使用整个缓冲区。 从块return
的任何字符串都用于确定应该用什么替换每行。
以下命令会将当前缓冲区中的每一行替换为文本hello world
:luado return 'hello world'
提供了两个隐式的line
和linenr
变量。 line
是被迭代的行的文本,而linenr
是它的编号。 以下命令将可以被2整数的行转成大写:
:luado if linenr % 2 == 0 then return line:upper() end
See also:
:help :luado
:luafile
这个命令加载一个lua文件
:luafile ~/foo/bar/baz/myluafile.lua
类似于vim的:source
命令或Lua内置的dofile()
函数。
See also:
:help :luafile
luafile 对比 require():
您可能想知道lua request()
和luafile
之间的区别是什么,以及您是否应该使用其中一个而不是另一个。 它们有不同的使用情形:
require()
:- 是内置的Lua函数,它允许你使用Lua的模块系统。
- 使用
Package.path
变量搜索模块(如前所述,您可以使用runtimepath
中的lua/
文件夹内的required()
lua脚本) - 跟踪已加载的模块,并防止第二次解析和执行脚本。 如果您更改包含某个模块代码的文件,并在Neovim运行时再次尝试‘required()’,则该模块实际上不会更新。
:luafile
:- 是一个执行命令,它不支持模块。
- 采用相对于当前窗口的工作目录的绝对或相对路径
- 执行脚本的内容,而不管该脚本以前是否执行过
如果您想运行您正在处理的Lua文件,:luafile
很有用:
:luafile %
Vim命名空间
Neovim会暴露一个全局的vim
变量来作为lua调用vim的APIs的入口。它还提供给用户一些额外的函数和子模块“标准库”
一些比较实用的函数和子模块如下:
vim.inspect
: 把lua对象以更易读的方式打印(在打印lua table是会很有用)vim.regex
: 在lua中使用vim寄存器vim.api
: 暴露vim的API(:h API
)的模块(别的远程调用也是调用同样的API)- (TODO)
vim.loop
: module that exposes the functionality of Neovim's event-loop (using LibUV) vim.lsp
: 控制内置LSP客户端的模块vim.treesitter
: 暴露tree-sitter库中一些实用函数的模块
上面列举功能的并不全面。如果你想知道更多可行的操作可以看::help lua-stdlib
和help lua-vim
。你也可以通过:lua print(vim.inspect(vim))
所有可用模块
Tips
每次你想检查一个对象时到要用print(vim.inspect(x))
是相当繁琐的。你可以你的配置中写一个全局的包装器函数来替代这个繁琐的过程
function _G.dump(...)
local objects = vim.tbl_map(vim.inspect, {...})
print(unpack(objects))
end
之后你就可以使用如下命令来快速检查对象内容了
dump({1, 2, 3})
:lua dump(vim.loop)
另外要注意的是,你可能会发现Lua会比其他语言少一些实用的内置函数(例如:os.clock()
,返回以秒为单位,而不是以毫秒为单位的值)。仔细阅读Neovim提供的标准库和vim.fn
(后续还会有更多内容),里面可以会有你想要的东西。