Neovim插件管理Packer切换为Lazy

今天本想解决Neovim自动化配置脚本编写问题,意外得知Packer已经不再维护,其官方仓库packer.nvim 写到:

This repository is currently unmaintained. For the time being (as of August, 2023), it is recommended to use one of the following plugin managers instead:

  • lazy.nvim: Most stable and maintained plugin manager for Nvim.
  • pckr.nvim: Spiritual successor of packer.nvim. Functional but not as stable as lazy.nvim.

这个消息很突然,但是之前lazy.nvim更加优秀,同时也得到了packer.nvim作者的认可,具体原因不得而知,既然packer.nvim不再维护,同时作者给了两个替代方案,显然更加稳定的lazy.nvim就是一个可靠的选择。

切换流程

  1. 册除packer.nvim的编译目录~/.config/nvim/plugins和由packer.nvim安装的插件.

    1
    2
    rm -rf ~/.config/nvim/plugins
    rm -rf ~/.local/share/nvim

  2. 删除packer.nvim的配置文件~/.config/nvim/lua/plg/plugin.lua.

    1
    rm ~/.config/nvim/lua/plg/plugin.lua

  3. 同时新建lazy.nvim的配置文件lazy-init.lua

    ~/.config/nvim/lua/lazy-init.lua
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
    if not vim.loop.fs_stat(lazypath) then
    vim.fn.system({
    "git",
    "clone",
    "--filter=blob:none",
    "https://github.com/folke/lazy.nvim.git",
    "--branch=stable", -- latest stable release
    lazypath,
    })
    end
    vim.opt.rtp:prepend(lazypath)
    require("lazy").setup({
    "git@github.com:neovim/nvim-lspconfig",
    "git@github.com:williamboman/mason.nvim",
    "git@github.com:williamboman/mason-lspconfig.nvim",
    -- 借用了vim插件,因为二者是兼容的,速度上vim-latex更快
    { "git@github.com:vim-latex/vim-latex" },
    { "git@github.com:jbyuki/nabla.nvim" },
    -- 添加latex插件vimtex
    { "git@github.com:lervag/vimtex" },
    { "git@github.com:mhinz/neovim-remote" },
    -- 添加neovim主题
    {
    "git@github.com:folke/tokyonight.nvim",
    "git@github.com:tomasr/molokai",
    "git@github.com:catppuccin/nvim",
    "git@github.com:jaredgorski/SpaceCamp",
    "git@github.com:morhetz/gruvbox",
    "git@github.com:nelstrom/vim-mac-classic-theme",
    "git@github.com:RRethy/nvim-base16",
    },
    -- 代码高亮
    { "git@github.com:nvim-treesitter/nvim-treesitter", run =":TSUpdate" },
    -- 状态栏主题
    {
    "git@github.com:nvim-lualine/lualine.nvim",
    requires = { "nvim-tree/nvim-web-devicons", opt = true },
    },
    -- -- nvim-cmp
    'git@github.com:hrsh7th/cmp-nvim-lsp',
    'git@github.com:hrsh7th/cmp-buffer' ,
    'git@github.com:hrsh7th/cmp-path' ,
    'git@github.com:hrsh7th/cmp-cmdline' ,
    'git@github.com:hrsh7th/nvim-cmp',
    -- vsnip
    'git@github.com:hrsh7th/cmp-vsnip' ,
    'git@github.com:hrsh7th/vim-vsnip' ,
    'git@github.com:rafamadriz/friendly-snippets' ,
    -- lspkind
    { "git@github.com:onsails/lspkind.nvim" },
    -- 自动插入模板
    { "git@github.com:aperezdc/vim-template" },
    -- 旧式片段插入程序
    { "git@github.com:SirVer/ultisnips" },
    { "git@github.com:honza/vim-snippets" },
    -- 注释插件
    { "git@github.com:terrortylor/nvim-comment" },
    { "git@github.com:nvim-tree/nvim-web-devicons" },
    -- 目录树插件
    { "git@github.com:nvim-tree/nvim-tree.lua" },
    -- This plugin adds indentation guides to all lines (including empty lines).
    { "git@github.com:lukas-reineke/indent-blankline.nvim" },
    -- 彩虹括号
    { "git@github.com:hiphish/rainbow-delimiters.nvim" },
    -- 用来显示文件结构的插件,对于编写程序查看各定义时很有帮助
    { "git@github.com:liuchengxu/vista.vim" },
    -- 模糊查找
    {
    "git@github.com:nvim-telescope/telescope.nvim", tag = "0.1.4",
    -- or , branch = '0.1.x',
    requires = { { "git@github.com:nvim-lua/plenary.nvim" } }
    },
    })

    注意: 官方网站还给出了另一个方法,就是将lazy-init.lua放在目录~/.config/nvim中,同时插件配置文件单独建立,然后再调用,但是本着lazy的原则,我还是更愿意一个文件解决问题,因为插件也不是多的放不下,文件越少越方便管理。

  4. 建立~/.config/nvim/init.vim配置文件

  • 先设置不引入插件,写入

    1
    lua require("lazy-init")
    启动nvim,然后插件就会自动开始安装了。

  • 启动各插件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    lua require("lazy-init")
    set shortmess+=I "关闭启动界面
    let g:loaded_ruby_provider = 0
    " 基础设置
    lua require('lsp/base')
    " 配置主题
    " lua require('theme/catppuccin')
    " lua require('theme/gruvbox')
    " lua require('theme/mac_classic')
    " lua require('theme/molokai')
    " lua require('theme/spacecamp')
    lua require('theme/tokyonight')
    " lua require('theme/nvim-base16')
    " 状态栏主题
    lua require('theme/lualine')
    "lua require('theme/evil_lualine')
    "lua require('theme/bubbles_lualine')
    "lua require('theme/slanted-gaps_lualine')
    lua require('lsp/keybindings')
    " 编程语言配置
    lua require('lsp/python')
    lua require('lsp/setup')
    lua require('lsp/shell')
    lua require('lsp/texlab')
    " Packer 插件管理
    lua require('plg/cmp')
    lua require('plg/vim-latex')
    lua require('plg/nabla')
    lua require('plg/vimtex')
    lua require('plg/vim-template')
    lua require('plg/nvim-comment')
    lua require('plg/nvim-tree')
    lua require('plg/lspkind')
    lua require('plg/indent-blankline')
    lua require('plg/rainbow-delimiters')
    lua require('plg/vista')
    lua require('plg/telescope')
    "
    " 由于vista插件有些配置不能使用lua语言改写,所以暂时在此按vimscript格式引入其配置,等时机成熟再改用lua语言
    " --------------------vista begin--------------------
    let g:vista_icon_indent = ["╰─▸ ", "├─▸ "]
    let g:vista_default_executive = 'ctags'
    let g:vista_executive_for = {
    \ 'cpp': 'vim_lsp',
    \ 'php': 'vim_lsp',
    \ }
    let g:vista_ctags_cmd = {
    \ 'haskell': 'hasktags -x -o - -c',
    \ }

    let g:vista_fzf_preview = ['right:50%']
    let g:vista#renderer#enable_icon = 1
    let g:vista#renderer#icons = {
    \ "function": "\uf794",
    \ "variable": "\uf71b",
    \ }
    " --------------------vista end--------------------
    "
    " ---------------Fcitx5 Auto Switch----------------
    let fcitx5state=system("fcitx5-remote")
    autocmd InsertLeave * :silent let fcitx5state=system("fcitx5-remote")[0] | silent !fcitx5-remote -c
    autocmd InsertEnter * :silent if fcitx5state == 2 | call system("fcitx5-remote -o") | endif
    " --------------------End Fcitx5--------------------

