I'm a bit confused on how 'binding' works in lua. The following function (neovim) defines a callback within vim.keymap.set() to be called later involving the bufnr from the outer scope. Now coming from a C++ background this seems odd, because bufnr would need to be captured/bound in a function closure, otherwise it wouldn't be available just like that within the callback scope (where vim.lsp.buf.format is called):
on_attach = function(client, bufnr)
-- Bind formatting to gf
if client.supports_method("textDocument/formatting") then
vim.keymap.set('n', 'gf', function()
vim.lsp.buf.format({ bufnr = bufnr, id = client.id, timeout_ms = 1000 })
end,
{ noremap = true, silent = true, buffer = bufnr })
end
end
How does that work in lua?
Lua is a lexically scoped language, and because of this all functions act as closures.
The anonymous function passed to vim.keymap.set is defined within the scope of the local variable bufnr, which in turn makes bufnr an upvalue, visible within the anonymous function.
This is easily demonstrable with a more plain Lua example.
local function pgen(to)
return function (n)
return n ^ to
end
end
local square = pgen(2)
local cube = pgen(3)
print(square(4), cube(5))
16.0 125.0
In this example, to is a local variable in each invocation of pgen. The anonymous functions returned from pgen retain visibility of each local to, accessing them as upvalues.
See: Lua 5.4: 3.5 - Visibility Rules
This form of automatic closure is very common in higher level languages. Equivalents can be seen in:
// JavaScript
const pgen = to => n => Math.pow(n, to);
# Python
def pgen(to):
return lambda n : n ** to
# Ruby
def pgen to
lambda { |n| n ** to }
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With