🦑

君もイカしたNeovimで開発してみなイカ?

2024/12/13に公開

Introduction

昨年書いた以下の記事にてneovimのpluginがだいぶ省略されて終わっていたので、棚卸しを兼ねて現在使っているpluginとその設定内容を紹介していきたいと思います。

neovim

keybinds

前回の記事から操作性を良くするために以下を追加しました。

-- 画面分割
vim.keymap.set("n", "<S-j>", ":split<CR>")
vim.keymap.set("n", "<S-l>", ":vsplit<CR>")
-- カーソル移動
vim.keymap.set({ "n", "v" }, "<C-n>", "20j")
vim.keymap.set({ "n", "v" }, "<C-p>", "20k")
-- 保存してnormalモードに戻る
vim.keymap.set("i", "jj", "<ESC>:<C-u>w<CR>")

plugins

lua/extensions/init.luaを真っさらにした状態から始めます。
nvim

lazy.nvim

https://github.com/folke/lazy.nvim
lazy.nvimは、neovimの各種pluginを管理してくれるパッケージマネージャです。
ドキュメントを参考にlua/extensions/init.luaに以下を記載します。

local plugins = {
}
local opts = {
  defaults = {
    lazy = true,
  },
  checker = {
    enabled = true,
  },
  preformance = {
    cache = {
      enabled = true,
    },
    reset_packpath = true,
    rtp = {
      reset = true,
      paths = {},
      disabled_plugins = {
        "gzip",
        "matchit",
        -- "matchparen",
        -- "netrwPlugin",
        "tarPlugin",
        "tohtml",
        "tutor",
        "zipPlugin",
      },
    },
  },
}
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
  local lazyrepo = "https://github.com/folke/lazy.nvim.git"
  local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
  if vim.v.shell_error ~= 0 then
    vim.api.nvim_echo({
      { "Failed to clone lazy.nvim:\n", "ErrorMsg" },
      { out,                            "WarningMsg" },
      { "\nPress any key to exit..." },
    }, true, {})
    vim.fn.getchar()
    os.exit(1)
  end
end
vim.opt.rtp:prepend(lazypath)
require("lazy").setup({
  spec = plugins,
  opts,
})

公式ドキュメントの設定をほぼそのまま持ってきています。
:Lazyを入力してこのような画面が出ればOKです。
lazy.nvim

oil.nvim

https://github.com/stevearc/oil.nvim
oil.nvimは、ファイルエクスプローラーです。
ドキュメントを参考にlua/extensions/init.luaのpluginsに以下を追加します。

  {
    "stevearc/oil.nvim",
    keys = {
      "<leader>ex",
    },
    config = function()
      require("extensions.oil")
    end,
    dependencies = {
      "nvim-tree/nvim-web-devicons",
    },
  },

lua/extensions/oil.luaに設定を記載します。

require("oil").setup({
  default_file_explorer = true,
  columns = {
    "icon",
  },
  buf_options = {
    buflisted = false,
    bufhidden = "hide",
  },
  win_options = {
    wrap = false,
    signcolumn = "no",
    cursorcolumn = false,
    foldcolumn = "0",
    spell = false,
    list = false,
    conceallevel = 3,
    concealcursor = "nvic",
  },
  delete_to_trash = false,
  skip_confirm_for_simple_edits = false,
  prompt_save_on_select_new_entry = true,
  cleanup_delay_ms = 2000,
  lsp_file_methods = {
    enabled = true,
    timeout_ms = 1000,
    autosave_changes = false,
  },
  constrain_cursor = "editable",
  watch_for_changes = false,
  keymaps = {
    ["g?"] = "actions.show_help",
    ["<CR>"] = "actions.select",
    ["<C-s>"] = { "actions.select", opts = { vertical = true }, desc = "Open the entry in a vertical split" },
    ["<C-h>"] = { "actions.select", opts = { horizontal = true }, desc = "Open the entry in a horizontal split" },
    ["<C-t>"] = { "actions.select", opts = { tab = true }, desc = "Open the entry in new tab" },
    ["<C-p>"] = "actions.preview",
    ["<C-c>"] = "actions.close",
    ["<C-l>"] = "actions.refresh",
    ["-"] = "actions.parent",
    ["_"] = "actions.open_cwd",
    ["`"] = "actions.cd",
    ["~"] = { "actions.cd", opts = { scope = "tab" }, desc = ":tcd to the current oil directory", mode = "n" },
    ["gs"] = "actions.change_sort",
    ["gx"] = "actions.open_external",
    ["g."] = "actions.toggle_hidden",
    ["g\\"] = "actions.toggle_trash",
  },
  use_default_keymaps = true,
  view_options = {
    show_hidden = true,
    is_always_hidden = function(name, bufnr)
      return false
    end,
    natural_order = "fast",
    case_insensitive = false,
    sort = {
      { "type", "asc" },
      { "name", "asc" },
    },
    highlight_filename = function(entry, is_hidden, is_link_target, is_link_orphan)
      return nil
    end,
  },
  extra_scp_args = {},
  git = {
    add = function(path)
      return true
    end,
    mv = function(src_path, dest_path)
      return true
    end,
    rm = function(path)
      return true
    end,
  },
  float = {
    padding = 2,
    max_width = 0,
    max_height = 0,
    border = "rounded",
    win_options = {
      winblend = 0,
    },
    get_win_title = nil,
    preview_split = "auto",
    override = function(conf)
      return conf
    end,
  },
  preview = {
    update_on_cursor_moved = true,
    preview_method = "fast_scratch",
    disable_preview = function(filename)
      return false
    end,
    win_options = {},
  },
  confirmation = {
    max_width = 0.9,
    min_width = { 40, 0.4 },
    width = nil,
    max_height = 0.9,
    min_height = { 5, 0.1 },
    height = nil,
    border = "rounded",
    win_options = {
      winblend = 0,
    },
  },
  progress = {
    max_width = 0.9,
    min_width = { 40, 0.4 },
    width = nil,
    max_height = { 10, 0.9 },
    min_height = { 5, 0.1 },
    height = nil,
    border = "rounded",
    minimized_border = "none",
    win_options = {
      winblend = 0,
    },
  },
  ssh = {
    border = "rounded",
  },
  kyemaps_help = {
    border = "rounded",
  },
})

