🔰

Neovim の環境構築方法

2023/04/15に公開

背景

私は、Neovimを使う前は、1年半ほどVS Codeを利用していました。
あるときに、同じ職場の先輩エンジニアの方のVim勉強会がありました。そこで、はじめてVimの操作方法を学んだことが、Vimっていいなぁになりました。
EC2サーバー内に入ったら、Vimを操作することが多くなるし、ターミナル内でコーディングを完結できる点に魅力を感じて、Vimへ移行することに決めました。
しかし、この記事を書くまでに3回ほど、エディタの移行に失敗しています。ですが、とうとう日頃使用していたVS CodeからNeovimだけでコーディングできるようになりました。
Neovim の環境構築とカスタマイズ方法を書くことで、Neovimユーザーが少しでも増えたらいいと思い、この記事を書きます。

前提知識 VimとNeovimとはなに?

Vim

https://mag.osdn.jp/07/07/18/0849244

viクローンのVimは、Emacsと並ぶオープンソース・エディタの巨頭である。このエディタは、単にviのオープンソース版というだけではなく、スクリプトやプラグインによる高い拡張性といったオリジナルのviにない特徴も備えている。

Neovim

https://mag.osdn.jp/18/06/13/170000

Vimからフォークしたテキストエディタ「Neovim」開発チームは6月11日、最新版「Neovim 0.3.0」を公開した。
NeovimはVimの良い部分はそのままに拡張性と使い勝手にフォーカスしたというテキストエディタ。コアを改変することなく高度なUIを導入し、非同期のジョブ管理など複数の開発者で作業を分ける機能も備え、メンテナンスも簡便にした。clojure、lisp、go、haskell、lua、javascript、perl、python、ruby、rustなどの言語にAPIを介してアクセスできる。ほとんどのVimのプラグインと互換性があるという。
Neovim 0.3は2017年5月に公開されたバージョン0.2に続く最新版。VimL表現パーサーを内蔵し、コマンドを呼びだす<Cmd>キーを実装した。APIも加わった。
Windows向けではMSVCビルドのサポートが加わった。テキストユーザーインターフェイス(TUI)でも多数の細かな強化が加わっている。
Neovim 0.3はApache License 2で公開されている。

Neovim のダウンロード

私は、普段Mac OSを使用してるため、MacへNeovimをインストールする方法を紹介します。他のOSをご利用の方は、こちらを参照してください。
https://github.com/neovim/neovim#install-from-package

Homebrewを利用している場合、このコマンドで最新のバージョンをインストールできます。

brew install neovim

インストールが完了したら、Neovimを起動しましょう。
このコマンドを実行すると以下、画像のようにNeovimが起動します!

nvim

次にNeovimの設定をしていきましょう。

Tips

毎回、nvim と打つのは面倒なので、私は以下のようにalias を貼っています。

# editor
alias v='nvim'

設定ファイルを作成する

ホームディレクトリでファイルを作成する。

cd .config
mkdir nvim && cd nvim
nvim init.lua

次は、Neovimのデフォルトの設定を変更していくことを解説していきます。

Neovim のデフォルト設定を変更する

.config/nvim/init.lua
local opt = vim.opt
-- 「※」等の記号を打つと、半角文字と重なる問題がある。「※」などを全角文字の幅で表示するために設定する
opt.ambiwidth = 'double'

-- 新しい行を改行で追加した時に、ひとつ上の行のインデントを引き継がせます。
opt.autoindent = true
opt.smartindent = true
-- smartindent と cindent を両方 true にしたときは、cindent のみ true になるようです。
-- opt.cindent = true
-- カーソルが存在する行にハイライトを当ててくれます。
opt.cursorline = true

-- カーソルが存在する列にハイライトを当てたい場合、下記をtrueにする。
-- opt.cursorculumn = true

