Eric's Blog 时光荏苒,岁月如梭

Neovim 插件管理器 nvim-plug

2025-02-09
Eric Wong

这篇文章给大家介绍一下我开发的新的 Neovim 插件管理器 nvim-plug,如果喜欢的话,欢迎在 Github 上点⭐ 。

nvim-plug

不管是 Neovim 还是 Vim,已经有太多太多的插件管理器了, 最早期时候刚接触 Vim 的时候,从刚开始编辑 vimrc 时候开始, 只是简单的设置 runtimepath 选项,到后来接触并切换至 Bundle 等各种 Vim 插件管理器。

我个人使用插件管理器更新迭代的路劲大致是:

  • 直接设置rtp
  • Bundle(Vundle)
  • vim-plug
  • neobundle.vim
  • dein.vim

越往后,插件管理器增加的功能越多,但实际上本质并未改变, 我前面写过一篇插件管理器的运行机制《Neovim 和 Vim 插件管理器的实现逻辑》

为什么重写插件管理器

我有很长很长一段时间在使用的 dein.vim,包括现在 Vim 下还是使用 dein,。 实际上 dein.vim 已经实现了我所需要的所有的插件管理器的核心逻辑功能,但是,目前我大部分情况使用的是 Neovim, 因为 dein 还是 vimscript 写的,因此速度上在插件很多的时候,还是有些慢的, 因此使用 Lua 来实现一个 Neovim 插件管理器:nvim-plug

目前已实现的功能包括:

  • cmds:依据执行的命令延迟加载
  • events:依据事件延迟加载
  • config: 包括 configconfig_beforeconfig_after 三种函数,分别在不同时机执行。
  • on_ft:依据文件类型延迟加载
  • on_map: 依据快捷键设定延迟加载
  • on_func: 依据调用的 Vim 函数延迟加载
  • script_type: 设定插件类型
  • build:设置 build 命令
  • if: 函数判断是否需要载入插件
  • frozen: 锁定,不自动更新,除非明确指定插件名称
  • depends: 依赖插件列表
  • branch/tag: 指定版本
  • type: 设定插件类型,用于下载 raw 插件
  • autoload: 下载后自动加载

安装 nvim-plug

在 Neovim 初始化文件的顶部,增加以下内容:

local dir = vim.fn.stdpath('data') .. '/repos/'

local function bootstrap(repo)
  if vim.fn.isdirectory(dir .. repo) == 0 then
    vim.fn.system({
      'git',
      'clone',
      '--depth',
      '1',
      'https://github.com/' .. repo .. '.git',
      dir .. repo,
    })
  end
  vim.opt.runtimepath:append(dir .. repo)
end

bootstrap('wsdjeg/job.nvim')
bootstrap('wsdjeg/logger.nvim')
bootstrap('wsdjeg/nvim-plug')

延迟加载

目前已经实现了按命令、事件等多种方式触发的延迟加载。

按命令延迟加载

当执行某个 Neovim 用户自定义命令时,再加载对应的插件:

require('plug').add({ {
  'wsdjeg/picker.nvim',
  cmds = { 'Picker' },
} })

autocmd 事件触发加载

require('plug').add({ {
  'wsdjeg/picker.nvim',
  events = { 'VimEnter' },
} })

插件界面的选择

其实关于插件管理器的界面,因为历史原因,一直习惯了 Vundle 的界面模式,包括 Vim 下知名插件 vim-plug 也是使用这样类似的插件管理器界面。 而我之前使用的 dein.vim 没有提供默认的界面,为此我还写过一个插件dein-ui.vim。那么在设计 nvim-plug 这个插件管理器的时候, 自然而然就实现了一个类似于 Vundle 的可视化界面,但是考虑到有可能会有其他操作界面模式的需求,因此 nvim-plug 这个插件管理器的操作界面是设计成界面和逻辑分离的模式。

如果兴趣,也可以实现一个新的插件列表界面,可以通过如下模式进行修改:

--- your custom UI

local function on_ui_update(name, data)
  -- logic
end


require('plug').setup({
  bundle_dir = 'D:/bundle_dir',
  max_processes = 5, -- max number of processes used for nvim-plug job
  base_url = 'https://github.com',
  ui = on_ui_update, -- default ui is notify, use `default` for split window UI
})

上述的 on_ui_update 函数会在插件下载、更新、build 等命令执行过程种被调用,函数调用时被传入两个参数:插件名称、界面更新数据 plugUiData。

The plugUiData is table with following keys:

plugUiData 是一个 Lua table,其键值如下:

键值 描述
clone_done boolead, is true when clone successfully
command string, clone, pull or build
clone_process string, git clone progress, such as 16% (160/1000)
clone_done boolean, git clone exit status
building boolean
build_done boolean
pull_done boolean
pull_process string

版权声明:本文为原创文章,遵循 署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)版权协议,转载请附上原文出处链接和本声明。


延生阅读

分享到:

评论