タイトル画像

status.nvim

こんにちは。N本ノック13日目ですね。 やっと執筆時点の定期考査が終わって胸をなでおろしている静カニです。 というわけで今回は、自作statuslineプラグインのstatus.nvimの使い方、設計思想について書いていきます。 ちなみに設計思想はところどころに垣間見えるようにしてるレベルなので自力で察してください。

導入

お好みのプラグインマネージャーで導入してください。 もちろん私は自作の[manager.nvim]です。解説記事はこれですね(ダイマ)。 私の設定はこれです。

機能

コンポーネントを繋げてるだけです。

中身はどうしろと

「中身はどう用意するのか」、という話です。 自分で用意してください…というのはさすがに鬼畜すぎるのでちゃんと用意してあります。 (今から挙げるものが作者純正というだけで自作できますよ!) それがこの3つです。

このリポジトリたちはいい感じのコンポーネント詰め合わせセットのような感じです。 少なくとも直書きするよりは設定ファイルが大分マシな見た目になると思います。 これらを踏まえた実際の使い方を見ていきます。

設定

この設定例は私の設定のうちあまり必須でない部分を取り除いたものです。

local function setup_highlights()
    local fg_ink = "#1e2030"

    vim.api.nvim_set_hl(0, "StatusNormal", { fg = fg_ink, bg = "#c3e88d", bold = true })
    vim.api.nvim_set_hl(0, "StatusInsert", { fg = fg_ink, bg = "#82aaff", bold = true })
    vim.api.nvim_set_hl(0, "StatusVisual", { fg = fg_ink, bg = "#c099ff", bold = true })
    vim.api.nvim_set_hl(0, "StatusReplace", { fg = fg_ink, bg = "#ff757f", bold = true })
    vim.api.nvim_set_hl(0, "StatusCommand", { fg = fg_ink, bg = "#ffc777", bold = true })
    vim.api.nvim_set_hl(0, "StatusTerminal", { fg = fg_ink, bg = "#4fd6be", bold = true })
    vim.api.nvim_set_hl(0, "StatusMain", { fg = "#c8d3f5", bg = "#1e2030" })
end

local function config()
    setup_highlights()
    local status = require("status.core")
    local std = require("status.std")
    local git = require("status.git")
    local lsp = require("status.lsp")
    status.setup({
        components = {
            left = {
                std.mode,
                "|",
                git.branch,
                git.diff,
                "|",
                lsp.status,
                lsp.diagnostics,
            },
            right = {
                std.filesize,
                std.encoding,
                std.filetype,
                "|",
                std.file,
                "[%l:%c]",
            },
        },
    })

    vim.opt.statusline = "%!v:lua.require('status.core').render()"
end

return function(manager)
    manager:add({
        id = "status.nvim",
        url = "https://github.com/shizukani-cp/status.nvim",
        dependencies = {
            "status-std",
            "status-git",
            "status-lsp",
        },
        config = config,
    })
    manager:load("status.nvim")
end

コードの解説

setup_highlightsrequireの嵐、setupして標準に流し込んでいるところに分けられます。 ということで見ていきましょう。

setup_highlights

ここで諸々のハイライトグループを設定しています。 これは基本的にstatus-stdのmodeで使われていて、highlightを設定するとモードによって色が変わるようになります。

私のdotfiles内ではtokyonight.nvimのデータを引っ張ってきてますが、この設定例だと色データもハードコードしてます。

requireの嵐

そこの4つ並んでるだけでどこが嵐だと思った人は今後夜出歩くとき背後に気をつけましょう。

このrequireでsetupするためのstatus本体や、コンポーネント詰め合わせセットを持ってきています。

setup

ここがキモですね。 キモではありますがだからといって複雑なわけではなく、構造は至ってシンプルです。 一行で表すとsetup({ components = { left = { std.mode }, right = { std.file } } })というようになりますね。 ということで、このleft,right内にコンポーネントを大量に置いていくわけです。

setupのもう少し詳細な仕様についてです。setupは渡されたものを2種類に分類しています。 文字列と関数ですね。関数の場合、render時にその関数が実行され、その結果が結合されていきます。 一方、文字列の場合renderするときはそのままの文字列が結合される対象になります。 このためfunction() return "|" endというムダ関数が"|"という劇的ビフォーアフターに。 劇的ビフォーアフター…匠…クリーパー…(ここで発狂した方はマインクラフターだと思います) ちなみに同じような関数を書いていた人がいます。 誰でしょうねえ…証拠物件はこちら

標準に流し込む

vim.opt.statusline = "%!v:lua.require('status.core').render()"で標準機能を使って流し込めます。 解説しておくと、vim.opt.statuslineでそれをstatuslineに設定するよ、ということができます。 その対象が後半ですね。シンプルにluaでstatus.coreを呼び出しrenderしています。

勘の良い方は気付いたかもしれません。renderはただの文字列を錬成する関数です。 なので(コンポーネントは全て純粋関数であるものとすると)render自体は純粋関数です。 ですから「なんか挙動がおかしいなあ…」と思ったら、 :lua vim.print(require('status.core').render())ですぐにみんな大好きブリントデバッグができます。

まとめ

manager.nvimよりも設定させていただきありがとうございますできるようになったと思います。 設定させていただきありがとうございますって何なんだって?vim-jpに来ればそのうち分かります。