-- TABキーを押した時に、2文字分の幅を持ったTABが表示されます。
opt.tabstop = 2
opt.softtabstop = 2
opt.shiftwidth = 2
-- tabstop で設定した数の分の半角スペースが入力されます。
opt.expandtab = true
-- カーソル行からの相対的な行番号を表示する
opt.relativenumber = true
opt.termguicolors = true

ノーマルモード時に、:wqを実行することでファイルを保存して、閉じることができます。

もう一度、Neovimを開くと、先程設定した項目が有効になっているはずです。もし、エラーが発生した場合は、上記のコードをタイポしています。

# ~/.config/nvim に移動して、下記のコマンドを実行します。
mkdir lua && cd lua
# 好きな名前でディレクトリを作成してください。
mkdir user_name && cd user_name
nvim basic_config.lua

~/.config/nvim/lua/user_name/basic_config.luaに先程、作成した全ての設定項目をコピーします。
そして、init.luaを書き換えます。

init.lua
-- basic_config.luaに記述してあるコードを読み込む
require ('user_name/basic_config')

プラグインマネージャーのインストール

Neovimにプラグインを追加する前に、プラグインマネージャーを導入します。

今回は、こちらを使用します。
https://github.com/tani/vim-jetpack

~/.config/nvim/init.lua
require ('user_name/setup_plugin')

これ以降で、作成するファイルは、~/.config/nvim/lua/user_name配下へ作成します。

新規でファイルを作成する。

~/.config/nvim/lua/user_name/setup_plugin.lua
-- Plugin Maneger を自動でダウンロードする
local jetpackfile = vim.fn.stdpath('data') .. '/site/pack/jetpack/opt/vim-jetpack/plugin/jetpack.vim'
local jetpackurl = "https://raw.githubusercontent.com/tani/vim-jetpack/master/plugin/jetpack.vim"
if vim.fn.filereadable(jetpackfile) == 0 then
  vim.fn.system(string.format('curl -fsSLo %s --create-dirs %s', jetpackfile, jetpackurl))
end

-- vim-jetpack で入れ込むプラグインをここに記載していく
vim.cmd('packadd vim-jetpack')

require('jetpack.paq') {
  -- ここの中に、プラグインを追記していきます。
  {'tani/vim-jetpack', opt = 1}, -- bootstrap
}

プラグインを追加する

これから出てくるプラグイン名は、require('jetpack.paq'){}の中に追記していきます。

カラーテーマ One Dark

https://github.com/navarasu/onedark.nvim

私は、カラーテーマにいつもOne Darkを使用しているため、Neovimでも使用します。

~/.config/nvim/lua/user_name/setup_plugin.lua
'navarasu/onedark.nvim',

~/.config/nvim/lua/user_name/内にpluginsディレクトリを作成してください。
新規でcolorscheme.luaを作成します。

~/.config/nvim/lua/user_name/plugins/colorscheme.lua
-- カラーテーマを設定します。
require('onedark').setup {
    style = 'darker'
}
require('onedark').load()
init.lua
+ require ('user_name/plugins/colorscheme')

nvim-treesitter

https://github.com/nvim-treesitter/nvim-treesitter

コードを色づけるために必要なプラグインです。コードに色をつけたい方は、必須プラグインです。

~/.config/nvim/lua/user_name/setup_plugin.lua
{'nvim-treesitter/nvim-treesitter', run = ':TSUpdate'}, -- プラグインを読み込んだ後にコマンドを実行します。

nvim-tree.lua

https://github.com/nvim-tree/nvim-tree.lua

ファイルエクスプローラーです。このプラグインを入れることで、ファイルを一覧で見ることができますし、ファイルの作成と削除、移動等ができます。