vim.keymap.set("n", "<leader>ex", "<CMD>Oil<CR>", { desc = "Open parent directory" })

ほぼドキュメントに記載の設定内容を適用しています。
異なる点は、非表示ファイルを無効化したり、oilの起動に<leader>exを割り当てている部分になります。
nvimを再起動するとoilがインストールされます。
インストールが完了したらqでlazyを閉じてもらい、私の環境ではleaderに,を適用しているので、,exを入力すると以下のように表示されます。
oil.nvim

nvim-treesitter

https://github.com/nvim-treesitter/nvim-treesitter
nvim-treesitterは言語に応じたハイライトをしてくれるpluginです。
ドキュメントを参考にlua/extensions/init.luaのpluginsに以下を追加します。

  {
    "nvim-treesitter/nvim-treesitter",
    build = ":TSUpdate",
    event = { "BufNewFile", "BufReadPre" },
    config = function()
      require("extensions.nvim-treesitter")
    end,
  },

lua/extensions/nvim-treesitter.luaに設定を記載します。

require("nvim-treesitter.configs").setup({
  ensure_installed = {
    "bash",
    "comment",
    "lua",
  },
  sync_install = false,
  auto_install = true,
  highlight = {
    enable = true,
    disable = function(lang, buf)
      local max_filesize = 100 * 1024 -- 100 KB
      local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf))
      if ok and stats and stats.size > max_filesize then
        return true
      end
    end,
    additional_vim_regex_highlighting = false,
  },
  incremental_selection = {
    enable = true,
    keymaps = {
      init_selection = "gnn",
      node_incremental = "grn",
      scope_incremental = "grc",
      node_decremental = "grm",
    },
  },
  indent = {
    enable = true,
  },
})

設定内容はドキュメントのものをほぼそのまま持ってきています。
incremental_selectionは、他とkeymapが被っているので追って修正します。
nvimを再起動するとnvim-treesitterがインストールされます。
以下のような感じでハイライトされるようになると思います。
tree-sitter

nvim-treesitter-context

https://github.com/nvim-treesitter/nvim-treesitter-context
nvim-treesitter-contextは、意味のあるコードの塊の先頭を画面上部で固定して見せてくれるpluginになります。
公式のドキュメントにScreenshotありますので、それを見るとイメージがつきやすいです。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "nvim-treesitter/nvim-treesitter-context",
    event = { "BufNewFile", "BufReadPre" },
    config = function()
      require("extensions.nvim-treesitter-context")
    end,
  },

extensions/nvim-treesitter-context.luaに設定を記載します。

require("treesitter-context").setup({
  enable = true,
  multiwindow = false,
  max_lines = 0,
  min_window_height = 0,
  line_numbers = true,
  multiline_threshold = 20,
  trim_scope = "outer",
  mode = "cursor",
  separator = nil,
  zindex = 20,
  on_attach = nil,
})

公式ドキュメントの設定をそのまま設定しています。
nvimを再起動するとnvim-treesitter-contextがインストールされます。
中間部分を省略して表示してくれるようになります。
nvim-treesitter-context

onenord.nvim

https://github.com/rmehri01/onenord.nvim
onenord.nvimは、カラーテーマです。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "rmehri01/onenord.nvim",
    event = { "VimEnter" },
    priority = 1000,
    config = function()
      require("extensions.onenord")
    end,
  },

lua/extensions/onenord.luaに設定を記載します。

local colors = require("onenord.colors").load()
require("onenord").setup({
  theme = "dark", 
  borders = true,
  fade_nc = false,
  styles = {
    comments = "NONE",
    strings = "NONE",
    keywords = "bold",
    functions = "bold",
    variables = "NONE",
    diagnostics = "underline",
  },
  disable = {
    background = true,
    float_background = false,
    cursorline = false,
    eob_lines = true,
  },
  inverse = {
    match_paren = false,
  },
  custom_highlights = {}, 
  custom_colors = {},
})

ドキュメントの設定をほぼそのまま持ってきています。
nvimを再起動するとonenordがインストールされます。
以下のようなカラーになります。
onenord.nvim

lualine.nvim

https://github.com/nvim-lualine/lualine.nvim
lualineは、ステータスラインを表示できるpluginになります、
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "nvim-lualine/lualine.nvim",
    event = { "VimEnter" },
    config = function()
      require("extensions.lualine")
    end,
    dependencies = {
      "nvim-tree/nvim-web-devicons",
      "rmehri01/onenord.nvim",
    },
  },

lua/extensions/lualine.luaに設定を記載します。

