前言

Neovim 的强大之一就在於小巧且種類繁多的功能外掛,基本上在 Neovim 的世界裡,只有你想不到的需求,沒有找不到的外掛,如果有,那就自己寫一個吧!

而隨著我們積年累月的使用與調教,外掛必定會越來越多,相依關係也勢必變得越來越複雜,這時有個方便的外掛管理工具就顯得非常重要了。

目前主流的工具有三個,分別是從 Vim8 延續下來,基於 Vim Script 所撰寫的 vim-plugs、使用 Lua 語言所撰寫的 packer.nvim(以下簡稱 packer),以及站在了 packer 的肩上,在推出後即廣受好評,同時也是我們這次的主角:lazy.nvim (以下簡稱 lazy)。

相較於 packer ,lazy 有著更強大的性能、以及更合理的外掛管理方式,且 packer 隨著的更新,它變得越來越混亂與臃腫,以致於在 lazy 出現後,packer 也原地爆炸,選擇停止維護。現在它轉生成了 pckr.nvim,但 packer 的官方也表明它沒有 lazy 來得穩定,而這也是我選擇從 packer 跳槽到 lazy 的主要原因。

所以,本章將介紹如何安裝與使用 lazy,如果你想直接複製完整的設定文件,也可以到這裡(我的 github)來複製完整的設定內容。

下載 lazy

首先,讓我們到 imp/ 中新增一個設定文件 lazy.lua,以及一個之後用來放各個外掛的設定文件的資料夾 plugins/

接著,編輯 lazy.lua,加入以下內容:

1
2
3
4
5
6
7
8
9
10
11
12
13
-- bootstrap lazy.nvim
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or 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)

然後,不要忘了到 init.lua 中去引用它:

require("imp.lazy")

這段程式的作用是,它會在 Neovim 每次啟動時檢查你是否已經下載了 lazy,如果沒有,它就會自動下載。

重新啟動 Neovim,這時你應該會注意到它停頓了一下,不要緊張,這表示它正在下載 lazy,下載完成後,我們就可以開始使用 lazy 了。

接下來我會對這段程式進行較詳細的說明,算是我在看了Understanding Neovim #2 - Plugins, Colorschemes之後的學習筆記,如果沒興趣的話,可以直接跳到下一段。

  1. 定義 lazy 的安裝路徑:

    local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"

    這裡使用了 vim.fn.stdpath() 來取得 Neovim 的 data 目錄路徑。我們可以直接在 Neovim 的 command line 中輸入以下指令來看看這個目錄究竟在哪:

    :lua print(vim.fn.stdpath("data"))

    一般來說,它應該會在 ~/.local/share/nvim。然後,這行程式碼會將 lazy 的存放目錄設定為這個目錄下的 lazy/lazy.nvim

    另外,data 這個目錄主要被 Neovim 用於存放各個外掛的資料和原始碼,也就是說,如果你想要親自去修改外掛底層的程式的話,你可以來這裡找它。

    而在過去沒有外掛管理器,或有外掛不支援管理器時,我們就是透過將外掛下載到這個目錄,然後再引用它們來使用的。

  2. 檢查並下載:

    if not (vim.uv or 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

    這段程式會檢查你的 data 目錄中是否已經下載了 lazy,如果沒有,它就會自動下載。

  3. 將 lazy 加入到 run time path:

    vim.opt.rtp:prepend(lazypath)

    run time path 是一個目錄清單,當 Neovim 在運行並加載功能和外掛時,它會去訪問這個清單中的目錄,並從中尋找它需要的功能,而這也就是 Neovim 運行外掛的原理了。

    另外,這裡使用 prepend 的目的是要將 lazy 加入這個清單的開頭,以確保 Neovim 在加載外掛時,會先透過 lazy,而非其他的目錄,以保證 lazy的正常運作並避免一些可能的衝突。

使用 lazy

要使用 lazy,我們得去調用 lazy 的 setup 函式:

require("lazy").setup(plugins, opts)
  • plugins:一個外掛的規格清單,我會在後續做更詳細的說明。
  • opts:lazy 的設定選項(皆為可選項)。

plugins 中,我們可以直接提供一組外掛的清單和額外規格,來讓 lazy 去下載與使用它們,但顯然,這樣會讓這份設定文件變得非常巨大。

所幸,我們可以直接輸入一個目錄,讓 lazy 去載入目錄中的所有設定文件,這也是為什麼我們先前特地開了一個資料夾,用來存放之後要下載的外掛的設定文件。

而關於 opts,通常我不太會去動它,lazy 的預設設定基本上沒有任何問題,所以我只基於無聊去調整了一些無關緊要的設定,如果你有興趣,可以到官方去看看 lazy 有什麼設定項可以玩。

現在,讓我們編輯 lazy.lua,到先前的程式碼下方加入以下的內容來啟用 lazy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
require("lazy").setup(
{ {import = "imp.plugins"} },
{
checker = {
enabled = true,
notify = false,
},
change_detection = {
enabled = true,
notify = false,
},
ui = {
border = "rounded",
}
}
)

說明:

  1. 設定外掛來源:
    首先,使用 import 來告訴 lazy 我們要用來存放外掛設定文件的目錄。
  2. 設定選項:
    • checker:它的作用是會自動檢查外掛是否有更新,但若每當有更新時就發出通知,那會很煩,所以我選擇啟用檢查,但關閉通知。
    • change_detection:和 checker 類似,不過這項檢查的是我們的設定文件是否有更動。
    • ui:我把 lazy 的 UI 邊框樣式改成圓角。

重新啟動 Neovim,這時你應該會發現它報錯了:

Error detected while processing /home/imp1ication/.config/nvim/init.lua:
No specs found for module imp.plugins
Press ENTER or type command to continue

不要緊張,這只是因為我們的 plugins/ 中還沒有任何的設定文件所導致的,讓我們先按下 Enter 鍵來跳過它的警告,然後輸入以下指令來開啟 lazy 的界面看看,確認 lazy 有在確實運作:

:Lazy

此時你應該就會看到類似如下的介面:

可以看到 Lazy 已經可以正確運行了,而且裡面已經有一個外掛,也就是 lazy 自己。

你可以將遊標移動到外掛名稱上面,然後輸入介面上方提供的,對應的大寫字母來對外掛進行管理操作,例如輸入 L 可以查看外掛的 Log,輸入 U 可以更新外掛等等。而這也就是 lazy 的基本使用方式了。

後記

至此,就是本章的所有內容了,lazy 已經能正確運作,而在下一章裡,我們終於要來開始下載與使用外掛。

而除了外掛本身的設定項外,lazy 在導入外掛時,還提供了許多的外掛規格(plugin spec)可以設定,包含它們的啟用條件、指定 commit 版本、以及其他的依賴外掛等等。

完整的說明同樣可以到官方去查看,而在之後的文章中,我只會對我有用到的部分進行說明。

另外,你也可以先到 Awesome Neovim 上逛逛,這裡收錄了 Neovim 大部分常用、好用的外掛,按功能分類,查找起來非常方便。

上一篇: Neovim 快捷鍵設定
下一篇: 第一個外掛 —— 顔色主題 Colorscheme

參考資料