~/.config/nvim/lua/user_name/setup_plugin.lua
{'nvim-tree/nvim-tree.lua',
    requires = {
      'nvim-tree/nvim-web-devicons',
},

新規でnvim_tree.luaを作成します。

~/.config/nvim/lua/user_name/plugins/nvim_tree.lua
require('nvim-tree').setup({
  sort_by = 'case_sensitive',
  view = {
    adaptive_size = true,
    mappings = {
      list = {
        { key = 'u', action = 'dir_up' },
      },
    },
  },
  renderer = {
    group_empty = true,
  },
  filters = {
    dotfiles = true,
  },
})

-- start neovim with open nvim-tree
require("nvim-tree.api").tree.toggle(false, true)
init.lua
+ require ('user_name/plugins/nvim_tree')
-- 私は、leaderはSpaceキーを当てています。下の割当だと、Spaceキーとeを同時押しすることで、ファイルツリーが表示されます。leaderキーの設定方法は後述します。
api.nvim_set_keymap('n', '<leader>e', ':NvimTreeToggle<CR>', {silent=true})

telescope.nvim telescope-file-browser.nvim

https://github.com/nvim-telescope/telescope.nvim
https://github.com/nvim-telescope/telescope-file-browser.nvim

ファイル名の検索、文字列検索を行うために、導入します。
ただし、下記の設定で動作するためには、外部コマンドのripgrepが必要になります。

https://github.com/BurntSushi/ripgrep

~/.config/nvim/lua/user_name/setup_plugin.lua
'nvim-lua/plenary.nvim',
{'nvim-telescope/telescope.nvim', tag = '0.1.0' },
init.lua
require("telescope").load_extension "file_browser"
vim.api.nvim_set_keymap(
  "n",
  "<space>ff",
  ":Telescope file_browser<CR>",
  { noremap = true }
)

require("telescope").setup{
  pickers = {
		find_files = {
			find_command = { "rg", "--files", "--hidden", "-g", "!.git" },
		},
	},
}

local builtin = require('telescope.builtin')
vim.keymap.set('n', '<leader>p', builtin.find_files, {})
vim.keymap.set('n', '<leader>f', builtin.live_grep, {})
vim.keymap.set('n', '<leader>fb', builtin.buffers, {})
vim.keymap.set('n', '<leader>fh', builtin.help_tags, {})

ファイルの中身を見ながら、検索することが可能です。便利!

nvim-web-devicons

https://github.com/nvim-tree/nvim-web-devicons

ファイルの拡張子ごとに、ファイルアイコンを提供してくれるものです。telescopeやnvim-treeと連携して、使用します。

~/.config/nvim/lua/user_name/setup_plugin.lua
+ 'nvim-tree/nvim-web-devicons',
init.lua
+ require ('user_name/plugins/nvim_web_devicons')
~/.config/nvim/lua/user_name/plugins/nvim_web_devicons.lua
-- ファイルアイコンの設定
require'nvim-web-devicons'.setup {
  override = {
    zsh = {
      icon = "",
      color = "#428850",
      cterm_color = "65",
      name = "Zsh"
    }
  };
  color_icons = true;
  default = true;
}

lualine.lua

https://github.com/nvim-lualine/lualine.nvim

Neovimのステータスラインの見栄えや構成をカスタマイズすることができます。

~/.config/nvim/lua/user_name/setup_plugin.lua
{
  'nvim-lualine/lualine.nvim',
  requires = 'kyazdani42/nvim-web-devicons'
},
~/.config/nvim/lua/user_name/plugins/lualine.lua
-- そんなにカスタマイズしていないです。デフォルトのままでも十分使用できます。
require('lualine').setup({
  options = { theme = 'onedark' },
})

地味ですが、ここをカスタマイズしておくと、スタイリッシュさが増します。

coc.nvim

https://github.com/neoclide/coc.nvim

コードの保管を出すことができます。補完を出すプラグインは、NeovimのLSPやcocがあります。
しかし、私は、導入が簡単なcocを使用しています。

~/.config/nvim/lua/user_name/setup_plugin.lua
{'neoclide/coc.nvim', branch='release'},

nvim-cursorline

https://github.com/yamatsum/nvim-cursorline

カーソル下の単語と同じつづりの単語に、アンダーラインを引いてくれるプラグインです。

~/.config/nvim/lua/user_name/setup_plugin.lua
'yamatsum/nvim-cursorline',
~/.config/nvim/lua/user_name/plugins/nvim_cursorline.lua
-- cursorline setting
require('nvim-cursorline').setup {
  cursorline = {
    enable = true,
    timeout = 1000,
    number = false,
  },
  cursorword = {
    enable = true,
    min_length = 3,
    hl = { underline = true },
  }
}

any-jump

https://github.com/pechorin/any-jump.vim

Vimで開いているディレクトリ配下のファイルを対象に、同じメソッドやクラスの呼び出し箇所へジャンプすることができます。

~/.config/nvim/lua/user_name/setup_plugin.lua
'pechorin/any-jump.vim',

leaderキーとjを押すことで発動します。メソッドの定義元に飛びたいときやCSSクラスの定義元に飛びたい時にとても便利です。

Comment.nvim

https://github.com/numToStr/Comment.nvim

ノーマルモード時にgcgccと押すだけで、コードをコメント化できる優れものプラグインです。

setup_plugin.lua
{'numToStr/Comment.nvim', config = function() require('Comment').setup() end},

nvim-colorizer.lua

https://github.com/norcalli/nvim-colorizer.lua

カラーコードの背景に色をあててくれるプラグインです。CSSファイルを作成する際に、カラーコードがどんな色なのかを、すぐに確認できるため、とても便利です。

~/.config/nvim/lua/user_name/setup_plugin.lua
'norcalli/nvim-colorizer.lua',
~/.config/nvim/lua/user_name/plugins/colorizer.lua
-- CSSにある色コードに色を当ててくれる
require'colorizer'.setup(config, {
  RRGGBBAA = true;
  rgb_fn = true;
  hsl_fn = true;
})

git.nvim

https://github.com/dinhhuy258/git.nvim

vim-fugitive のLua版プラグインです。Gitコマンドを手軽に実行できたりします。使用頻度は低いです。

~/.config/nvim/lua/user_name/setup_plugin.lua
'dinhhuy258/git.nvim',

gitsigns.nvim

https://github.com/lewis6991/gitsigns.nvim

Git管理しているファイルでの、変更差分を行番号の隣あたりに、色とシンボルで表示してくれるプラグインです。blameも見れたりします。

~/.config/nvim/lua/user_name/setup_plugin.lua
'lewis6991/gitsigns.nvim',
~/.config/nvim/lua/user_name/plugins/gitsigns.lua
require('gitsigns').setup {
  signs = {
    add          = { hl = 'GitSignsAdd'   , text = '│', numhl='GitSignsAddNr'   , linehl='GitSignsAddLn'    },
    change       = { hl = 'GitSignsChange', text = '│', numhl='GitSignsChangeNr', linehl='GitSignsChangeLn' },
    delete       = { hl = 'GitSignsDelete', text = '_', numhl='GitSignsDeleteNr', linehl='GitSignsDeleteLn' },
    topdelete    = { hl = 'GitSignsDelete', text = '‾', numhl='GitSignsDeleteNr', linehl='GitSignsDeleteLn' },
    changedelete = { hl = 'GitSignsChange', text = '~', numhl='GitSignsChangeNr', linehl='GitSignsChangeLn' },
    untracked    = { hl = 'GitSignsAdd'   , text = '┆', numhl='GitSignsAddNr'   , linehl='GitSignsAddLn'    },
  },
  signcolumn = true,
  numhl      = false,
  linehl     = false,
  word_diff  = false,
  watch_gitdir = {
    interval = 1000,
    follow_files = true
  },
  attach_to_untracked = true,
  current_line_blame = false,
  current_line_blame_opts = {
    virt_text = true,
    virt_text_pos = 'eol',
    delay = 1000,
    ignore_whitespace = false,
  },
  current_line_blame_formatter = '<author>, <author_time:%Y-%m-%d> - <summary>',
  sign_priority = 6,
  update_debounce = 100,
  status_formatter = nil,
  max_file_length = 40000,
  preview_config = {
    -- Options passed to nvim_open_win
    border = 'single',
    style = 'minimal',
    relative = 'cursor',
    row = 0,
    col = 1
  },
  yadm = {
    enable = false
  },
}

nvim-ts-autotag

https://github.com/windwp/nvim-ts-autotag

HTMLタグを打つと、閉じタグを自動で入力してくれるプラグインです。Typescriptを書くことが多い方は、便利かもしれないです。

~/.config/nvim/lua/user_name/setup_plugin.lua
'windwp/nvim-ts-autotag',

auto-save.lua

https://github.com/pocco81/auto-save.nvim

ファイルを自動保存してくれるプラグインです。保存のタイミングは、Neovimのイベントに沿って保存されます。

~/.config/nvim/lua/user_name/setup_plugin.lua
'pocco81/auto-save.nvim',
~/.config/nvim/lua/user_name/plugins/auto_save.lua
require'auto-save'.setup({
  trigger_events = {"InsertLeave", "BufLeave", "FocusLost"},
  --, "ModeChanged" これを有効にすると、ノーマルモード時のSが効かなくなる
  --{"InsertLeave", "TextChanged"},
})

bufferline.lua

https://github.com/akinsho/bufferline.nvim

Neovim のバッファラインの外見をカスタマイズできます。見た目をかっこよくしたい場合、おすすめです。

~/.config/nvim/lua/user_name/setup_plugin.lua
'akinsho/bufferline.nvim',
~/.config/nvim/lua/user_name/plugins/bufferline.lua
require'bufferline'.setup({
  options = {
    -- mode = "tabs",
    separator_style = 'thick',
    -- separator_style = 'slant',
    -- always_show_bufferline = false,
    show_buffer_close_icons = true,
    show_close_icon = true,
    color_icons = true,
  },
  highlights = {
    separator = {
      fg = '#073642',
      bg = '#000000',
    },
    background = {
      fg = '#657b83',
      bg = '#444444'
    },
    buffer_selected = {
      fg = '#ffffff',
      bg = '#000000',
      bold = true,
    },
    fill = {
      bg = '#073642'
    }
  },
})

vim.keymap.set('n', '<Tab>', '<Cmd>BufferLineCycleNext<CR>', {})
vim.keymap.set('n', '<S-Tab>', '<Cmd>BufferLineCyclePrev<CR>', {})

nvim-autopairs

https://github.com/windwp/nvim-autopairs

開き括弧を入力した時に、閉じ括弧を補完してくれるプラグインです。

~/.config/nvim/lua/user_name/setup_plugin.lua
'windwp/nvim-autopairs',

nvim-treesitter-endwise

https://github.com/RRethy/nvim-treesitter-endwise

Rubyでコーディングする際に、メソッドやモジュールのendを自動で入力してくれるプラグインです。

~/.config/nvim/lua/user_name/setup_plugin.lua
'RRethy/nvim-treesitter-endwise',

mini.indentscope

https://github.com/echasnovski/mini.indentscope

インデントの縦を点線で描画してくれるプラグインです。HTMLをコーディングする時やネストが深い時に重宝します。

~/.config/nvim/lua/user_name/setup_plugin.lua
'echasnovski/mini.indentscope',

toggleterm.nvim

https://github.com/echasnovski/mini.indentscope

Neovim上で簡単にターミナルを開くことができるプラグインです。また、私はGit操作をLazygitを使用することが多いため、このプラグインの機能を使用して、Neovim上でLazygitを使用できるようにしています。

~/.config/nvim/lua/user_name/setup_plugin.lua
'akinsho/toggleterm.nvim',
~/.config/nvim/lua/user_name/plugins/toggleterm.lua
require("toggleterm").setup{
  size = 30,
  direction = 'horizontal',

}

local Terminal = require("toggleterm.terminal").Terminal
local lazygit = Terminal:new({
	cmd = "lazygit",
	direction = "float",
	hidden = true
})

function lazygit_toggle()
	lazygit:toggle()
end

キーコンフィグの設定

Neovimを便利に、素早く操作するためにはキーコンフィグは欠かせません。

init.lua
vim.g.mapleader = ' ' -- 半角スペースを設定しています。
vim.keymap.set('i', 'jj', '<ESC>', {silent=true}) -- インサートモードを抜ける
vim.keymap.set('n', ';', ':', {silent=true}) -- シフトを押すことなく、;を入力する。割と便利

vim.keymap.set('n', '<leader>sv', '<C-w>v') -- ウィンドウを垂直方向に分割する
vim.keymap.set('n', '<leader>sh', '<C-w>s') -- ウィンドウを水平に分割する
vim.keymap.set('n', '<leader>se', '<C-w>=') -- ウィンドウの幅を等分にする
vim.keymap.set('n', '<leader>sx', ':close<CR>') -- 現在、カーソルがいるウィンドウを閉じる
vim.keymap.set('n', '<leader>sw', '<C-w>><C-w>><C-w>><C-w>><C-w>><C-w>><C-w>><C-w>>') -- ウィンドウの幅を少し広げる
vim.keymap.set('n', '<leader>sww', '<C-w>><C-w>><C-w>><C-w>><C-w>><C-w>><C-w>><C-w>><C-w>><C-w>><C-w>><C-w>><C-w>><C-w>><C-w>><C-w>>') -- ウィンドウの幅を大きく広げる
vim.keymap.set('n', '<leader>st', '<C-w><<C-w><<C-w><<C-w><<C-w><<C-w><<C-w><<C-w><') -- ウィンドウの幅を少し狭める
vim.keymap.set('n', '<leader>stt', '<C-w><<C-w><<C-w><<C-w><<C-w><<C-w><<C-w><<C-w><<C-w><<C-w><<C-w><<C-w><<C-w><<C-w><<C-w><<C-w><') -- ウィンドウの幅を大きく狭める

-- タブを作成、削除
vim.keymap.set('n', '<leader>to', ':tabnew<CR>')
vim.keymap.set('n', '<leader>tx', ':tabclose<CR>')
vim.keymap.set('n', '<leader>tn', ':tabn<CR>')
vim.keymap.set('n', '<leader>tp', ':tabp<CR>')
-- ウィンドウを移動する
vim.keymap.set('n', '<C-l>', '<C-w>l')
vim.keymap.set('n', '<C-h>', '<C-w>h')
vim.keymap.set('n', '<C-j>', '<C-w>j')
vim.keymap.set('n', '<C-k>', '<C-w>k')
-- 単語を' " どちらかで囲う
vim.keymap.set('n', '<leader>aw', 'ciw""<Esc>P')
vim.keymap.set('n', '<leader>aW', "ciw''<Esc>P")

以上で、設定は完了です。
ここまで設定して、Nvimを再起動させると、こんな感じになります。

最後に

Neovimは、VSCodeと違い自分でカスタマイズすることで機能を追加したり、自前のスクリプトを作成して、簡単なタスクを実行したりできます。定期的にNeovimの設定を見直したり、機能追加することで、さらに使いやすくすることもできます。この記事を通して、Neovimを使用してくださる方が増えたらうれしいです!

参考資料

今回、使用したプラグインマネージャーの作者が、公開した記事はこちら
https://zenn.dev/dog/articles/jetpack_intro

プラグインを探したい場合、こちらのレポジトリが参考になります。
https://github.com/yutkat/my-neovim-pluginlist

Discussion