Neovimにおいてluaのfunctionに対するbindは地味だけど便利
便利
Neovimの設定やらプラグインやらをLuaで書いていると、頻出する即時関数たち。
vim.api.nvim_create_user_command("Hoge", function()
vim.fn["hoge"]()
end, {})
function() ~ end
はFormatterで改行されがちです。Formatterは無設定こそ至上と主張する者としては、これは致し方無しと飲むしかありません。
しかしかといって、即時関数で包むことを止めて
vim.api.nvim_create_user_command("Hoge", vim.fn["hoge"], {})
などと書くと、意図しない引数を受け取って痛い目を見がちです。(詳細は割愛します)
…だったら、JavaScriptのbind
のように、引数を固定してしまえば良いのでは?
作った
local M = {}
--- 指定の関数のすべての引数を束縛した関数を返す
--- @param f function
--- @param ... any
--- @return function
function M.bind_all(f, ...)
local args = { ... }
return function()
return f(unpack(args))
end
end
--- 指定の関数の先頭のいくつかの引数を束縛した関数を返す
--- @param f function 関数
--- @param ... any 束縛する引数
--- @return function
function M.bind(f, ...)
local bound = { ... }
return function(...)
local args = { ... }
local merged = {}
for v in ipairs(bound) do
table.insert(merged, v)
end
for v in ipairs(args) do
table.insert(merged, v)
end
return f(unpack(merged))
end
end
return M
冒頭のユースケースを考えると、ほとんどのシーンはbind_all
で充分ですが、一応bind
も用意してみました。
充分にテストされていないので、後者の利用については十分ご注意ください。
local func = require("func")
vim.api.nvim_create_user_command("Hoge", func.bind_all(vim.fn["hoge"]), {})
便利ですね。
Bindをそんなくだらない目的に使うな、とお叱りを受けそうですが。
蛇足: 記事を書くということ
この記事は、ふとNeovimの設定をしていて思いついた便利関数を、Copilotに生成してもらい、それを元に20分ほどで書いた記事です。
正味本当にしょうもない内容だと思います。Neovimの標準機能のどこかにすでにある気もします。
ですが詳しく調べたりはしていません。思いつきをそのまま垂れ流すことにしました。
「記事を書く」というと、なんだか特別なもので、重厚で社会的意義のある文章を提供しなくてはならない、というプレッシャーがあります。
特にアドベントカレンダーとなると、そのプレッシャーは特に大きく感じられると思います。
しかし、そんなプレッシャーは実在しません。
ちょっとした思いつき、ちょっとしたハックをどんどん公開していきましょう。
時には批判を受けることもあるでしょう。時には過ちを含むこともあるでしょう。
しかし天賦の才でもない限り、記事を書かねば記事を書けるようにはなりません。
記事を書かねば、批判を受けることもできません。
他人の目にさらさねば、過ちに気づけないことすらあるでしょう。
他人の目に触れることで、あるいは意外な発想を誰かに与えることもあります。
いかに雑に記事を書くか。
今年はこれを1つのテーマとして、Vim駅伝にも参加してきました。
みなさんも、恐れず、雑なアウトプットを世の中に晒してほしいと常々思っています。
アドベントカレンダーは1つの良いきっかけになることでしょう。是非。
Discussion