Closed nanotee closed 3 years ago
Some VimScript functions that modify a variable in-place behave differently in Lua, since the conversion creates a copy:
let s:list = [1, 2, 3]
let s:newlist = map(s:list, {_, v -> v * 2})
echo s:list
" [2, 4, 6]
echo s:newlist
" [2, 4, 6]
local tbl = {1, 2, 3}
local newtbl = vim.fn.map(tbl, function(_, v) return v * 2 end)
print(vim.inspect(tbl)) -- { 1, 2, 3 }
print(vim.inspect(newtbl)) -- { 2, 4, 6 }
This may also have performance implications?
Does this include set options like
vim.o.list = true
and in nvim cmdline:
:lua print(vim.o.list)
?
I cant print it, but the set option has an effect (applying listchars).
'list'
is a window-local option, so I don't think the error is related to type conversion, you'd have to use vim.wo.list
Thanks for mentioning this, I was rewriting my fzf
config into lua
and trying to figure out what was wrong was driving me crazy! It's only because of your mention of fzf#wrap
that I found this.
My code right now looks something like this:
local cmd = string.format(
":call fzf#run(fzf#wrap({'source': '%s', 'options': ['--prompt', '%s'], 'dir': '%s'}))",
source,
prompt,
root
)
vim.cmd(cmd)
Is it possible to re-write this into lua and avoid the string interpolation?
For Lua callbacks, there's this trick I learned by reading nvim-lspfuzzy's source code: https://github.com/ojroques/nvim-lspfuzzy/blob/f41f8b03a8eacee578b2b4f14866163538fcfe37/lua/lspfuzzy.lua#L138-L142
I'm surprised your example doesn't work though, it looks as though you're only passing strings to fzf#wrap()
I think that fzf#wrap
returns a function that's then passed to fzf#run
. At least that's my theory.
I re-wrote the function into this:
vim.call("fzf#run", vim.call("fzf#wrap", { source = source, options = { "--prompt", prompt }, dir = root }))
And after I pick a file from the prompt, I get an error:
Error detected while processing function 11[30]..<SNR>35_callback:
line 23:
Vim(call):E718: Funcref required
The output of fzf#wrap itself is a table/dict, and I suspect one of those vim.NIL
values are actually functions:
{
_action = {
["ctrl-t"] = "tab split",
["ctrl-v"] = "vsplit",
["ctrl-x"] = "split"
},
dir = "/home/hugo/.dotfiles",
down = "40%",
options = " '--prompt' 'git> ' --expect=ctrl-v,ctrl-x,ctrl-t",
["sink*"] = vim.NIL,
sinklist = vim.NIL,
source = "git ls-files --cached --modified --others --exclude-standard | uniq"
}
Oh, yeah, that link confirms it: sink
is a function.
fzf#wrap()
does indeed return default functions if no sink
option is passed: https://github.com/junegunn/fzf/blob/a91a67668e0830a8cf9a792c4949e03b4189f097/plugin/fzf.vim#L422-L429
Passing sink = 'edit'
to fzf#wrap()
might fix your problem
Oh, deleting the sink*
and sinklist
keys from the table might work better:
local fzf_wrapped_options = vim.call("fzf#wrap", { source = source, options = { "--prompt", prompt }, dir = root })
fzf_wrapped_options['sink*'] = nil
fzf_wrapped_options.sinklist = nil
vim.call("fzf#run", fzf_wrapped_options)
That worked, thanks!
Ugh, I cheered too soon. It doesn't work. It lets me pick a file but does nothing.
I though it worked because I'd picked the same file and it didn't error. :(
Right, deleting sink*
and sinklist
removes the default action entirely so selecting an item does nothing. Passing sink = 'edit'
to fzf#wrap()
should to the trick since it prevents it from returning a table with vim.NIL
:
vim.cal('fzf#run', vim.call("fzf#wrap", { source = source, options = { "--prompt", prompt }, dir = root, sink = 'edit' }))
(sorry for the confusion, I'm learning about the internals of fzf.vim
as I debug this)
The side from which one does the conversion matters when converting functions:
Bumped into this when I tried to pass a Lua callback to
vim.fn['fzf#wrap']
from the Lua side