Closed wookayin closed 1 year ago
Actually it's not a bug (the GH issue template does not have that category) -- please feel free to remove the label.
API extensions are something that I'm willing to add (I've already added one for telescope-specific behavior in vim.ui.select), but it's something I still want to be very careful about. Any extensions should
vim.ui.*
implementationsThe telescope extension will never conflict with core (the telescope key is safe because they will never write code in core that depends on a plugin), and gracefully degrades for other implementations. It can conflict with user settings, but it unlocks the ability for callsites to use telescope-specific features (e.g. preview window), which I thought was significant enough upside. Additionally, the API extension is extremely simple: just a single 'telescope' parameter that is passed to telescope directly.
My main concerns about the proposed extensions to vim.ui.input
are the conflicts with user-supplied options and the relatively large addition to the API surface area.
Why do you think it makes sense for the callsite to be able to override layout and styling options set by the user? What is your specific use case?
Thank you @stevearc for detailed explanation. I totally agree with your rationale to make it as compatible and as same as the built-in vim.ui functions, and they make lots of sense to me.
I was trying to use some dynamic, or semi-dynamic way of configuring those UI attributes so that I can have different layouts, width, position, etc. for different use cases. Some input dialogs are better with relative = cursor
(e.g. entering some buffer- or window-local variables) and others are better with relative = editor
(e.g. entering some global values), for instance.
Actually this is already possible through get_config
, mentioned in README: :help dressing_get_config
.
dressing.setup {
input = {
relative = 'editor', -- default
get_config = function(opts)
-- opts: the lua table passed to vim.ui.input(opts, ...)
-- returns a specific configuration to override with
if opts.kind == 'codeaction':
return { relative = 'cursor' }
end
return {}
end
}
}
So this is already more than enough because I can use different kind
(or any other field) to tell where vim.ui.input
was called from.
Indeed, one could take advantage of this feature to implement more dynamic, per-instance configuration overriding if they would really want it. It's kind of a hack (at users' own risk), but officially the plugin itself does not support dynamic options against potential discrepancy with the original behavior. For instance,
dressing.setup {
input = {
width = 40, -- default
relative = 'editor', -- default
get_config = function(opts)
-- Just a demonstration: allow overriding `width` and `relative` only
local extra_opts = {}
if opts.width ~= nil then extra_opts.width = opts.width end
if opts.relative ~= nil then extra_opts.relative = opts.relative end
return extra_opts
end
}
}
With such a config, we can do something like:
local on_confirm = function(x) vim.notify(vim.inspect(x)) end
vim.ui.input({ default_prompt = "Enter >", width = 100, relative = 'cursor' }, on_confirm)
I didn't think to do that, but you're right the get_config
can be modified to do your own customizations. I think the only thing standing in the way of making this a feature instead of a hack is that officially (in the Neovim docs) vim.ui.input
does not support/mention the use of a kind
option the way vim.ui.select
does.
Thanks for this, @wookayin ! I was trying to have a customized input for creating notes and needed the example of using get_config to sort it out. Wouldn't have figured it out without this issue.
@wookayin I generalised your idea and with
require("dressing").setup({
...
input = {
win_options = {
sidescrolloff = 4,
},
get_config = function(extra_opts)
local opts = require("dressing.config").input
return vim.tbl_deep_extend("force", opts, extra_opts or {})
end,
},
...
select = {
get_config = function(extra_opts)
local opts = require("dressing.config").select
return vim.tbl_deep_extend("force", opts, extra_opts or {})
end,
}
})
it's possible to fully customise the config from the call side. I am well aware that this is dangerous and might lead to breaking things when it clashes with newly introduced parameters to the Neovim API, but I think it's fine to To This At Your Own Risk, kind of thing! Thanks for the initial idea!
We can configure many options for
vim.ui.input
viadressing.setup { input = ... }
, but this applies globally only and there seems no way to override with per-instance options at this moment. For example, one may want to make thevim.ui.input
window have a different size, different position (relative) just temporarily.I tried something like
but most of the options other than
prompt
,default
, etc. (as per the "standard" spec ofvim.ui.input()
) do not work. Although those options would work only when dressing.nvim is used, but I think it's perfectly fine to have theopts
table contains some specific and optional arguments.