首页
学习
活动
专区
圈层
工具
发布
清单首页nvim文章详情

使用 lua 编写 neovim 插件

在 vim 中 viml 是第一公民,很多插件都是使用 viml 进行开发的,而在 neovim 中,lua 成为了主要的脚本语言,几乎现在 95%以上的 neovim 都是采用 lua 进行开发的。

插件目录结构

开发一款插件,我们首先要明确插件的目录结构,虽然这个结构不是必须固定的,但是遵守一定的规则可以让我们的插件变得更容易被修改,更容易进行扩展。

插件目录一般为一个 plugin 文件夹放入我们的主文件,lua 文件夹放入代码库。

浮动窗口

在 neovim 中,增加了浮动窗口的功能,这样我们显示一些信息非常的方便,我们可以使用 neovim 提供的关于浮动窗口的 api 进行插件的编写。

编写插件的时候,我们一般都会首先定义一些变量,这样方便我们后续的使用。定义好变量之后,我们接下来会根据需求定义我们的函数,一般情况下都是一个功能定义一个函数,每个函数完成一个指定的功能。

此外,需要注意的一点就是,一般插件都是会有一些默认配置的,我们可以定义一些配置默认值,这样用户可以在零配置的情况下就使用我们的插件。

简单的代码如下:

代码语言:javascript
复制
local api = vim.api
local buf, win

local function open_window()
  buf = api.nvim_create_buf(false, true) -- create new emtpy buffer

  api.nvim_buf_set_option(buf, 'bufhidden', 'wipe')

  -- get dimensions
  local width = api.nvim_get_option("columns")
  local height = api.nvim_get_option("lines")

  -- calculate our floating window size
  local win_height = math.ceil(height * 0.8 - 4)
  local win_width = math.ceil(width * 0.8)

  -- and its starting position
  local row = math.ceil((height - win_height) / 2 - 1)
  local col = math.ceil((width - win_width) / 2)

  -- set some options
  local opts = {
    style = "minimal",
    relative = "editor",
    width = win_width,
    height = win_height,
    row = row,
    col = col
  }

  -- and finally create it with buffer attached
  win = api.nvim_open_win(buf, true, opts)
end

视图更新

几乎所有的插件最后都要更新渲染视图,我们可以根据指定的内容进行视图的更新,一般都是根据执行的一些命令结果来更新视图,在 neovim 中,可以通过vim.fn.systemlist函数获取命令执行结果,然后通过函数api.nvim_buf_set_lines将结果渲染到视图上。

代码语言:javascript
复制

local function update_view()
  -- we will use vim systemlist function which run shell
  -- command and return result as list
  local result = vim.fn.systemlist('git diff-tree --no-commit-id --name-only -r HEAD')

  -- with small indentation results will look better
  for k,v in pairs(result) do
    result[k] = '  '..result[k]
  end

  api.nvim_buf_set_lines(buf, 0, -1, false, result)
end

插件交互

很多时候我们的插件是需要和用户进行交互的,也就是用户输入一些命令之后,我们要能够响应用户的输入,然后来调整我们插件的输出。

在 neovim 中,我们可以通过api.nvim_buf_set_keymap来进行输入按键的功能绑定。

函数导出

最后,我们可以将我们的插件中的函数进行导出,也就是让它们可以被执行。最后再在主函数中调用它们即可,这样我们的插件就编写完成了。

代码语言:javascript
复制
local function my_plugin()
  position = 0 -- if you want to preserve last displayed state just omit this line
  open_window()
  set_mappings()
  update_view(0)
  api.nvim_win_set_cursor(win, {4, 0}) -- set cursor on first list entry
end

return {
  my_plugin = my_plugin,
  update_view = update_view,
  open_file = open_file,
  move_cursor = move_cursor,
  close_window = close_window
}
下一篇
举报
领券