local colors = require("onenord.colors").load()
local switch_color = {
  active = { fg = colors.active, bg = colors.mypink },
  inactive = { fg = colors.active, bg = colors.light_gray },
}
require("lualine").setup({
  options = {
    icons_enabled = true,
    theme = "auto",
    section_separators = { left = "", right = "" },
    component_separators = { left = "", right = "" },
    disabled_filetypes = {
      statusline = {},
      winbar = {},
    },
    ignore_focus = {},
    always_divide_middle = true,
    always_show_tabline = true,
    globalstatus = true,
    refresh = {
      statusline = 1000,
      tabline = 1000,
      winbar = 1000,
    },
  },
  sections = {
    lualine_a = {
      "mode",
    },
    lualine_b = {
      {
        "filename",
        file_status = true,
        newfile_status = true,
        path = 1,
        shorting_target = 40,
        symbols = { modified = "_󰷥", readonly = " ", newfile = "󰄛", unnamed = "[No Name]" },
      },
    },
    lualine_c = {
      {
        "diagnostics",
        sources = {
          "nvim_diagnostic",
          "nvim_lsp",
        },
        sections = {
          "error",
          "warn",
          "info",
          "hint",
        },
        symbols = {
          error = " ",
          warn = " ",
          info = " ",
          hint = " ",
        },
        update_in_insert = false,
        always_visible = false,
      },
      { "navic" },
    },
    lualine_x = {
      {
        require("lazy.status").updates,
        cond = require("lazy.status").has_updates,
        color = {
          fg = "#ff9e64",
        },
      },
    },
    lualine_y = {
      {
        "filetype",
        colored = true,
        icon_only = false,
        color = {
          fg = colors.fg,
        },
      },
    },
    lualine_z = {
      {
        "fileformat",
        icons_enabled = true,
        symbols = {
          unix = "", -- e712
          dos = "", -- e70f
          mac = "", -- e711
        },
        separator = {
          left = "",
          right = "",
        },
      },
    },
  },
  inactive_sections = {
    lualine_a = {},
    lualine_b = {},
    lualine_c = { "filename" },
    lualine_x = { "location" },
    lualine_y = {},
    lualine_z = {},
  },
  tabline = {
    lualine_a = {
      {
        "buffers",
        show_filename_only = true,
        hide_filename_extension = false,
        show_modified_status = true,
        mode = 0,
        max_length = vim.o.columns * 2 / 3,
        filetype_names = {
          TelescopePrompt = "Telescope",
          dashboard = "Dashboard",
          packer = "Packer",
          fzf = "FZF",
          alpha = "Alpha",
        },
        use_mode_colors = false,
        buffers_color = switch_color,
        symbols = {
          modified = "_󰷥",
          alternate_file = " ",
          directory = " ",
        },
      },
    },
    lualine_b = {},
    lualine_c = {},
    lualine_x = {
      {
        "diff",
        colored = true,
        symbols = {
          added = " ",
          modeiffied = " ",
          removed = " ",
        },
        source = nil,
      },
    },
    lualine_y = {
      {
        "b:gitsigns_head",
        icon = {
          "",
          color = {
            fg = colors.orange,
          },
        },
        color = {
          fg = colors.fg,
        },
      },
    },
    lualine_z = {
      { "tabs", tabs_color = switch_color },
    },
  },
  winbar = {},
  inactive_winbar = {},
  extensions = {},
})

lua/options.luaに以下を追加します。

vim.api.nvim_set_option("showmode", false)

zenn上では文字化けしちゃってますが、wezterm & nvim上で見れば化けていないと思います。
カラーについては、onenordから取得しています。
lualineでモードを表示しているので、showmodeを無効化してます。
lua/extensions/onenord.luaの設定を編集します。

  custom_colors = {
    mypink = "#FFB2CC",
  },

nvimを再起動するとlualineがインストールされます。
画面上部と下部にステータスラインが出るようになります。
lualine.nvim
ファイルをtabキーで簡単に切り替えたいので以下のkeybindを設定しています。

-- buffer
vim.keymap.set("n", "<Tab>", ":bnext<CR>")
vim.keymap.set("n", "<S-Tab>", ":bprev<CR>")

noice.nvim

https://github.com/folke/noice.nvim
noice.nvimは、メッセージやコマンドラインなどのUIをいい感じにしてくれるpluginです。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "folke/noice.nvim",
    event = "VeryLazy",
    config = function()
      require("extensions.noice")
    end,
    dependencies = {
      "MunifTanjim/nui.nvim",
      "rcarriga/nvim-notify",
    }
  },

lua/extensions/noice.luaに設定を記載します。

require("noice").setup({
  lsp = {
    override = {
      ["vim.lsp.util.convert_input_to_markdown_lines"] = true,
      ["vim.lsp.util.stylize_markdown"] = true,
      ["cmp.entry.get_documentation"] = true,
    },
  },
  presets = {
    bottom_search = true,
    command_palette = true,
    long_message_to_split = true,
    inc_rename = false,
    lsp_doc_border = false,
  },
})

ドキュメントの設定内容をそのまま持ってきています。
nvimを再起動するとnoiceがインストールされます。
試しにコマンドを打ってみると以下のようにわかりやすいUIになっているかと思います。
noice.nvim

nvim-hlslens

https://github.com/kevinhwang91/nvim-hlslens
nvim-hlslensは、ファイル内検索をわかりやすくしてくれるpluginになります。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "kevinhwang91/nvim-hlslens",
    event = { "FilterWritePre" },
    keys = {
      "<leader>L",
    },
    config = function()
      require("extensions.nvim-hlslens")
    end,
  },

lua/extensions/nvim-hlslens.luaに設定を記載します。

require('hlslens').setup({
  calm_down = true,
  nearest_only = true,
})
vim.keymap.set({'n', 'x'}, '<leader>L', function()
    vim.schedule(function()
        if require('hlslens').exportLastSearchToQuickfix() then
            vim.cmd('cw')
        end
    end)
    return ':noh<CR>'
end, {expr = true})

