Linux & IT ノート

Neovim を素のまま育てる設定術

管理人 約10分で読めます

巨大なプラグインセットを入れる前に、素の Neovim が持つポテンシャルを引き出してみましょう。 LSP のネイティブサポートと treesitter を使えば、モダンな編集体験は init.lua 数十行でも実現できます。

なぜ「素のまま育てる」のか

LazyVim や AstroNvim といったディストリビューションは便利ですが、何十ものプラグインが最初から入っていて、自分が何を使っているかわからなくなりがちです。 一方、自分で少しずつ育てた設定は「なぜこの設定があるか」を全て説明できるので、問題が起きたときに素早く対処できます。

基本設定から始める

まず ~/.config/nvim/init.lua を作成して、エディタの基本動作を設定します。

-- 基本設定
vim.opt.number = true          -- 行番号を表示
vim.opt.relativenumber = true  -- 相対行番号を表示
vim.opt.expandtab = true       -- タブをスペースに展開
vim.opt.shiftwidth = 2         -- インデント幅
vim.opt.tabstop = 2            -- タブ幅
vim.opt.smartindent = true     -- スマートインデント
vim.opt.wrap = false           -- 折り返しを無効化
vim.opt.cursorline = true      -- カーソル行をハイライト
vim.opt.termguicolors = true   -- 24bit カラーを有効化
vim.opt.scrolloff = 8          -- スクロール時の余白行数
vim.opt.signcolumn = 'yes'     -- サインカラムを常に表示
vim.opt.updatetime = 250       -- スワップファイルの更新間隔 (ms)

-- リーダーキーをスペースに設定
vim.g.mapleader = ' '
vim.g.maplocalleader = ' '

パッケージマネージャー lazy.nvim を導入する

プラグイン管理には lazy.nvim が現在の標準的な選択肢です。

-- lazy.nvim のブートストラップ
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)

require('lazy').setup({
  -- ここにプラグインを追加していく
})

treesitter でシンタックスハイライトを強化する

Neovim 標準の正規表現ベースのハイライトより、treesitter は AST を使うため格段に正確です。

require('lazy').setup({
  {
    'nvim-treesitter/nvim-treesitter',
    build = ':TSUpdate',
    config = function()
      require('nvim-treesitter.configs').setup({
        ensure_installed = {
          'lua', 'python', 'javascript', 'typescript',
          'rust', 'go', 'bash', 'json', 'yaml', 'toml',
        },
        highlight = { enable = true },
        indent = { enable = true },
      })
    end,
  },
})

treesitter のメリット

  • ネストした文字列内のハイライトが正確
  • インデント補助が構文を理解して動く
  • テキストオブジェクト拡張(関数単位・クラス単位での操作)が可能

LSP でコード補完・定義ジャンプを設定する

Neovim 0.5 以降、LSP クライアントが標準搭載されました。nvim-lspconfig でサーバーと接続します。

{
  'neovim/nvim-lspconfig',
  dependencies = {
    'williamboman/mason.nvim',
    'williamboman/mason-lspconfig.nvim',
  },
  config = function()
    require('mason').setup()
    require('mason-lspconfig').setup({
      ensure_installed = { 'lua_ls', 'pyright', 'ts_ls' },
    })

    local lspconfig = require('lspconfig')
    local on_attach = function(_, bufnr)
      local opts = { buffer = bufnr }
      vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts)
      vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts)
      vim.keymap.set('n', '<leader>rn', vim.lsp.buf.rename, opts)
      vim.keymap.set('n', '<leader>ca', vim.lsp.buf.code_action, opts)
    end

    lspconfig.lua_ls.setup({ on_attach = on_attach })
    lspconfig.pyright.setup({ on_attach = on_attach })
    lspconfig.ts_ls.setup({ on_attach = on_attach })
  end,
},

補完エンジン nvim-cmp を追加する

LSP だけでは補完候補が表示されません。nvim-cmp を追加して補完UIを整えます。

{
  'hrsh7th/nvim-cmp',
  dependencies = {
    'hrsh7th/cmp-nvim-lsp',
    'hrsh7th/cmp-buffer',
    'L3MON4D3/LuaSnip',
    'saadparwaiz1/cmp_luasnip',
  },
  config = function()
    local cmp = require('cmp')
    cmp.setup({
      snippet = {
        expand = function(args)
          require('luasnip').lsp_expand(args.body)
        end,
      },
      mapping = cmp.mapping.preset.insert({
        ['<C-d>'] = cmp.mapping.scroll_docs(-4),
        ['<C-f>'] = cmp.mapping.scroll_docs(4),
        ['<C-Space>'] = cmp.mapping.complete(),
        ['<CR>'] = cmp.mapping.confirm({ select = true }),
        ['<Tab>'] = cmp.mapping.select_next_item(),
        ['<S-Tab>'] = cmp.mapping.select_prev_item(),
      }),
      sources = {
        { name = 'nvim_lsp' },
        { name = 'luasnip' },
        { name = 'buffer' },
      },
    })
  end,
},

ファジーファインダー telescope.nvim

ファイル検索やコマンド検索に欠かせないプラグインです。

{
  'nvim-telescope/telescope.nvim',
  dependencies = { 'nvim-lua/plenary.nvim' },
  config = function()
    local builtin = require('telescope.builtin')
    vim.keymap.set('n', '<leader>ff', builtin.find_files)
    vim.keymap.set('n', '<leader>fg', builtin.live_grep)
    vim.keymap.set('n', '<leader>fb', builtin.buffers)
    vim.keymap.set('n', '<leader>fh', builtin.help_tags)
  end,
},

まとめ:段階的に育てる

最小構成でも十分快適に使えます。プラグインは「本当に必要になったら追加する」という姿勢で増やしていくのがコツです。 設定ファイルは ~/.config/nvim/ 以下をディレクトリ構成で管理すると、後からメンテナンスしやすくなります。

~/.config/nvim/
├── init.lua          # エントリーポイント
└── lua/
    └── config/
        ├── options.lua   # vim.opt の設定
        ├── keymaps.lua   # キーバインド
        └── plugins/      # プラグイン設定

最初から全部入りを求めず、自分の作業フローに合わせて少しずつ育てていくのが、Neovim との付き合い方だと思っています。