🎨

NeoVim でエラーや警告が出ている行をハイライトする(VSCode Error Lens 風)

2024/08/31に公開

Error Lens とは

VSCode に Error Lens という拡張がある。エラーや警告など Language Server の Diagnostics が出ている行の背景色を変えメッセージをインライン表示することで、Diagnostics を目立たせるもの。

Error Lens - Visual Studio Marketplace より

https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens

かわいいので NeoVim でもやりたい。

NeoVim で diagnostics が出ている行の背景色を変える

以下のコミットで vim.diagnostic.configsignslinehl が追加された。これを設定することで Error Lens のような行全体の背景色変更が実現できる。

https://github.com/neovim/neovim/pull/26555

https://neovim.io/doc/user/diagnostic.html#vim.diagnostic.Opts.Signs

vim.api.nvim_set_hl(0, "DiagnosticErrorLine", { bg = "いい感じの背景色" })
vim.api.nvim_set_hl(0, "DiagnosticWarnLine", { bg = "いい感じの背景色" })
vim.api.nvim_set_hl(0, "DiagnosticHintLine", { bg = "いい感じの背景色" })
vim.api.nvim_set_hl(0, "DiagnosticInfoLine", { bg = "いい感じの背景色" })

vim.diagnostic.config({
  signs = {
    text = {
      -- ...
    },
    linehl = {
      [vim.diagnostic.severity.ERROR] = "DiagnosticErrorLine",
      [vim.diagnostic.severity.WARN] = "DiagnosticWarnLine",
      [vim.diagnostic.severity.HINT] = "DiagnosticHintLine",
      [vim.diagnostic.severity.INFO] = "DiagnosticInfoLine",
    },
  },
})

おまけ: Catppuccin for VSCode の Error Lens を再現する

Catppuccin というカラーテーマがあるが、これの VSCode 版は Error Lens の色設定を同梱している。

https://marketplace.visualstudio.com/items?itemName=Catppuccin.catppuccin-vsc#extension-support

https://github.com/catppuccin/vscode/blob/catppuccin-vsc-v3.15.2/packages/catppuccin-vsc/src/theme/extensions/error-lens.ts

筆者は NeoVim でも Catppuccin を使っているので、公式(?)が考えて VSCode に実装してくれた色設定を真似している。
NeoVim では Floating Window など重なりがある場合以外で色の透過ができないため、alpha blending する関数を定義して使うことで擬似的に透過を再現した。

-- catppuccin のパレットを読み出す
local palettes = require("catppuccin.palettes")
local palette = palletes.get_palette("frappe")

-- catppuccin では `base` が背景色に使われるので、それをベースの色にしている
-- `alpha_blend` 関数は AI がなんかいい感じに作ってくれたやつを使う
vim.api.nvim_set_hl(0, "DiagnosticErrorLine", { bg = alpha_blend(palette.red, palette.base, 0.15) })
vim.api.nvim_set_hl(0, "DiagnosticWarnLine", { bg = alpha_blend(palette.peach, palette.base, 0.15) })
vim.api.nvim_set_hl(0, "DiagnosticHintLine", { bg = alpha_blend(palette.green, palette.base, 0.15) })
vim.api.nvim_set_hl(0, "DiagnosticInfoLine", { bg = alpha_blend(palette.blue, palette.base, 0.15) })

結果こんなかんじ。

https://github.com/izumin5210/dotfiles/pull/522

Discussion