选择建立~/.config/nvim/init.vim,因为有些vim的插件还没有完全使用lua重写,比如fcitx5在不同模式下自动切换的这段代码就必须写在init.vim文件中才得,这是当前一个最好的选择。

Lazy 使用方法

Plugins are managed with the :Lazy command. Open the help with <?> to see all the key mappings.

You can press <CR> on a plugin to show its details. Most properties can be hovered with <K> to open links, help files, readmes, git commits and git issues.

Lazy can automatically check for updates in the background. This feature can be enabled with config.checker.enabled = true.

Any operation can be started from the UI, with a sub command or an API function:

Command Lua Description
:Lazy build {plugins} require("lazy").build(opts) Rebuild a plugin
:Lazy check [plugins] require("lazy").check(opts?) Check for updates and show the log (git fetch)
:Lazy clean [plugins] require("lazy").clean(opts?) Clean plugins that are no longer needed
:Lazy clear require("lazy").clear() Clear finished tasks
:Lazy debug require("lazy").debug() Show debug information
:Lazy health require("lazy").health() Run :checkhealth lazy
:Lazy help require("lazy").help() Toggle this help page
:Lazy home require("lazy").home() Go back to plugin list
:Lazy install [plugins] require("lazy").install(opts?) Install missing plugins
:Lazy load {plugins} require("lazy").load(opts) Load a plugin that has not been loaded yet. Similar to :packadd. Like :Lazy load foo.nvim. Use :Lazy! load to skip cond checks.
:Lazy log [plugins] require("lazy").log(opts?) Show recent updates
:Lazy profile require("lazy").profile() Show detailed profiling
:Lazy reload {plugins} require("lazy").reload(opts) Reload a plugin (experimental!!)
:Lazy restore [plugins] require("lazy").restore(opts?) Updates all plugins to the state in the lockfile. For a single plugin: restore it to the state in the lockfile or to a given commit under the cursor
:Lazy sync [plugins] require("lazy").sync(opts?) Run install, clean and update
:Lazy update [plugins] require("lazy").update(opts?) Update plugins. This will also update the lockfile

Any command can have a bang to make the command wait till it finished. For example, if you want to sync lazy from the cmdline, you can use:

1
$ nvim --headless "+Lazy! sync" +qa

opts is a table with the following key-values:

  • wait: when true, then the call will wait till the operation completed
  • show: when false, the UI will not be shown
  • plugins: a list of plugin names to run the operation on
  • concurrency: limit the number of concurrently running tasks

Stats API (require("lazy").stats()):

1
2
3
4
5
6
7
8
9
10
11
12
{
-- startuptime in milliseconds till UIEnter
startuptime = 0,
-- when true, startuptime is the accurate cputime for the Neovim process. (Linux & Macos)
-- this is more accurate than `nvim --startuptime`, and as such will be slightly higher
-- when false, startuptime is calculated based on a delta with a timestamp when lazy started.
real_cputime = false,
count = 0, -- total number of plugins
loaded = 0, -- number of loaded plugins
---@type table<string, number>
times = {},
}

lazy.nvim provides a statusline component that you can use to show the number of pending updates. Make sure to enable config.checker.enabled = true to make this work.

Example of configuring lualine.nvim
1
2
3
4
5
6
7
8
9
10
11
12
require("lualine").setup({
sections = {
lualine_x = {
{
require("lazy.status").updates,
cond = require("lazy.status").has_updates,
color = { fg = "#ff9e64" },
},
},
},
})