私の Neovim を振り返ってみる

2023/12/24に公開

Vim アドベントカレンダーシリーズ2 24日目の記事です 🎄

https://qiita.com/advent-calendar/2023/vim

はじめに

以前に「2023年わたしの Neovim」という記事を書いてから、ちょうど半年くらいが経ちます。

https://zenn.dev/arrow2nd/articles/aa2605c67efdb0

この記事を書いていた当時はまだ研修中でしたが、今ではガッツリ業務で Neovim を使うようになりました。

私の環境が変わったように Neovim の環境も大きく変わってきたので、今回はそれを振り返ってみたいと思います。

こんな感じになった

Before

以前

After

今

外観周り

カラースキームを自作に

iceberg.vim を愛用していたのですが、自作に乗り換えました。

https://github.com/arrow2nd/aqua

何か不満があったとかではなく、「なんか自作してみたいな~」の気持ちだけで作ったので、かなり iceberg をリスペクトした配色になっています。

濃い水色と差し色のピンクがかわいくて気に入っています。

aqua

フローティングウィンドウにボーダーを付けた

あったらかわいいので付けました。

ボーダーありのウィンドウ

listcharsを変更

パっと見で何が何なのか分かりにくかったので、良さそうな記号を割り当て直しました。

option.lua
opt.listchars = {
-   tab = '>>',
+   tab = "▸ ",
-   trail = '-',
+   trail = "⋅",
-   nbsp = '+'
+   nbsp = "␣",
+   extends = "❯",
+   precedes = "❮"
}

機能周り

自動フォーマットを無効化できるように

保存時に自動でフォーマットが走るように設定していたのですが、プロジェクトによっては困る場面が出てきたのでパス指定で無効化できるようにしました。

util.lua
-- 自動フォーマットを有効にできるか
--
-- 環境変数 `NVIM_DISABLE_AUTOFORMATTING_PROJECTS` にプロジェクトのパスを追加することで無効にできます
-- カンマ区切りで複数指定可能です
local function enable_autoformat()
  local root = vim.fn.getcwd(0)
  local disable_projects = vim.split(os.getenv("NVIM_DISABLE_AUTOFORMATTING_PROJECTS") or "", ",")

  -- 無効にするプロジェクトか
  for _, project in ipairs(disable_projects) do
    if root == project then
      return false
    end
  end

  return true
end

enable_autoformat() を自動フォーマットを有効にするかの条件に含めることで実現しています。

util.lua
-- 保存時に自動フォーマット
if client.supports_method("textDocument/formatting") and enable_autoformat() then
    local augroup = vim.api.nvim_create_augroup("LspFormatting", { clear = false })
    vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr })
    vim.api.nvim_create_autocmd("BufWritePre", {
      callback = function()
        vim.lsp.buf.format({ bufnr = bufnr, timeout_ms = 5000 })
      end,
      group = augroup,
      buffer = bufnr,
    })
end

プラグイン

ddu.vim

ddc.vim を使い始めた頃から存在は知っていたのですが、ついに telescope.nvim から乗り換えました。
初めは慣れなかったのですが、今ではすっかり手に馴染んでいます。

Shougo/ddu-ui-ffShougo/ddu-ui-filer を導入して、ファジーファインダー兼ファイラーとして利用しています。

https://github.com/Shougo/ddu.vim

使っている Source たち

Telescope で言うところの Pickers に当たるものです。
色々入れています。

ddc.vim

Shougo/ddc-source-cmdline を導入して、コマンドライン補完を有効にしました。

https://github.com/arrow2nd/dotfiles/blob/a5ce4816070d828f11544b3e00a4511cc952b484/.config/nvim/lua/plugins/ddc.lua#L28-L118

/ で検索するときに、バッファ内の単語が補完できたり、入力中にヘルプが見られたりするので助かっています。

コマンドライン補完

mini.starter

起動時に表示される画面です。
mini.nvim にいつの間にか増えてたので追加してみました。

mini.starter

直近に触ったファイルを開き直したいことが多々あるので、重宝しています。

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

mini.hipatterns

いつの間にか増えてたシリーズ第2弾です。
nvim-highlight-colors から移行しました。

mini.hipatterns

機能は少し減ったものの、特段不自由はしていません。

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

toggleterm

vim-floaterm を使っていたのですが、機能を持て余している感があったので移行しました。

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

efm-langserver

null-ls がアーカイブされたので移行しました。
Mason 経由で利用しています。

https://github.com/mattn/efm-langserver

cspell

Typo 軽減のために追加しました。
こちらは efm-langserver 経由で利用しています。

https://cspell.org/

デフォルトだと警告の主張が強いので、hint 扱いにしています。

lsp.lua
  -- cspellが実行できるなら追加
if vim.fn.executable("cspell") then
    languages["="] = {
      {
        lintCommand = "cspell --no-progress --no-summary --no-color --config=~/.config/cspell/cspell.json ${INPUT}",
        lintIgnoreExitCode = true,
        lintFormats = {
          "%f:%l:%c - %m",
          "%f:%l:%c %m",
        },
        lintSeverity = 4, -- hint
      },
    }
end

cspell
主張ひかえめ

また、:AddCspellLocalDic :AddCspellDotfilesDic で単語を辞書へ追加できるようにしています。

commands.lua
-- ファイルに1行追加
local function append_to_file(file, line)
  local f = io.open(file, "a")
  if f == nil then
    print("Error: Cannot open file for writing")
    return
  end

  f:write(line .. "\n")
  f:close()
end

-- カーソル下の単語をファイルに追加
function WriteWordToFile(file_path)
  local file = file_path

  if file_path:sub(1, 1) == "~" then
    file = vim.uv.os_homedir() .. file_path:sub(2)
  end

  local word = vim.fn.expand("<cword>")

  -- 単語を編集させる
  local input = vim.fn.input("Edit word: ", string.lower(word))
  vim.api.nvim_command("redraw")
  if input == "" then
    print("No word provided. Operation canceled.")
    return
  end

  append_to_file(file, input)

  print("Word '" .. input .. "' has been written to " .. file)
end

-- ローカル辞書に追加
vim.api.nvim_create_user_command("AddCspellLocalDic", "lua WriteWordToFile('~/.local/share/cspell/user.txt')", {})

-- dotfilesで管理している辞書に追加
vim.api.nvim_create_user_command("AddCspellDotfilesDic", "lua WriteWordToFile('~/.config/cspell/dic.txt')", {})

gp.nvim

ChatGPT を使うために追加しました。

gp.nvim

Markdown 形式で履歴が残るので、後から見返しやすい点が好きです。

https://github.com/Robitx/gp.nvim

さいごに

年末なので、私の Neovim の環境の変化を振り返ってみました。

dotfiles のコミットログを眺めながら記事を書いていたのですが、Neovim の設定以外にも当時試行錯誤していた様子が残っていてとても面白かったです。

ログ

これからも引き続き、盆栽のように設定を育てていきたいです…。

https://github.com/arrow2nd/dotfiles

Discussion