ドキュメントの設定内容をそのまま持ってきています。
nvimを再起動するとnvim-hlslensがインストールされます。
nvimを再起動し適当なファイルにて/を入力して検索するといい感じに結果が見れます。
nvim-hlslens

gitsigns.nvim

https://github.com/lewis6991/gitsigns.nvim
gitsigns.nvimは、git周りの装飾をしてくれるpluginになります。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "lewis6991/gitsigns.nvim",
    event = { "BufReadPre" },
    config = function()
      require("extensions.gitsigns")
    end,
  },

lua/extensions/gitsigns.luaに設定を記載します。

require("gitsigns").setup({
  signs = {
    add = { text = " ▎" },
    change = { text = " ▎" },
    delete = { text = " " },
    topdelete = { text = " " },
    changedelete = { text = "▎ " },
    untracked = { text = " ▎" },
  },
  signs_staged = {
    add = { text = " ▎" },
    change = { text = " ▎" },
    delete = { text = " " },
    topdelete = { text = " " },
    changedelete = { text = "▎ " },
    untracked = { text = " ▎" },
  },
  signs_staged_enable = false,
  signcolumn = true,
  numhl = false,
  linehl = false,
  word_diff = false,
  watch_gitdir = {
    follow_files = true,
  },
  auto_attach = true,
  attach_to_untracked = false,
  current_line_blame = false,
  current_line_blame_opts = {
    virt_text = true,
    virt_text_pos = "eol",
    delay = 1000,
    ignore_whitespace = false,
    virt_text_priority = 100,
    use_forus = true,
  },
  current_line_blame_formatter = "<summary> (<author_time:%Y/%m>) - <author>",
  sign_priority = 6,
  update_debounce = 100,
  status_formatter = nil,
  max_file_length = 40000,
  preview_config = {
    border = "single",
    style = "minimal",
    relative = "cursor",
    row = 0,
    col = 1,
  },
  on_attach = function(bufnr)
    local gitsigns = require('gitsigns')
    local function map(mode, l, r, opts)
      opts = opts or {}
      opts.buffer = bufnr
      vim.keymap.set(mode, l, r, opts)
    end
    map('n', ']c', function()
      if vim.wo.diff then
        vim.cmd.normal({']c', bang = true})
      else
        gitsigns.nav_hunk('next')
      end
    end)
    map('n', '[c', function()
      if vim.wo.diff then
        vim.cmd.normal({'[c', bang = true})
      else
        gitsigns.nav_hunk('prev')
      end
    end)
    map('n', '<leader>hs', gitsigns.stage_hunk)
    map('n', '<leader>hr', gitsigns.reset_hunk)
    map('v', '<leader>hs', function() gitsigns.stage_hunk {vim.fn.line('.'), vim.fn.line('v')} end)
    map('v', '<leader>hr', function() gitsigns.reset_hunk {vim.fn.line('.'), vim.fn.line('v')} end)
    map('n', '<leader>hS', gitsigns.stage_buffer)
    map('n', '<leader>hu', gitsigns.undo_stage_hunk)
    map('n', '<leader>hR', gitsigns.reset_buffer)
    map('n', '<leader>hp', gitsigns.preview_hunk)
    map('n', '<leader>hb', function() gitsigns.blame_line{full=true} end)
    map('n', '<leader>tb', gitsigns.toggle_current_line_blame)
    map('n', '<leader>hd', gitsigns.diffthis)
    map('n', '<leader>hD', function() gitsigns.diffthis('~') end)
    map('n', '<leader>td', gitsigns.toggle_deleted)
    map({'o', 'x'}, 'ih', ':<C-U>Gitsigns select_hunk<CR>')
  end,
})

lua/extensions/lualine.luaの設定を編集します。

local function diff_source()
  local gitsigns = vim.b.gitsigns_status_dict
  if gitsigns then
    return {
      added = gitsigns.added,
      modified = gitsigns.changed,
      removed = gitsigns.removed,
    }
  end
end

-- sourceに上記関数を設定
    lualine_x = {
      {
        "diff",
        colored = true,
        symbols = {
          added = " ",
          modeiffied = " ",
          removed = " ",
        },
        source = diff_source,
      },
    },

lua/extensions/init.luaのlualineのdependenciesにgitsignsを追加します。

  {
    "nvim-lualine/lualine.nvim",
    event = { "VimEnter" },
    config = function()
      require("extensions.lualine")
    end,
    dependencies = {
      "nvim-tree/nvim-web-devicons",
      "rmehri01/onenord.nvim",
      "lewis6991/gitsigns.nvim",
    },
  },

ドキュメントの設定内容をほぼそのまま持ってきています。
zenn上ではアイコンが文字化けしていますが、wezterm & nvim上では化ていないと思います。
nvimを再起動するとgitsigns.nvimがインストールされます。
gitのstatusがサイドバーでわかるようになっています。
gitsigns.nvim

nvim-navic

https://github.com/SmiteshP/nvim-navic
nvim-navicは、コードのパンくずを提供してくれるpluginです。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "SmiteshP/nvim-navic",
    event = { "BufNewFile", "BufReadPre" },
    config = function()
      require("extensions.nvim-navic")
    end,
    dependencies = {
      "neovim/nvim-lspconfig",
    },
  },

lua/extensions/nvim-navic.luaに設定を記載します。

require("nvim-navic").setup({
  lsp = {
    auto_attach = true,
  },
  highlight = true,
  depth_limit = 9,
})

