Neovimの履歴管理ができるAIプラグインsenpai.nvimの使い方
この記事はVim駅伝の2025年4月9日の記事です。
前回(2025年4月7日)の記事はmikoto2000さんのdevcontainer.vim で Claude Code を使うでした。
NeovimのAIプラグインもかなり増えてきましたね。今回はチャット履歴を保存して、後から会話も継続できるAIプラグインsenpai.nvimを紹介します。

senpai.nvimとは
senpai.nvimはNeovimのAI系プラグインです。筆者が作りました。
既存プラグインと比べた特徴は次のとおり。
- チャットの履歴が管理できる
- Mastra/Vercel AI SDKベースで作られている
- 呼び出しのためのデフォルトキーマップを設定していない
他の機能は次のとおり。
- MCP(Model Context Protocol)
- RAG(Retrieval Augmented Generation)
- プロンプトをカスタマイズしてチャットを開く(一言でなんていえばいいんでしょうね)
- conventionalコミットメッセージの作成
導入方法
eetann/senpai.nvim依存
依存はあります。なるべく依存減らしたいって人、ごめんなさいね。
- curl
- Bun
- インストール簡単だから許して
- 依存プラグイン
- nui.nvim: UIの表示で使用
- plenary.nvim: curlとかのラッパー
- nvim-treesitter: UIの表示で使用
Node.jsではなくBunを採用したのは速いからです。
インストール
lazy.nvimだと次のように書いてインストールできます。
return { "eetann/senpai.nvim", build = "bun install", dependencies = { "MunifTanjim/nui.nvim", "nvim-lua/plenary.nvim", "nvim-treesitter/nvim-treesitter", }, opts = {}}bun install、ちょっと時間かかります。履歴とかRAGの管理で必要なライブラリがあるんです。
lazy.nvimでの遅延読み込み
lazy.nvimでの遅延読み込みの例も載せておきます。
return { "eetann/senpai.nvim", build = "bun install", dependencies = { "MunifTanjim/nui.nvim", "nvim-lua/plenary.nvim", "nvim-treesitter/nvim-treesitter", }, keys = { { "<space>ss", "<Cmd>Senpai toggleChat<CR>" }, { "<space>sl", "<Cmd>Senpai promptLauncher<CR>" }, { "<space>sv", "<Cmd>Senpai transferToChat<CR>", mode = "v" }, }, cmd = { "Senpai" }, ft = "gitcommit", opts = {}}設定の書き方
プラグインの設定はsetupの中に書きます。
require("senpai").setup()lazy.nvimの場合、setupの中身はoptsに書きます。この書き方について知りたい人は別の記事「lazy.nvimの使い方から起動を爆速にする方法までを解説」を読んでください。
return { "eetann/senpai.nvim", -- 省略 opts = { -- ここに書く }}対応しているLLM
現在対応しているのプロバイダーは次のとおりです。
| 名前 | API tokenの環境変数 |
|---|---|
anthropic | ANTHROPIC_API_KEY |
deepseek | DEEPSEEK_API_KEY |
google | GOOGLE_GENERATIVE_AI_API_KEY |
openai | OPENAI_API_KEY |
openrouter | OPENROUTER_API_KEY |
デフォルトでどのプロバイダーを使うかはproviders.defaultに書きます。
require("senpai").setup({ providers = { default = "openrouter", },})各プロバイダーでのモデルの指定はmodel_idに書きます。
require("senpai").setup({ providers = { default = "openrouter", openrouter = { model_id = "openai/chatgpt-4o-latest" }, },})model_idの書き方は次のリンクを参考にしてください。
主要な機能の紹介
機能を紹介していきます。詳しい使い方はREADMEかヘルプを読んでください。
チャット機能
:Senpai toggleChatでチャットのウィンドウをトグルできます。

入力欄(下のウィンドウ)に入力したら<CR>で送信です。
ファイル読み込み
blink.cmpを使っていれば、/fileの補完でFinderが開き、選択したファイルが[bar.ts](./foo/bar.ts)のようにプロンプトに追記されます。
blink.cmpを使ってなくても、上記のようにリンク形式でファイルを指定すれば、ファイルの内容を読み込んでくれます。
ファイル編集
ファイル編集もできます。AIにファイル編集頼んだらReplace Fileというブロックが表示されます。
このブロック内でaを入力するとdiffが開きます。
diffはNeovimのdiffthisを使っているので、doやdpといったキーマップでdiffを適用できます(ヘルプは:help copy-diffs)。
キーマップ
?でチャットのヘルプが開きます。キーマップをカスタマイズしたらこのヘルプにも反映されます。

ここでEnterを押すとそのキーを入力したときと同じ動作になります。
キーマップを設定していないやつも実行できます。
たとえばopen_api_docで、senpai.nvim開発者向けのOpenAPI(OpenAIではない)のUIが開きます。

