【Lua入門】Neovimプラグインは5分で作れる。「Hello World」を表示するだけの自作プラグイン開発
「Neovimのプラグイン開発」と聞くと、何かすごい魔法を使っているように思えるかもしれません。
しかし、現代のNeovimはLuaという非常にシンプルな言語で制御されており、ディレクトリ構成さえ守れば、誰でも簡単に機能を拡張できます。
今回は、「コマンドを叩くと、画面中央に挨拶を表示するフローティングウィンドウが出る」という、シンプルながらも"プラグインらしい"挙動をする機能を作ってみましょう。
1. ディレクトリ構成:これが全ての基本
Neovimのプラグインは、特定のディレクトリ構造を持ったただのフォルダーです。
適当な場所(~/dev/my-first-plugin など)に、以下の構造を作ってください。
my-first-plugin/
└── lua/
└── hello/
└── init.lua
-
重要:
lua/フォルダの中に作ったサブフォルダ名(ここではhello)が、require('hello')で呼び出す際の名前になります。一意な名前にするのがコツです。
2. コードを書く:APIを叩くだけ
lua/hello/init.lua を開き、以下のコードを記述します。
やっていることはシンプルで、**「バッファ(メモリ上の作業領域)を作り、ウィンドウを開き、そこに文字を入れる」**だけです。
-- lua/hello/init.lua
local M = {}
-- メインの関数
function M.say_hello()
-- 1. 新しいバッファを作成 (listed=false, scratch=true)
local buf = vim.api.nvim_create_buf(false, true)
-- 2. バッファに文字を書き込む
vim.api.nvim_buf_set_lines(buf, 0, -1, false, {
" Hello, Neovim! ",
" This is my 1st ",
" Plugin using Lua ",
})
-- 3. ウィンドウの設定(画面中央にフローティング表示)
local width = 20
local height = 3
local ui = vim.api.nvim_list_uis()[1]
local row = (ui.height - height) / 2
local col = (ui.width - width) / 2
local opts = {
relative = "editor",
width = width,
height = height,
row = row,
col = col,
style = "minimal",
border = "rounded", -- 角丸の枠線
}
-- 4. ウィンドウを開く
vim.api.nvim_open_win(buf, true, opts)
end
-- セットアップ関数(ユーザーが require('hello').setup() で呼ぶ)
function M.setup()
-- コマンドを定義する (:Hello)
vim.api.nvim_create_user_command("Hello", M.say_hello, {})
end
return M
3. 動かしてみる:ローカルプラグインの読み込み
作ったプラグインをNeovimに認識させましょう。
普段使っているプラグインマネージャー(lazy.nvimなど)の設定ファイルを開き、ローカルパスを指定して読み込ませます。
lazy.nvim の場合:
-- plugins.lua など
return {
{
dir = "~/dev/my-first-plugin", -- 自分のフォルダパスを指定
config = function()
-- ここでinit.luaのsetup関数を呼ぶ
require("hello").setup()
end,
},
}
設定を保存してNeovimを再起動し、コマンドモードで :Hello と打ってみてください。
画面中央に、角丸の枠線で囲まれた「Hello, Neovim!」が浮かび上がったはずです。
これが、あなたが初めて作ったNeovimプラグインです。
4. ステップアップ:Rustでプラグインを書く (nvim-oxi)
Luaは手軽ですが、複雑な計算や重い処理には向きません。
そこで、Rust使いのあなたの出番です。
nvim-oxi というクレートを使うと、Rustで書いたコードを共有ライブラリ(.so や .dll)としてコンパイルし、それをLuaから require して動かすことができます。
Rustでの実装イメージ:
use nvim_oxi::{Dictionary, Function, libuv::{self, AsyncHandle}};
#[nvim_oxi::module]
fn my_rust_plugin() -> nvim_oxi::Result<Dictionary> {
let mut dict = Dictionary::new();
// Rustの関数をLuaに公開
dict.insert("compute_heavy_task", Function::from_fn(|()| {
// ここで重い計算やスレッド処理を行える
Ok("Result from Rust!".to_string())
}));
Ok(dict)
}
「UI周りの軽い処理はLua」、「検索アルゴリズムや通信処理などのコアロジックはRust」。
このハイブリッド構成こそが、**最強のPDE(個人用開発環境)**を作るための最適解です。