Neovimのプラグイン管理をdeinからlazy.nvimに移行した話

# ※本記事は当方の更新の過程をもとに、Claudeが自動生成しました


## はじめに

長らくNeovimのプラグイン管理に[dein.vim](https://github.com/Shougo/dein.vim)を使用してきましたが、最近のNVIM Lua時代に合わせて[lazy.nvim](https://github.com/folke/lazy.nvim)に移行しました。この記事では、その移行過程と注意点を共有します。

## なぜlazy.nvimに移行したのか

- **Pure Lua**: 設定をVimscriptからLuaに完全移行するため
- **高速**: lazy.nvimはNeovimのために最適化されたプラグインマネージャー
- **モジュール化**: 設定ファイルを適切に分割して管理できる
- **遅延読み込み**: パフォーマンス向上のための機能が標準搭載
- **開発が活発**: 最新のNeovimの機能をすぐに活用できる

## 移行のステップ

### 1. lazy.nvimのインストール

`init.lua`にbootstrap codeを追加します：

```lua
-- lazy.nvim bootstrap installation
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv).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)

-- リーダーキーの設定（プラグイン設定の前に行う）
vim.g.mapleader = " "
vim.g.maplocalleader = "\\"
```

### 2. 基本設定ファイルの準備

設定ファイルを適切に分割します：

- `lua/options.lua`: 基本設定
- `lua/keymaps.lua`: キーマッピング
- `lua/autocmds.lua`: 自動コマンド
- `lua/lsp/init.lua`: LSP全体の設定
- `lua/lsp/cmp.lua`: 補完関連の設定

### 3. プラグイン設定の移行

deinの各プラグイン設定をlazy.nvmの形式に変換します。`lua/plugins.lua`にプラグインを定義します：

```lua
-- lua/plugins.lua
-- プラグインとその設定

return {
  -- プラグイン定義がここに入ります
  -- 例：
  {
    "benjaminwhite/Benokai",
    lazy = false,
    priority = 1000,
    init = function()
      vim.cmd([[
        colorscheme Benokai
        
        " 各種ハイライト設定
        ...
      ]])
    end,
  },
  
  -- 他のプラグイン...
}
```

### 4. プラグインマネージャの設定

`init.lua`にlazy.nvimの設定を追加します：

```lua
-- プラグインマネージャの設定
require("lazy").setup({
  -- プラグインの基本スペック
  spec = {
    -- プラグイン定義ファイルのインポート
    { import = "plugins" },
  },
  
  -- デフォルト設定
  defaults = {
    lazy = false, -- デフォルトではプラグインを遅延読み込みしない（dein挙動と合わせる）
    version = false, -- 常に最新のバージョン（タグではなくmaster）を使用
  },
  
  -- インストール設定
  install = {
    colorscheme = { "Benokai" }, -- 既存のカラースキームを優先
  },
  
  -- チェッカー（更新確認）
  checker = {
    enabled = true, -- プラグインの更新確認を有効化
    notify = false, -- 通知を無効化
  },
  
  -- 変更検出
  change_detection = {
    enabled = true, -- 設定ファイルの変更検出を有効化
    notify = false, -- 通知を無効化
  },
  
  -- パフォーマンス設定
  performance = {
    rtp = {
      disabled_plugins = {
        "gzip",
        "matchit",
        "matchparen",
        "netrwPlugin",
        "tarPlugin",
        "tohtml",
        "tutor",
        "zipPlugin",
      },
    },
  },
})
```

## プラグイン定義の変換例

### deinでの定義（古い書き方）

```vim
" カラースキーム
call dein#add('benjaminwhite/Benokai')
```

### lazy.nvimでの定義（新しい書き方）

```lua
{
  "benjaminwhite/Benokai",
  lazy = false,
  priority = 1000,
  init = function()
    vim.cmd([[
      colorscheme Benokai
      " 設定など...
    ]])
  end,
}
```

## 主なlazy.nvimの機能と設定方法

### 1. 遅延読み込み

deinではVimscriptの`hook_*`フックを使っていましたが、lazy.nvimではより直感的に設定できます：

```lua
{
  "nvim-telescope/telescope.nvim",
  -- tag = "0.1.x",
  dependencies = { 
    "nvim-lua/plenary.nvim" 
  },
  init = function()
    -- キーマップなどの初期化
    vim.keymap.set('n', 'fr', "<cmd>Telescope find_files<cr>", { desc = 'Find files' })
  end,
  cmd = "Telescope",  -- コマンド実行時に読み込み
}
```

### 2. イベントでの読み込み

特定のイベントで読み込むことができます：

```lua
{
  "nvim-treesitter/nvim-treesitter",
  build = ":TSUpdate",
  event = { "BufReadPost", "BufNewFile" },  -- バッファ読み込み時に有効化
  init = function()
    -- 設定など...
  end,
}
```

### 3. ファイルタイプに基づく読み込み

特定のファイルタイプでのみ読み込むこともできます：

```lua
{
  "alvan/vim-closetag",
  init = function()
    vim.g.closetag_filenames = '*.html,*.xhtml,*.phtml,*.erb,*.php,*.vue,*.tsx'
  end,
  ft = { 'html', 'xhtml', 'phtml', 'erb', 'php', 'vue', 'typescriptreact'},  -- これらのファイルタイプでのみ読み込み
}
```

## LSP設定の分離

LSP関連の設定は複雑になりがちなので、別ファイルに分けて管理します：

```lua
-- init.luaから読み込み
require('lsp').setup()
require('lsp.cmp').setup()
```

`lsp/init.lua`では全体的なLSP設定を行い、`lsp/cmp.lua`では補完関連の設定を行います。

## 移行時の注意点

1. **遅延読み込みのバランス**: deinからの移行では、デフォルトで`lazy = false`に設定しました。これは既存の挙動を維持するためですが、パフォーマンスを重視する場合は必要に応じて`lazy = true`に変更すると良いでしょう。

2. **インポートとパス設定**: Luaモジュールのパスを適切に設定することが重要です。
   ```lua
   -- Luaモジュール検索パスに現在のディレクトリを追加
   package.path = vim.fn.stdpath('config') .. "/lua/?.lua;" .. package.path
   ```

3. **コマンドとAPIの変換**: 
   - VimscriptのコマンドはLuaでは`vim.cmd([[...]])`内に記述
   - `autocmd`は`vim.api.nvim_create_autocmd`に変換
   - オプション設定は`vim.opt`を使用

4. **設定の優先順位**: カラースキームなど見た目に関わる設定は`priority`を高く設定して、先に読み込まれるようにしています。

## まとめ

deinからlazy.nvimへの移行は、Neovimの設定をより現代的で整理された形に進化させる良い機会となりました。lazy.nvimの多彩な機能により、プラグイン管理が容易になり、設定ファイルも整理されて管理しやすくなりました。

特に以下のメリットを感じています：

- **モジュール化された設定**: 関連する設定を適切に分割できた
- **Pure Lua**: Vimscriptから完全にLuaへ移行できた
- **パフォーマンス向上**: 必要なときだけプラグインを読み込むことで起動が高速化
- **メンテナンス性向上**: プラグインごとに設定が分離され、依存関係も明確になった

これからNeovimの設定をLuaに移行する方の参考になれば幸いです。

## 参考リンク

- [lazy.nvim GitHub](https://github.com/folke/lazy.nvim)
- [Neovim公式ドキュメント](https://neovim.io/doc/)