And I'm wondering what's v
in this context? v:false
, v:true
, {_, v ->
, and fnamemodify(v,
?
There are two separate instances of v
here and they mean two different things.
Vim variables under the v:
namespace
Vim has a list of special variables under the v:
namespace. Note that v:
is fixed here. Variables here include v:argv
(the arguments passed to the vim
command), v:version
with a simple version number, and v:val
which can be used in map()
or filter()
expressions to refer to the current item in the iteration.
Vim also includes constants here and v:true
and v:false
are examples here. These are constants that evaluate to the values in the boolean type. Older versions of Vim didn't have a boolean type and used 1 and 0 to indicate true or false (numeric values actually still work everywhere.) When a boolean type was introduced, the values were added to the v:
namespace to prevent conflicts with any previous usage of those names.
See :help vim-variable
for a comprehensive list of the v:
variables.
Argument name in a lambda expression
The {_, v ->
syntax starts a lambda expression, which is a way to define a function on the spot, using very short syntax. It's typically used together with map()
and filter()
since they take function arguments.
The part before the ->
lists the arguments taken by the lambda. Since map()
iterates over a Dict, you might want to use something like {key, value -> ...}
since that's what the lambda function gets when it's called.
But since the key
argument is not really used anywhere, you can just call it _
, which is a useful placeholder for an argument you need to receive but will not be using.
If you were to use a lambda {key, value -> ...}
(or even {_, value -> ...}
), you would refer to the second argument as value
, so you'd use fnamemodify(value, ':t:r')
and so on. But since the point of a lambda is brevity, it makes sense to shorten it to just v
, especially since you need to repeat that at least twice and in this case three times.
The lambda expression is just an unnamed function. If you wanted to, you could have written a function instead:
function! FormatLink(key, value)
return printf('[%s](%s)',
\ fnamemodify(a:value, ':t:r')->substitute('^string_', '', ''),
\ fnamemodify(a:value, ':t'))
endfunction
Notice that in a function I'm referring to those by a:value
, another advantage of lambda expressions is that you don't need to use the a:
prefix for an argument.
I also had to modify the example slightly, since I didn't have access to a:strip
from the other function. Which shows one advantage of lambda in that they create a closure inside the function where they're called (which means you can access that function's arguments and local variables.) You'd have to pass them as additional arguments to a named function, which is not always possible (such as in the case of using one in map()
.)
To use this function with a map()
, you would need to use ->map(function('FormatLink'))
, which shows yet another advantage of lambdas in that you can use them directly as a Funcref, while for a named function you need to wrap it in function()
and refer to its name by a string.
See :help map()
, which has some more useful examples including lambdas and more pointers if you're interested.