lua/extensions/init.luaのlualineのdependenciesにnvim-navicを追加します。

  {
    "nvim-lualine/lualine.nvim",
    event = { "VimEnter" },
    config = function()
      require("extensions.lualine")
    end,
    dependencies = {
      "nvim-tree/nvim-web-devicons",
      "rmehri01/onenord.nvim",
      "lewis6991/gitsigns.nvim",
      "SmiteshP/nvim-navic",
    },
  },

ドキュメントの設定をそのまま設定しています。
nvimを再起動するとnvim-navicがインストールされます。
適当なファイルを開くと下部のステータスラインにパンくずが表示されるようになります。
nvim-navic

nvim-scrollbar

https://github.com/petertriho/nvim-scrollbar
nvim-scrollbarは、その名の通りスクロールバーを表示するpluginになります。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "petertriho/nvim-scrollbar",
    event = { "BufNewFile", "BufReadPre" },
    config = function()
      require("extensions.nvim-scrollbar")
    end,
    dependencies = {
      "kevinhwang91/nvim-hlslens",
      "lewis6991/gitsigns.nvim",
    },
  },

lua/extensions/nvim-scrollbar.luaに設定を記載します。

local colors = require("onenord.colors").load()
require("scrollbar").setup({
  handle = {
    color = colors.bg_highlight,
  },
  marks = {
    Search = { color = colors.orange },
    Error = { color = colors.error },
    Warn = { color = colors.warn },
    Info = { color = colors.info },
    Hint = { color = colors.hint },
    Misc = { color = colors.purple },
  },
})
require("scrollbar.handlers.gitsigns").setup()

ドキュメントの設定内容をほぼそのまま持ってきています。
nvim-hlslensの結果をscrollbarに表示させるために設定を編集します。
lua/extentions/init.lua

  {
    "kevinhwang91/nvim-hlslens",
    event = { "FilterWritePre" },
    keys = {
      "<leader>L",
    },
    config = function()
      require("scrollbar.handlers.search").setup(require("extensions.nvim-hlslens"))
    end,
  },

lua/extensions/nvim-hlslens.lua

local config = {
  calm_down = true,
  nearest_only = true,
}
vim.keymap.set({ "n", "x" }, "<leader>L", function()
  vim.schedule(function()
    if require("hlslens").exportLastSearchToQuickfix() then
      vim.cmd("cw")
    end
  end)
  return ":noh<CR>"
end, { expr = true })
return config

nvimを再起動するとnvim-scrollbarがインストールされます。
右側にscrollbarが表示されるようになり、gitのステータスやhlslensの結果も表示されるようになりました。
nvim-scrollbar

telescope

https://github.com/nvim-telescope/telescope.nvim
https://github.com/nvim-telescope/telescope-fzf-native.nvim
telescopeは、ファジーファインダーが使えるようになるpluginになります。
telescope-fzf-nativeにfzfをtelescopeで扱う設定が書かれています。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    'nvim-telescope/telescope.nvim', tag = '0.1.8',
    keys = {
      "<leader>ff",
      "<leader>fg",
      "<leader>fb",
      "<leader>fh",
    },
    config = function()
      require("extensions.telescope")
    end,
    dependencies = { 
      'nvim-lua/plenary.nvim',
      { 'nvim-telescope/telescope-fzf-native.nvim', build = 'make' }}
  },

lua/extensions/telescope.luaに設定を記載します。

require("telescope").setup({
  defaults = {
    mappings = {
      i = {
        ["<C-h>"] = "which_key",
        ["<esc>"] = require("telescope.actions").close,
        ["<C-[>"] = require("telescope.actions").close,
      },
      n = {
        ["<C-h>"] = "which_key",
      },
    },
    winblend = 20,
  },
  extensions = {
    fzf = {
      fuzzy = true,
      override_generic_sorter = true,
      override_file_sorter = true,
      case_mode = "smart_case",
    },
  },
})
require("telescope").load_extension("fzf")
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)

ドキュメントの設定をほぼそのまま持ってきてます。
nvimを再起動するとtelescopeがインストールされます。
私の環境ではleaderに,を適用しているので、,ffを入力すると以下のように表示されます。
telescope
基本的に私は,ffでファイル移動しています。

nvim-lspconfig

https://github.com/neovim/nvim-lspconfig
nvim-lspconfigは、nvim用のlspクライアント構成を提供するpluginです。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "neovim/nvim-lspconfig",
    event = { "BufNewFile", "BufReadPre" },
    config = function()
      require("extensions.nvim-lspconfig")
    end,
  },

lua/extensions/nvim-lspconfig.luaに設定を記載します。

vim.keymap.set("n", "<space>e", vim.diagnostic.open_float)
vim.keymap.set("n", "[d", vim.diagnostic.goto_prev)
vim.keymap.set("n", "]d", vim.diagnostic.goto_next)
vim.keymap.set("n", "<space>q", vim.diagnostic.setloclist)
vim.api.nvim_create_autocmd("LspAttach", {
  group = vim.api.nvim_create_augroup("UserLspConfig", {}),
  callback = function(ev)
    local opts = { buffer = ev.buf }
    vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts)
    vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts)
    vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)
    vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts)
    vim.keymap.set("n", "<C-g>", vim.lsp.buf.signature_help, opts)
    vim.keymap.set("n", "<space>wa", vim.lsp.buf.add_workspace_folder, opts)
    vim.keymap.set("n", "<space>wr", vim.lsp.buf.remove_workspace_folder, opts)
    vim.keymap.set("n", "<space>wl", function()
      print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
    end, opts)
    vim.keymap.set("n", "<space>D", vim.lsp.buf.type_definition, opts)
    vim.keymap.set("n", "<space>rn", vim.lsp.buf.rename, opts)
    vim.keymap.set({ "n", "v" }, "<space>ca", vim.lsp.buf.code_action, opts)
    vim.keymap.set("n", "gr", vim.lsp.buf.references, opts)
    vim.keymap.set("n", "<space>f", function()
      vim.lsp.buf.format({ async = true })
    end, opts)
  end,
})
vim.api.nvim_create_autocmd("BufWritePre", {
  buffer = buffer,
  callback = function()
    vim.lsp.buf.format({ async = false })
  end,
})

