こんにちは。ナミレリです。
今回はNeovimのプラグインマネージャであるLazy.nvimを紹介していきます。私はPacker.nvimを使ってきましたが、やっと念願のLazy.nvimに移行しました。移行してみた感想ですが、Lazy.nvimはUIも快適で、何より高速なでパフォーマンスが高く、また、プラグインの設定もスマートに記述することができる点が気に入っています。(が、最初は慣れが必要でした)
Packer.nvimから移行を検討している方や、Neovimのプラグイン管理に悩んでいる方、より効率的な開発環境を構築したい方は、ぜひLazy.nvimを活用するためにこの記事を参考にしてみてください。
この記事はこんな人にオススメ
- プラグインマネージャであるLazy.nvimを使ってみたい方
- Packer.nvimからLazy.nvimへ移行を検討している方
- Lazy.nvimの実際の使用例を知りたい方
- Lazy.nvimのLuaによる記述方法を知りたい方
- M3 MacBook Air 15インチ
- macOS Sonoma 14.5
- NVIM v0.10.1
- Parallels Desktop 19 for Mac バージョン 19.3.0 (54924)
目次
はじめに
私はプラグインマネージャとしてPacker.nvimを使っていますが、Packer.nvimは2023年8月以降メンテナンスされていません。Packer.nvimの代替としてLazy.nvimとPckr.nvimが案内されています。今回は主流であるLazy.nvimに移行していきます。
Lazy.nvimとは?
Lazy.nvimは、Packer.nvimの機能を拡張しさらにユーザーの利便性を高めるために開発されました。特に、パフォーマンスの向上や設定の簡略化に重点を置いています。
Packer.nvimから移行して感じることは、とにかく速い!UIがカッコイイ!ことです。少し慣れてくると、プラグイン毎に遅延ロードを細かく設定できるので、中級者以上も満足するパフォーマンスのチューニングが楽しくなります。
主な特徴としては以下の通りです。
超高速なプラグインロード:
必要な時にのみプラグインをロードすることで、Neovimの起動時間を大幅に短縮。
プラグインの遅延ロード:
特定のイベントや条件に応じてプラグインをロードする機能を提供。
カスタマイズ性:
ユーザーのニーズに合わせた細かい設定が可能。
インターフェース:
見た目がかっこいい!
Lazy.nvimの見た目
Packer.nvimとLazy.nvimの記述の比較
まずは、簡単にLazy.nvimの記述例をPacker.nvimと比較して見てみましょう。
例:Packer.nvimでのneo-tree.nvim設定
use {
"nvim-neo-tree/neo-tree.nvim",
branch = "v3.x",
requires = {
"nvim-lua/plenary.nvim",
"nvim-tree/nvim-web-devicons",
"MunifTanjim/nui.nvim",
"3rd/image.nvim",
},
require("neo-tree").setup({
window = {
position = "right",
},
})
}
例:Lazy.nvimでのneo-tree.nvim設定
return {
{
"nvim-neo-tree/neo-tree.nvim",
branch = "v3.x",
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-tree/nvim-web-devicons",
"MunifTanjim/nui.nvim",
"3rd/image.nvim",
},
opts = {
window = {
position = "right",
},
},
cmd = "Neotree",
},
}
上記の例でのPacker.nvimとLazy.nvimの記述の違いは下のようになります。
- use{}は不要
- requiresはdependencies
- setup{}も不要
- 設定のオプションはopts = {}に書く
他にも違いはありますが、上記の例では一旦こんな感じです。
また、上記の例でもopts = {}が出てきましたが、以下のようにLazy.nvimは、config = function()の代わりにopts = {}を書くのが良い例です。
{ "folke/todo-comments.nvim", opts = {} },
{
"folke/todo-comments.nvim",
config = function()
require("todo-comments").setup({})
end,
},
それでは、Lazy.nvimでかっこよく使いやすいNeovim環境を構築していきましょう。まずは既存環境をバックアップしておきます。
既存環境のバックアップ
Packer.nvimを使っている方は、Lazy.nvimをインストールする前に、既存の設定ファイル等をリネームしてバックアップしておきます。
Lazy.nvimが肌に合わずに元の環境に戻したい場合に備えて、必ずやっておきます。
mv ~/.config/nvim ~/.config/nvim_backup
mv ~/.local/share/nvim ~/.local/share/nvim_backup
mv ~/.local/state/nvim ~/.local/state/nvim_backup
Lazy.nvimのインストール
バックアップが済んだら、真っ新なNeovim環境にLazy.nvimをインストールしていきます。Lazy.nvimのインストールは、公式を参考にして進めていきます。
init.luaにブートストラップスクリプトを書かずに、別のファイル(例えば)~/.config/nvim/lua/config/lazy.luaにブートストラップを記述し、init.luaからそのファイルをrequireする方法などもありますが、
今回は、init.luaにブートストラップのスクリプトを書き、また構成は以下のようにしてみます。
Neovimのディレクトリ構成
ディレクトリ構成はこだわりや好みで自由に構成することができます。
ディレクトリ・ファイル | 説明 |
---|---|
~/.config/nvim/init.lua | Lazy.nvimのブートストラップスクリプトを書きます。 |
~/.config/nvim/lua/plugins/ | このディレクトリ配下の個別ファイルにプラグインを記述。 |
~/.config/nvim/lua/plugins/plugins_lazy.lua | インストールするプラグインをこのファイルに列挙。 |
~/.config/nvim/lua/core/ | このディレクトリ配下に、プラグイン以外の基本的な設定を記述。 |
~/.config/nvim/lua/user/ | このディレクトリ配下に、個別カスタマイズの設定を記述。 |
~/.config/nvim/
├── init.lua --> bootstrap script
└── lua/
├── plugins/
│ ├── plugins_lazy.lua
│ ├── plugin1_cfg.lua
│ └── plugin2_cfg.lua
├── core/
│ ├── autocmds.lua
│ ├── keymaps.lua
│ └── options.lua
└── user/
└── ui.lua
ディレクトリやファイルの作成
まずは上で紹介した、Neovimのディレクトリ構成(空のディレクトリや空のファイル)を下のコマンドで作ります。
mkdir -p ~/.config/nvim/lua/plugins && \
mkdir -p ~/.config/nvim/lua/core && \
mkdir -p ~/.config/nvim/lua/user && \
touch ~/.config/nvim/init.lua && \
touch ~/.config/nvim/lua/core/autocmds.lua && \
touch ~/.config/nvim/lua/core/keymaps.lua && \
touch ~/.config/nvim/lua/core/options.lua && \
touch ~/.config/nvim/lua/plugins/plugins_lazy.lua && \
touch ~/.config/nvim/lua/user/ui.lua && \
echo 'return {}' > ~/.config/nvim/lua/plugins/plugins_lazy.lua
最後の、echo 'return {}' > ○○ですが、プラグインリストを定義するファイル(plugins_lazy.lua)はテーブルで返す必要があるため、return {}という形式で空のテーブルを返すための記述を書いています。
こうすることで、plugins_lazy.luaを適切に書くまでエラーなくNeovimを起動することができます。
Luaのテーブルについて
先程のようなLuaのテーブルは、連想配列(ハッシュ)として機能し、キーと値のペアでデータを保持します。テーブルは以下のように作成できます。
local my_table = {
key1 = "value1",
key2 = "value2",
key3 = {
sub1 = "value3",
sub2 = "value4",
},
}
便利なブートストラップスクリプト
事前にLazy.nvimをインストールしていなくても、Lazy.nvimのインストール状態をチェックし、必要な場合は自動的にインストールするように設定します。
~/.config/nvim/init.luaを下のように編集します。
nvim ~/.config/nvim/init.lua
~/.config/nvim/init.lua
-- lazy.nvim boot strap
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",
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
-- local plugins
local plugins = {
{ import = "plugins" },
}
-- local opts
local opts = {
root = vim.fn.stdpath("data") .. "/lazy",
lockfile = vim.fn.stdpath("config") .. "/lazy-lock.json",
concurrency = 10,
checker = { enabled = true },
log = { level = "info" },
}
-- leader key
vim.g.mapleader = " "
-- lazy setup
require("lazy").setup(plugins, opts)
-- require core/ and user/
require("core.options")
require("core.autocmds")
require("core.keymaps")
require("user.ui")
上に記載したinit.luaのlazy.nvim boot strapの説明です。
-- lazy.nvim boot strap
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",
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
lazypath:lazy.nvimのインストールパスを定義しています。vim.fn.stdpath("data")はNeovimの標準データディレクトリを返します。
if not vim.loop.fs_stat(lazypath):指定されたパスにlazy.nvimが存在しない場合にのみ、以下の処理を実行します。
vim.fn.system({...}):Gitを使用してlazy.nvimを指定されたパスにクローンします。
vim.opt.rtp:prepend(lazypath):runtimepathにlazy.nvimのパスを追加します。
上に記載したinit.luaのlocal pluginsの説明です。
-- local plugins
local plugins = {
{ import = "plugins" },
}
plugins:プラグイン設定のテーブルを定義しています。ここではplugins配下のファイルからプラグイン設定をインポートするように指定しています。
こうすることで、~/.config/nvim/lua/plugins/配下にプラグイン毎に設定ファイルを分割しても、そのファイルをrequireせずに自動的に読み込んでくれます。
例えば、以下のようにプラグインのファイルを分割して管理することができます。
例
-- 例:~/.config/nvim/lua/plugins/*.lua
return {
-- colorscheme
{
"catppuccin/nvim",
name = "catppuccin",
priority = 1000,
config = function()
vim.cmd.colorscheme("catppuccin")
end,
},
}
上に記載したinit.luaのlocal optsの説明です。
-- local opts
local opts = {
root = vim.fn.stdpath("data") .. "/lazy",
lockfile = vim.fn.stdpath("config") .. "/lazy-lock.json",
concurrency = 10,
checker = { enabled = true },
log = { level = "info" },
}
root:lazy.nvimのルートディレクトリを指定しています。
lockfile:ロックファイルのパスを指定しています。
concurrency:ラグインのインストールや更新時に使用する同時実行スレッドの数を指定しています。
checker:プラグインの更新チェック機能を有効にしています。
log:ログレベルをinfoに設定しています。
上に記載したinit.luaのleader keyの説明です。
-- leader key
vim.g.mapleader = " "
vim.g.mapleader:リーダーキーをスペースキーに設定しています。
上に記載したinit.luaのlazy setupの説明です。
-- lazy setup
require("lazy").setup(plugins, opts)
require("lazy").setup():lazy.nvimをセットアップします。
起動とLazyコマンドについて
起動
Neovimを再度起動してみましょう。以下のメッセージが表示されたらENTERを押して続けます。
nvim
Neovimが起動したら、:LazyでLazy.nvimを起動します。
Lazyコマンド
以下がLazy.nvimの画面でのキーボードショートカットです。
メニュー | キーボード ショートカット | コマンド | 説明 |
---|---|---|---|
HOME | H | :Lazy | プラグインリストの表示 |
Install | I | :Lazy install | 足りないプラグインをインストール |
Update | U | :Lazy update | プラグインをアップデート ロックファイルも更新さる |
Sync | S | :Lazy sync | インストール、クリーン、アップデートを実行 |
Clean | X | :Lazy clean | 必要ないプラグインを削除 |
Check | C | :Lazy check | 更新をチェックしてログを表示 |
Log | L | :Lazy log | 最近の更新を表示 |
Restore | R | :Lazy restore | ロックファイルの状態に全てのプラグインを更新 |
Profile | P | :Lazy profile | 詳細なプロファイルを表示 |
Debug | D | :Lazy debug | 詳細なプロファイルを表示 |
Help | ? | :Lazy help | ヘルプページを表示 |
続いて、~/.config/nvim/lua/core/配下の設定ファイルを記述していきます。
~/.config/nvim/lua/core/配下のファイルについて
それでは、~/.config/nvim/lua/core/配下の各ファイルの設定をしていきます。と言ってもkeymaps.luaとautocmds.luaは現段階では空のファイルとしておき、options.luaのみ設定していきます。
options.luaについて
先程紹介したinit.luaでrequireするファイルは以下の4つですが、この段階ではoptions.luaのみ設定します。
options.luaの内容については、下の記事を参考に設定してください。
keymaps.luaについて
(このブログでは)keymaps.luaには、様々なインストールしたプラグインインのkeymapを設定するファイルとします。現段階で空のファイルです。
autocmds.luaについて
(このブログでは)autocmds.luaには、特定のイベントが発生したときに自動的に実行するコマンドを記述するファイルとします。vim.api.nvim_create_autocmd関数(やvim.api.nvim_create_augroup関数)を使用して自動コマンドを設定します。現段階で空のファイルです。
プラグインのインストール準備
ディレクトリ・ファイル | 説明 |
---|---|
~/.config/nvim/lua/plugins/ | このディレクトリ配下の個別ファイルにプラグインを記述。 |
~/.config/nvim/lua/plugins/plugins_lazy.lua | インストールするプラグインをこのファイルに列挙。 |
plugins_lazy.luaは以下のようにluaテーブルで記述していきます。
plugins_lazy.luaの記述例
return {
{ "folke/todo-comments.nvim", opts = {} },
}
デザイン・UI関連のプラグイン
以前の記事でも紹介した私のおすすめする(使っている)見た目、デザインやUIに関わるプラグインをベースにLazy.nviでインストールしていきます。プラグインの概要や設定方法を紹介していきます。
デザイン・UI関連のおすすめプラグイン
カテゴリ | プラグイン | 説明 |
---|---|---|
カラースキーム | folke/tokyonight.nvim | 美しいダークカラーのテーマ |
カラースキーム | catppuccin/nvim | 美しいパステルカラーのテーマ |
ファイルブラウザ | nvim-neo-tree/neo-tree.nvim | ディレクトリやファイルをツリー構造で表示 |
・アイコン | nvim-tree/nvim-web-devicons | ファイルタイプに応じたアイコン |
・ライブラリ | nvim-lua/plenary.nvim | ユーティリティライブラリ |
・ライブラリ | MunifTanjim/nui.nvim | UIコンポーネントライブラリ |
ステータスライン | nvim-lualine/lualine.nvim | ステータスラインをカスタマイズ |
タブライン | kdheepak/tabline.nvim | タブラインをカスタマイズ |
インデント | echasnovski/mini.indentscope | アニメーションするインデントガイドを表示 |
シンタックスハイライト | nvim-treesitter/nvim-treesitter | シンタックスハイライトする |
ポップアップUI | folke/noice.nvim | ポップアップメニューのUI |
gitのサイン表示 | lewis6991/gitsigns.nvim | gitの状態を可視化する |
それでは、~/.config/nvim/lua/plugins/plugins_lazy.luaに上のプラグインの設定をしていきます。
カラースキーム(catppuccin/nvim、folke/tokyonight.nvim)
nvim ~/.config/nvim/lua/plugins/plugins_lazy.lua
~/.config/nvim/lua/plugins/plugins_lazy.lua
return {
-- colorscheme
{
"catppuccin/nvim",
name = "catppuccin",
lazy = false,
priority = 1000,
},
{
"folke/tokyonight.nvim",
lazy = false,
priority = 1000,
},
}
上に記載したlazy = false、priority = 1000の説明です。
lazy = false
この設定は、プラグインを遅延読み込みしないことを指定しています。Neovimの起動する際に、即プラグインをに読み込みます。カラースキームは即読み込ませるものなでこのように設定します。
priority = 1000
この設定は、プラグインの読み込み順序を制御するための優先度の設定です。数値が大きいほど優先度が高く、早いタイミングで読み込まれます。priority = 1000と設定することで、他のプラグインよりも先に読み込まれる設定です。カラースキームは、高い優先度を設定することが一般的です。
今回はcatppuccinを有効にしています。tokyonightはenable = falseで無効にしています。
この記事ではカラースキームの設定を~/.config/nvim/lua/user/ui.luaに設定します。
nvim ~/.config/nvim/lua/user/ui.lua
~/.config/nvim/lua/user/ui.lua
-- colorscheme
vim.cmd.colorscheme "catppuccin-macchiato"
-- vim.cmd.colorscheme "tokyonight-storm"
ファイルブラウザ(nvim-neo-tree/neo-tree.nvim)
~/.config/nvim/lua/plugins/plugins_lazy.luaを編集しますが、
~/.config/nvim/lua/plugins/plugins_lazy.lua
-- file browser
{
"nvim-neo-tree/neo-tree.nvim",
branch = "v3.x",
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-tree/nvim-web-devicons",
"MunifTanjim/nui.nvim",
},
opts = {
window = {
position = "right",
},
event_handlers = {
{
event = "file_open_requested",
handler = function()
require("neo-tree.command").execute({ action = "close" })
end,
},
},
},
cmd = "Neotree",
},
上に記載したdependencies、opts、cmdの説明です。
dependencies
dependenciesは、プラグインが依存する他のプラグインを指定するためのオプションです。依存関係が正しく解決され、必要なプラグインが先にインストールされロードされるようになります。Packer.nvimのrequiresです。
opts
optsは、プラグインに渡す設定を指定するためのオプションです。プラグインが初期化される際に、指定した設定が適用されます。
cmd
cmdは、プラグインが読み込まれるトリガーとなるコマンドを指定するためのオプションです。指定したコマンドが実行されたときにプラグインが読み込まれるので、Neovimの起動時間を短縮できます。
keymapは、以下のように<leader>nnに設定しています。
~/.config/nvim/lua/core/keymaps.lua
local vim = vim
local opts = { noremap = true, silent = true } -- local term_opts = { silent = true }
local keymap = vim.keymap.set
-- オプションテーブルにdescを追加するための簡略化関数
local function extend_opts(desc)
return vim.tbl_extend("force", opts, { desc = desc })
end
-- Neotree
keymap("n", "<leader>nn", ":Neotree toggle<cr>", extend_opts("Neotree Toggle"))
ステータスライン(nvim-lualine/lualine.nvim)
nvim ~/.config/nvim/lua/plugins/plugins_lazy.lua
~/.config/nvim/lua/plugins/plugins_lazy.lua
{
"nvim-lualine/lualine.nvim",
dependencies = {
"nvim-tree/nvim-web-devicons",
},
opts = {},
event = "VeryLazy",
},
上に記載したevent = "VeryLazy"の説明です。
event = "VeryLazy"
event = "VeryLazy"は、、Neovimの起動後にアイドル状態になったときに発生するイベントです。起動時に必要な最低限のプラグインや設定がロードされた後、ユーザーが最初の操作を行う前に遅延してプラグインをロードします。
利用シーン
例えば、起動時にすぐには必要とされないが、最終的には必要となるプラグインをロードする際に使用します。
タブライン(kdheepak/tabline.nvim)
nvim ~/.config/nvim/lua/plugins/plugins_lazy.lua
~/.config/nvim/lua/plugins/plugins_lazy.lua
-- tabline
{
"kdheepak/tabline.nvim",
opts = {},
event = "BufWinEnter",
},
上に記載したeventの説明です。
event
eventは、指定したイベントが発生したときにプラグインをロードします。必要に応じてプラグインをロードすることができるので、Neovimの起動時間の短縮することができます。
上の例では、event = "BufWinEnter"とし、バッファがウィンドウに表示されるときにプラグインをロードするようにしています。
その他にもたくさんのイベントがありますので、よく使われるイベントを紹介します。
よく使われるイベント
イベント | 説明 |
---|---|
BufEnter | バッファがアクティブになったときに発生 |
BufRead | バッファにファイルが読み込まれたときに発生 |
BufReadPre | ファイルがバッファに読み込まれる前に発生 |
BufReadPost | ファイルが読み込まれた後に発生 |
BufWinEnter | バッファがウィンドウに表示されるときに発生 |
BufNewFile | 新しいファイルを作成するためにバッファを開いたときに発生 |
BufWrite | バッファが書き込まれるときに発生 |
VimEnter | Neovimが起動して初期化が完了したときに発生 |
InsertEnter | 挿入モードに入ったときに発生 |
CmdlineEnter | コマンドラインモードに入ったときに発生 |
FileType | バッファのファイルタイプが設定されたときに発生 |
インデント(echasnovski/mini.indentscope)
nvim ~/.config/nvim/lua/plugins/plugins_lazy.lua
~/.config/nvim/lua/plugins/plugins_lazy.lua
-- indent
{
"echasnovski/mini.indentscope",
opts = {
symbol = "▏",
},
event = "BufRead",
},
上の例では、event = "BufRead"とし、バッファにファイルが読み込まれたときにプラグインをロードするようにしています。
シンタックスハイライト(nvim-treesitter/nvim-treesitter)
nvim ~/.config/nvim/lua/plugins/plugins_lazy.lua
~/.config/nvim/lua/plugins/plugins_lazy.lua
-- nvim-treesitter
{
"nvim-treesitter/nvim-treesitter",
event = { "BufRead", "BufNewFile", "InsertEnter" },
build = ":TSUpdate",
config = function()
local configs = require("nvim-treesitter.configs")
configs.setup({
ensure_installed = {
"awk",
"bash",
"comment",
"c",
"css",
"csv",
"diff",
"gpg",
"html",
"htmldjango",
"javascript",
"json",
"lua",
"markdown",
"python",
"rust",
"sql",
"ssh_config",
"tmux",
"toml",
"vim",
"xml",
"yaml",
"regex",
"vimdoc",
},
sync_install = false,
auto_install = true,
highlight = { enable = true },
indent = { enable = true },
})
end,
},
ensure_installedで指定した言語パーサがインストールされます。サポートされている言語の一覧はこちらです。
上の例では、event = { "BufRead", "BufNewFile", "InsertEnter" }としています。
- バッファにファイルが読み込まれたとき
- 新しいファイルを作成するためにバッファを開いたとき
- 挿入モードに入ったとき
にプラグインをロードするようにしています。
ポップアップUI(folke/noice.nvim)
nvim ~/.config/nvim/lua/plugins/plugins_lazy.lua
~/.config/nvim/lua/plugins/plugins_lazy.lua
-- noice
{
"folke/noice.nvim",
event = "VeryLazy",
dependencies = {
"MunifTanjim/nui.nvim",
"rcarriga/nvim-notify",
},
opts = {
routes = {
{
filter = { event = "msg_show", find = "E486: Pattern not found: .*" },
opts = { skip = true },
},
},
lsp = {
-- override markdown rendering so that **cmp** and other plugins use **Treesitter**
override = {
["vim.lsp.util.convert_input_to_markdown_lines"] = true,
["vim.lsp.util.stylize_markdown"] = true,
["cmp.entry.get_documentation"] = true, -- requires hrsh7th/nvim-cmp
},
},
},
},
event = "VeryLazy"
event = "VeryLazy"は、、Neovimの起動後にアイドル状態になったときに発生するイベントです。起動時に必要な最低限のプラグインや設定がロードされた後、ユーザーが最初の操作を行う前に遅延してプラグインをロードします。
gitのサイン表示(lewis6991/gitsigns.nvim)
nvim ~/.config/nvim/lua/plugins/plugins_lazy.lua
~/.config/nvim/lua/plugins/plugins_lazy.lua
-- git
{
"lewis6991/gitsigns.nvim",
config = true,
event = { "BufReadPre", "BufNewFile" },
},
上の例では、event = { "BufReadPre", "BufNewFile" }としています。
- ファイルがバッファに読み込まれる前
- 新しいファイルを作成するためにバッファを開いたとき
にプラグインをロードするようにしています。
起動時間
Lazy.nvimでは、:Lazy profileで起動時間を確認することができます。この記事で紹介したプラグインをインストールした状態で、29.57msとなりました。
最後に
最後まで読んでいただきありがとうございます。今回のLazy.nvimで最初にやっておきたい初期設定はいかがでしたでしょうか。
次回はLSPの設定を紹介します。https://namileriblog.com/mac/lazy_nvim_lsp/
NeovimとHHKBの組み合わせは、コーディング体験を最適化し、より生産的で満足のいくものにするための最高のツールです。コーディングの楽しさと効率性を新たなレベルへと引き上げてくれます。
定番おすすめ記事
Neovimをかっこ良くクールに使う設定