senpai.nvimが内部で使っているAPIをここで試せます。
履歴機能
履歴は自動で保存されます。:Senpai 〇〇Saveみたいなコマンドを打つ必要はありません。
過去のチャットを復元したい場合、:Senpai loadThreadで選択UIが開きます。
snacks.nvimユーザーであれば、画像のようにシステムプロンプトとかモデルもプレビューに表示されます。
履歴から復元したらそのまま会話も継続できます。
AIとの会話を一過性のものにはしたくないので履歴機能のあるプラグインにしました。「せんぱああああい、この前話してた実装なんですけど〜」みたいなノリです。
MCP
流行りのMCPも使えます。チャットでの呼び出しはAIが勝手に考えてくれます。
「このタイミングで呼び出さなくても……」ということはあるので、いずれメンションでの呼び出し(@fooみたいな)機能でオンオフできるようにしたいところです。
プロジェクトごとにMCPを設定もできます。詳しくは別の記事senpai.nvimのプロジェクト毎にルール・MCPを設定する方法をご覧ください。
server-sequential-thinkingなどは数回ツールを呼び出す都合で、一度のメッセージだけでは処理しきれないことがあります。その場合は「続きをお願いします」みたいに会話すればOKです。
RAG
RAGも使えます。URL以外はまだ対応していません。
チャットの入力欄にてgRを打つと、URL入力欄が表示されます。
URLを入力したらfetchして内部のDBに保存されます。チャットでの呼び出しは@ragを付けます。
設定の可視化
AI系のプラグインで設定していると、「これ本当に反映されたのかな?」と思うことがあります。たとえばプロバイダーをvim.env.OPENAI_API_KEY and "openai" or "openrouter"のように動的に設定している場合です。
senpai.nvimではいくつかの設定を可視化できます。
現在チャットに紐づくLLMプロバイダー・モデル名はチャットのトップに表示されます。
設定したシステムプロンプトはヘルプ?のshow_system_prompt、MCPのツール設定はshow_mcp_toolsから確認できます。
プロンプトのカスタマイズ
どのチャットでも共通のシステムプロンプトを設定したい場合、設定のchat.system_promptに書きます。
require("senpai").setup({ chat = { system_prompt = "Answers should be in Japanese." }})システムプロンプトは別に英語以外で書いてもかまいません。
プロジェクトごとにプロンプトを指定したい場合は、別の記事senpai.nvimのプロジェクト毎にルール・MCPを設定する方法をご覧ください。
カスタマイズしたプロンプトを使い分けたい場合、prompt_launchersに書きます。
require("senpai").setup({ prompt_launchers = { ["Tsundere"] = { system = "Answers should be tsundere style.", priority = 100, }, ["test message"] = { user = "test message. Hello!", }, },})ここで書いたやつは:Senpai promptLauncherで一覧として表示されます。選んだやつがチャットで開きます。
実際に筆者がこの記事の構成を考えるときに使ったpromptLauncherを載せておきます(記事自体は頑張って25歳の人間が書いてます!)。
コミットメッセージの自動生成
:Senpai commitMessageでコミットメッセージを生成できます。.git/COMMIT_EDITMSGを開いたときに実行してみてください。いわゆるConventional Commits形式で書いてくれます。
この機能を作ってから、senpai.nvimのコミットメッセージの大半はこの機能で書かせてます(実例:eetann/senpai.nvim@b865dcf)。
言語指定も可能です。
:Senpai commitMessage Japaneseプロンプトに渡すだけなので厳密な言語名じゃなくてもかまいません。
:Senpai commitMessage English(Tsundere)筆者は英語と日本語を使い分けたいので、次のようにキーマップを設定しています。.config/nvim/after/ftplugin/gitcommit.lua.
vim.keymap.set("n", "<C-g><C-g>", function() if vim.env.COMMIT_MESSAGE_ENGLISH == "1" then vim.cmd("Senpai commitMessage English") else vim.cmd("Senpai commitMessage Japanese") endend, { buffer = true, desc = "Senpai commitMessage" })環境変数COMMIT_MESSAGE_ENGLISHが1なら英語、それ以外は日本語にしています。リポジトリ毎の環境変数の設定にはmiseを使ってます。
以上、自作AIプラグインsenpai.nvimの紹介でした。動画で所々senpai(先輩)をsenapi(せなぴ)とtypoしていますが、現在は修正済みです。純粋に無能でした。
まだ1か月くらいしか経っていないひよっこプラグインです。速度面とかパフォーマンスは改善していきたいです。進捗はvim-jpのSlackの#times-eetannか@eetann092でウォッチできます。
他にもNeovimの記事を書いてます。よかったらどうぞ。最近のイチオシは:=について書いている記事です。