以前はkeymapの設定が書いてあったのですが、今は無くなっているようです。
nvimを再起動するとnvm-lspconfigがインストールされます。

mason.nvim

https://github.com/williamboman/mason.nvim
mason.nvimは、LSP・DAP・Linter・Formatterなどの外部ツールを管理できるpluginです。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "williamboman/mason.nvim",
    event = { "BufNewFile", "BufReadPre" },
    config = function()
      require("extensions.mason")
    end,
  },

lua/extensions/mason.luaに設定を記載します。

require("mason").setup({
  ui = {
    check_outdated_packages_on_open = false,
    border = "single",
  },
})

ドキュメントの設定をほぼそのまま持ってきてます。
nvimを再起動するとmasonがインストールされます。
:Masonと入力すると以下のような画面がみれると思います。
mason.nvim
lua-language-serverstyluaをインストールしておきましょう。

mason-lspconfig.nvim

https://github.com/williamboman/mason-lspconfig.nvim
mason-lspconfigは、masonとnvim-lspconfigを繋ぐpluginになります。
lua/extensions/init.luaのmasonのdependenciesに以下を追加します。

  {
    "williamboman/mason.nvim",
    event = { "BufNewFile", "BufReadPre" },
    config = function()
      require("extensions.mason")
    end,
    dependencies = {
      "williamboman/mason-lspconfig.nvim",
      "neovim/nvim-lspconfig",
    },
  },

lua/extensions/mason.luaに以下を追加します。

require("mason-lspconfig").setup_handlers({
  function(server_name)
    require("lspconfig")[server_name].setup({})
  end,
})

ドキュメントの設定をほぼそのまま持ってきてます。
nvimを再起動するとmason-lspconfigがインストールされます。
これでmasonでインストールしたlspを使えるようになります。
mason-lspconfig.nvim

none-ls.nvim

https://github.com/nvimtools/none-ls.nvim
null-lsがアーカイブされ、フォークされたのがnone-lsになります。
none-ls.nvimは、LinterやFormatterなどの非LSPソースを簡単な設定で利用できるようにするpluginです。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "nvimtools/none-ls.nvim",
    event = { "BufNewFile", "BufReadPre" },
    config = function()
      require("extensions.none-ls")
    end,
  },

lua/extensions/none-ls.luaに設定を記載します。

local lsp_formatting = function(bufnr)
  vim.lsp.buf.format({
    filter = function(client)
      return client.name == "null-ls"
    end,
    bufnr = bufnr,
  })
end
local augroup = vim.api.nvim_create_augroup("LspFormatting", {})
require("null-ls").setup({
  on_attach = function(client, bufnr)
    if client.supports_method("textDocument/formatting") then
      vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr })
      vim.api.nvim_create_autocmd("BufWritePre", {
        buffer = bufnr,
        group = augroup,
        callback = function()
          lsp_formatting(bufnr)
        end,
        desc = "[lsp] format on save",
      })
    end
  end,
})

nvimを再起動するとnone-lsがインストールされます。

mason-null-ls.nvim

mason-null-ls.nvimは、masonとnone-lsを繋ぐpluginになります。
lua/extensions/init.luaのmasonのdependenciesに以下を追加します。

  {
    "williamboman/mason.nvim",
    event = { "BufNewFile", "BufReadPre" },
    config = function()
      require("extensions.mason")
    end,
    dependencies = {
      "williamboman/mason-lspconfig.nvim",
      "jay-babu/mason-null-ls.nvim",
      "nvimtools/none-ls.nvim",
      "neovim/nvim-lspconfig",
    },
  },

lua/extensions/mason.luaに設定を追加します。

require("mason-null-ls").setup({
  automatic_setup = true,
  handlers = {},
})

ドキュメントの設定をそのまま設定しています。
nvimを再起動するとmason-null-lsがインストールされます。
適当なluaファイルを保存すると自動フォーマットされると思います。

Comment.nvim

https://github.com/numToStr/Comment.nvim
Comment.nvimは、その名の通りコメントアウトを楽にしてくれるpluginになります。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "numToStr/Comment.nvim",
    event = { "BufNewFile", "BufReadPre" },
    config = function()
      require("extensions.comment")
    end,
  },

lua/extensions/comment.luaに設定を記載します。

require("Comment").setup({
  ---Add a space b/w comment and the line
  padding = true,
  ---Whether the cursor should stay at its position
  sticky = true,
  ---Lines to be ignored while (un)comment
  ignore = nil,
  ---LHS of toggle mappings in NORMAL mode
  toggler = {
    ---Line-comment toggle keymap
    line = "gcc",
    ---Block-comment toggle keymap
    block = "gbc",
  },
  ---LHS of operator-pending mappings in NORMAL and VISUAL mode
  opleader = {
    ---Line-comment keymap
    line = "gc",
    ---Block-comment keymap
    block = "gb",
  },
  ---LHS of extra mappings
  extra = {
    ---Add comment on the line above
    above = "gcO",
    ---Add comment on the line below
    below = "gco",
    ---Add comment at the end of line
    eol = "gcA",
  },
  ---Enable keybindings
  ---NOTE: If given `false` then the plugin won't create any mappings
  mappings = {
    ---Operator-pending mapping; `gcc` `gbc` `gc[count]{motion}` `gb[count]{motion}`
    basic = true,
    ---Extra mapping; `gco`, `gcO`, `gcA`
    extra = true,
  },
  ---Function to call before (un)comment
  pre_hook = nil,
  ---Function to call after (un)comment
  post_hook = nil,
})

