📝

init.vim & dein から init.lua & lazy.nvim へ、シンプル設定で移行した

2023/01/26に公開

背景

neovim で会社の先輩からもらった vimrc を 7 年くらい継ぎ足し継ぎ足しで使っているぐちゃぐちゃの init.vim と、どこでどう動いているか把握していないプラグインも混ざっている dein.toml を、 init.lua & lazy.nvim への移行に合わせて整理した。

lazy.nvim とは

https://github.com/folke/lazy.nvim

最近急速に注目を浴びているらしい Lua 製(かつ Lua 記述)のプラグインマネージャ。
README を見る限りだと init.lua でのセットアップしか書いていない。vim script に翻訳すれば init.vim でも動くのかもしれないが、変な橋を渡って消耗したくないので今回は素直に init.lua 化をしている。

init.lua の記述

$XDF_CONFIG_HOME/nviminit.lua ファイルを作成する。 init.vim と両方存在していると競合しているとエラー表示が出るため、 init.vim を別名に変更して退避し、 init.lua のみを読み込ませる。 nvim -u {path/to/file} で設定ファイルを指定して起動する。
init.lua 内の require 関数では、直下の lua ディレクトリ以下を読み込むことができる。必要に応じてディレクトリ以下にファイルを分割して作成する。

まず以下のように、必要最低限だろうものに絞って基本設定を記述していく。文法については nvim-lua-guide-ja を参考にしている。

init.lua
-- encoding
vim.o.encofing = 'utf-8'
vim.scriptencoding = 'utf-8'

-- visual
vim.o.ambiwidth = 'double'
vim.o.tabstop = 2
vim.o.softtabstop = 2
vim.o.shiftwidth = 2
vim.o.expandtab = true
vim.o.autoindent = true
vim.o.smartindent = true

vim.o.visualbell = true
vim.o.number = true
vim.o.showmatch = true
vim.o.matchtime = 1

-- search
vim.o.incsearch = true
vim.o.ignorecase = true
vim.o.smartcase = true
vim.o.hlsearch = true
vim.api.nvim_set_keymap('n', '<Esc><Esc>', ':nohl<CR>', { noremap = true, silent = true})

-- manipulation
vim.g.mapleader = ' '
vim.opt.clipboard:append{'unnamedplus'}
vim.o.ttimeout = true
vim.o.ttimeoutlen = 50

vim.o.undofile = true
vim.o.undodir = vim.fn.stdpath('cache') .. '/undo'

vim.api.nvim_set_keymap('n', 'j', 'gj', { noremap = true })
vim.api.nvim_set_keymap('n', 'k', 'gk', { noremap = true })
vim.api.nvim_set_keymap('n', '<Down>', 'gj', { noremap = true })
vim.api.nvim_set_keymap('n', '<Up>', 'gk', { noremap = true })
vim.api.nvim_set_keymap('n', 'gj', 'j', { noremap = true })
vim.api.nvim_set_keymap('n', 'gk', 'k', { noremap = true })

設定内容の詳細はこのあたりを参考にしてほしい。
https://qiita.com/t_uda/items/407220bfc989f901baf5
https://itchyny.hatenablog.com/entry/2014/12/25/090000

plugin の設定

まず lazy.nvim の設定を別ファイルに、公式の README のほぼコピペで記述する。

lua/lazy_nvim.lua
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)

plugins = require('plugins')

require('lazy').setup(plugins)

plugin 自体は lua/plugins.lua に定義している。こちらも同様、 LSP 等は除き、ターミナル上で簡単にファイルを編集する際にあると便利なもののみに留める。

lua/plugins.lua
return {
  { -- colorscheme
    'blueshirts/darcula',
    config = function()
      vim.cmd([[colorscheme darcula]])
    end
  },
  'editorconfig/editorconfig-vim',
  {
    'nvim-lualine/lualine.nvim',
    dependencies = { 'nvim-tree/nvim-web-devicons' },
    config = function()
      require('lualine').setup()
    end
  },
  {
    'lewis6991/gitsigns.nvim',
    config = function()
      require('gitsigns').setup()
    end
  },
  {
    'numToStr/Comment.nvim',
    config = function()
        require('Comment').setup()
        vim.api.nvim_set_keymap('n', '<C-_>', 'gcc', {})
        vim.api.nvim_set_keymap('v', '<C-_>', 'gc', {})
    end
  },
  {
    'nvim-tree/nvim-tree.lua',
    dependencies = {
      'nvim-tree/nvim-web-devicons',
    },
    config = function()
      require("nvim-tree").setup({
        open_on_setup_file = true
      })
    end
  }
}

以下のように plugin ごとに設定を記述するファイルに分割することで、詳細設定を plugins.lua から隠蔽することができる。(require は lua からの相対 path)

config/nvim-tree
require("nvim-tree").setup({
  open_on_setup_file = true
})
plugins.lua
return {
  { -- colorscheme
    'blueshirts/darcula',
    config = function()
      vim.cmd([[colorscheme darcula]])
    end
  },
  'editorconfig/editorconfig-vim',
  {
    'nvim-lualine/lualine.nvim',
    dependencies = { 'nvim-tree/nvim-web-devicons' },
    config = function()
      require('config/lualine')
    end
  },
  {
    'lewis6991/gitsigns.nvim',
    config = function()
      require('config/gitsigns')
    end
  },
  {
    'numToStr/Comment.nvim',
    config = function()
      require('config/comment')
    end
  },
  {
    'nvim-tree/nvim-tree.lua',
    dependencies = {
      'nvim-tree/nvim-web-devicons',
    },
    config = function()
      require('config/nvim-tree')
    end
  }

これで簡素ながら init.lua への移行が完了した。今まで何をしているかわからなかった設定をすべて削ぎ落としたが、問題なく動いているように見える。
完成したコードはこちら
https://github.com/euxn23/init-lua-and-lazy-nvim-sample

本来は別の dotfiles リポジトリで管理しているが、永遠に未完成である……。

appendix: plugin の追加

筆者は neovim ではなく IDE を主に開発に使用しているため上記でおおよそ困らなそうであるが、拡張するのであれば以下を参考に plugin を追加すると良い。

https://zenn.dev/yutakatay/articles/neovim-plugins-2022
https://zenn.dev/yano/articles/neovim_frontend_development_2022

入れるのであれば LSP 、ファイラ系、フォーマッタ辺りを必要に応じて設定しようと思っている。

最後に

シンプルな設定のみで移行後のファイルを作ったので、移行に際して何が必要なのか参考にして欲しい。
dotfiles もくもく会という discord サーバがあるため、興味がある人は是非入ってみてほしい。(現在あまり活発ではないが、たまに通話しながらのもくもく会をしたい目的で建てている。)
https://discord.gg/TkJMYFk4bP

Discussion