ドキュメントの設定をそのまま設定しています。
nvimを再起動するとComment.nvimがインストールされます。
適当なファイルを開いてgccと入力すると1行コメントアウトされると思います。
Comment.nvim

trouble.nvim

https://github.com/folke/trouble.nvim
trouble.nvimは、コードが起こす問題を解決するのに役立つpluginになります。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "folke/trouble.nvim",
    keys = {
      "<leader>xx",
      "<leader>xX",
      "<leader>cs",
      "<leader>cl",
      "<leader>xL",
      "<leader>xQ",
    },
    config = function()
      require("extensions.trouble")
    end,
    dependencies = "nvim-tree/nvim-web-devicons",
  },

lua/extensions/trouble.luaに設定を記載します。

require("trouble").setup({})
vim.keymap.set("n", "<leader>xx", "<CMD>Trouble diagnostics toggle<CR>", { desc = "Diagnostics (Trouble)" })
vim.keymap.set(
  "n",
  "<leader>xX",
  "<CMD>Trouble diagnostics toggle filter.buf=0<CR>",
  { desc = "Buffer Diagnostics (Trouble)" }
)
vim.keymap.set("n", "<leader>cs", "<CMD>Trouble symbols toggle focus=false<CR>", { desc = "Symbols (Trouble)" })
vim.keymap.set(
  "n",
  "<leader>cl",
  "<CMD>Trouble lsp toggle focus=false win.position=right<CR>",
  { desc = "LSP Definitions / references / ... (Trouble)" }
)
vim.keymap.set("n", "<leader>xL", "<CMD>Trouble loclist toggle<CR>", { desc = "Location List (Trouble)" })
vim.keymap.set("n", "<leader>xQ", "<CMD>Trouble qflist toggle<CR>", { desc = "Quickfix List (Trouble)" })

ドキュメントの設定をそのまま設定しています。
nvimを再起動するとtrouble.nvimがインストールされます。
適当なファイルを開いて,xxを入力すると以下の情報が見れると思います。
trouble.nvim

nvim-navbuddy

https://github.com/SmiteshP/nvim-navbuddy
nvim-navbuddyは、パンくずのようなナビゲーション機能をポップアップで表示してくれるpluginです。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "SmiteshP/nvim-navbuddy",
    event = { "BufNewFile", "BufReadPre" },
    config = function()
      require("extensions.nvim-navbuddy")
    end,
    dependencies = {
      "neovim/nvim-lspconfig",
      "SmiteshP/nvim-navic",
      "MunifTanjim/nui.nvim",
      "nvim-telescope/telescope.nvim",
    },
  },

lua/extensions/nvim-navbuddy.luaに設定を記載します。

local actions = require("nvim-navbuddy.actions")
require("nvim-navbuddy").setup({
  window = {
    size = { height = "40%", width = "100%" },
    position = { row = "96%", col = "50%" },
  },
  mappings = {
    ["t"] = actions.telescope({
      layout_config = {
        height = 0.40,
        width = 0.90,
        prompt_position = "top",
        preview_width = 0.70,
      },
      layout_strategy = "horizontal",
    }),
  },
  lsp = {
    auto_attach = true,
  },
})
vim.keymap.set("n", "<leader>nb", vim.cmd.Navbuddy)

ドキュメントの設定ほぼそのままですが、見た目を少し変えています。
nvimを再起動するとnvim-navbuddyがインストールされます。
適当なファイルを開いて,nbを入力するとコードが階層化されたUIを見ることができます。
nvim-navbuddy

nvim-cmp

https://github.com/hrsh7th/nvim-cmp
nvim-cmpは、補完機能を提供するpluginになります。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "hrsh7th/nvim-cmp",
    event = { "VimEnter" },
    config = function()
      require("extensions.nvim-cmp")
    end,
    dependencies = {
      "neovim/nvim-lspconfig",
      "hrsh7th/cmp-nvim-lsp",
      "hrsh7th/cmp-buffer",
      "hrsh7th/cmp-path",
      "hrsh7th/cmp-cmdline",
      "onsails/lspkind-nvim",
      "hrsh7th/cmp-nvim-lsp-signature-help",
      "hrsh7th/cmp-nvim-lsp-document-symbol",
    },
  },

lua/extensions/nvim-cmp.luaに設定を記載します。

local cmp = require("cmp")
cmp.setup({
  mapping = cmp.mapping.preset.insert({
    ["<C-b>"] = cmp.mapping.scroll_docs(-4),
    ["<C-f>"] = cmp.mapping.scroll_docs(4),
    ["<C-Space>"] = cmp.mapping.complete(),
    ["<C-e>"] = cmp.mapping.abort(),
    ["<CR>"] = cmp.mapping.confirm({ select = false }),
  }),
  sources = cmp.config.sources({
    { name = "nvim_lsp" },
    { name = "nvim_lsp_signature_help" },
  }, {
    { name = "buffer" },
  }, {
    { name = "path" },
  }),
})
cmp.setup.cmdline({ "/", "?" }, {
  mapping = cmp.mapping.preset.cmdline(),
  sources = {
    { name = "nvim_lsp_document_symbol" },
    {
      name = "buffer",
      option = {
        keyword_pattern = [[\k\+]],
      },
    },
  },
})
cmp.setup.cmdline(":", {
  mapping = cmp.mapping.preset.cmdline(),
  sources = cmp.config.sources({
    { name = "path" },
  }, {
    { name = "cmdline" },
  }),
  matching = { disallow_symbol_nonprefix_matching = false },
})

lua/extensions/mason.luaの設定を編集します。

local capabilities = require("cmp_nvim_lsp").default_capabilities()
require("mason-lspconfig").setup_handlers({
  function(server_name)
    require("lspconfig")[server_name].setup({
      capabilities = capabilities,
    })
  end,
})

ドキュメントの設定ほぼそのままで、各種pluginを追加しています。
nvimを再起動するとnvim-cmpがインストールされます。
適当なファイルを開いてinsertモードでctrl + nすると入力候補が出てくると思います。
nvim-cmp

copilot.lua

https://github.com/zbirenbaum/copilot.lua
copilot.luaは、nvim上でcopilotを扱えるようにするpluginになります。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "zbirenbaum/copilot.lua",
    event = "VimEnter",
    config = function()
      require("extensions.copilot")
    end,
  },

lua/extensions/copilot.luaに設定を記載します。

require("copilot").setup({
  panel = { enabled = false },
  suggestion = { enabled = false },
})

ドキュメントの設定ほぼそのままです。
nvimを再起動するとcopilot.luaがインストールされます。
:Copilot authを入力してアカウント連携してください。

copilot-cmp

https://github.com/zbirenbaum/copilot-cmp
cpilot-cmpは、補完でcopilotが使えるようになるpluginです。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "zbirenbaum/copilot-cmp",
    event = { "VimEnter" },
    config = function()
      require("copilot_cmp").setup()
    end,
    dependencies = {
      "hrsh7th/nvim-cmp",
      "zbirenbaum/copilot.lua",
    },
  },

lua/extensions/nvim-cmp.luaを編集します。

cmp.setup({
  mapping = cmp.mapping.preset.insert({
    ["<C-b>"] = cmp.mapping.scroll_docs(-4),
    ["<C-f>"] = cmp.mapping.scroll_docs(4),
    ["<C-Space>"] = cmp.mapping.complete(),
    ["<C-e>"] = cmp.mapping.abort(),
    ["<CR>"] = cmp.mapping.confirm({ select = true }),
  }),
  sources = cmp.config.sources({
    { name = "nvim_lsp" },
    { name = "nvim_lsp_signature_help" },
  }, {
    { name = "copilot" },
  }, {
    { name = "buffer" },
  }, {
    { name = "path" },
  }),
  formatting = {
    format = require("lspkind").cmp_format({
      mode = "symbol",
      maxwidth = 50,
      ellipsis_char = "...",
      preset = "codicons",
      symbol_map = { Copilot = "" },
    }),
  },
})

nvim-cmpでcopilotを呼び出せるようにし、フォーマットを変えています。
nvimを再起動するとcopilot-cmpがインストールされます。
適当なファイルで適当な文字列を入力するとcopilotくんが出てくるようになります。
copilot-cmp

nvim-surround

https://github.com/kylechui/nvim-surround
nvim-surroundは、タグやクォーテーションなどを便利に追加・編集・削除できるpluginになります。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "kylechui/nvim-surround",
    version = "*",
    event = { "BufNewFile", "BufReadPre" },
    config = function()
      require("extensions.nvim-surround")
    end,
  },

lua/extensions/nvim-surround.luaに設定を記載します。

require("nvim-surround").setup({})

nvimを再起動するとnvim-surroundがインストールされます。
追加する場合はys{motion}{char}、削除の場合はds{char}、編集の場合はcs{target}{replacement}を入力すると変換してくれます。

nvim-autopairs

https://github.com/windwp/nvim-autopairs
nvim-autopairsは、その名の通り括弧などのペアを自動で入力してくれるpluginになります。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "windwp/nvim-autopairs",
    event = { "BufNewFile", "BufReadPre" },
    config = function()
      require("extensions.nvim-autopairs")
    end,
  },

lua/extensions/nvim-surround.luaに設定を記載します。

require("nvim-autopairs").setup({})

nvimを再起動するとnvim-autopairsがインストールされます。
適当なファイルで{を入力すると}が自動で入力されるようになります。
nvim-autopairs

nvim-ts-autotag

https://github.com/windwp/nvim-ts-autotag
nvim-ts-autotagは、htmlタグを自動でclose&renameしてくれるpluginになります。
lua/extensions/init.luaのpluginsに以下を追加します。

  {
    "windwp/nvim-ts-autotag",
    event = { "BufNewFile", "BufReadPre" },
    config = function()
      require("extensions.nvim-ts-autotag")
    end,
  },

lua/extensions/nvim-ts-autotag.luaに設定を記載します。

require("nvim-ts-autotag").setup({})

nvimを再起動するとnvim-autopairsがインストールされます。
適当なhtmlで<div>を入力すると</div>が自動で入力されるようになります。
nvim-ts-autotag

まとめ

長々とお付き合いいただきありがとうございました。
昨年Neovimの環境を構築した際は、coralpinkさんの手順そのままに、どのpluginがどういう役割を果たしていて設定は何があってというのを浅い理解のまま1年使っていました。
今回1から1つずつpluginを導入していき、各々どういう役割で何の設定があるのかを理解しながら快適なNeovim環境を構築できました。
また、役割が被っていたplugin、邪魔だなと思っていた機能のplugin、ほぼ使っていなかったpluginを一掃できたので、大変満足です。
他におすすめのプラグインや設定ありましたらコメントいただければと思います。

君もイカしたNeovim環境で開発してみなイカ?🦑

株式会社モニクル

Discussion