ytil_noxi/
vim_ui_select.rs1use core::fmt::Debug;
4use core::fmt::Display;
5use std::rc::Rc;
6
7use color_eyre::eyre::eyre;
8use nvim_oxi::mlua;
9use nvim_oxi::mlua::IntoLua;
10use nvim_oxi::mlua::ObjectLike;
11
12pub struct QuickfixConfig {
18 pub trigger_value: String,
20 pub all_items: Vec<(String, i64)>,
22}
23
24pub fn open<C, K, V>(
36 choices: impl IntoIterator<Item = C> + Debug,
37 opts: &(impl IntoIterator<Item = (K, V)> + Debug + Clone),
38 callback: impl Fn(usize) + 'static,
39 maybe_quickfix: Option<QuickfixConfig>,
40) -> color_eyre::Result<()>
41where
42 C: Display,
43 K: IntoLua,
44 V: IntoLua,
45{
46 let lua = mlua::lua();
47
48 let vim_ui_select = lua
49 .globals()
50 .get_path::<mlua::Function>("vim.ui.select")
51 .map_err(|err| eyre!("cannot fetch vim.ui.select function from Lua globals | error={err:#?}"))?;
52
53 let opts_table = lua
54 .create_table_from(opts.clone())
55 .map_err(|err| eyre!("cannot create opts table | opts={opts:#?} error={err:#?}"))?;
56
57 let quickfix = maybe_quickfix.map(Rc::new);
58
59 let vim_ui_select_callback = lua
60 .create_function(
61 move |_: &mlua::Lua, (selected_value, idx): (Option<String>, Option<usize>)| {
62 if let Some(quickfix) = &quickfix
63 && selected_value.is_some_and(|x| x == quickfix.trigger_value)
64 {
65 let _ = crate::quickfix::open(quickfix.all_items.iter().map(|(s, i)| (s.as_str(), *i)))
66 .inspect_err(|err| {
67 crate::notify::error(format!("error opening quickfix | error={err:#?}"));
68 });
69 return Ok(());
70 }
71 if let Some(idx) = idx {
72 callback(idx.saturating_sub(1));
73 }
74 Ok(())
75 },
76 )
77 .map_err(|err| {
78 eyre!("cannot create vim.ui.select callback | choices={choices:#?} opts={opts_table:#?} error={err:#?}")
79 })?;
80
81 let vim_ui_choices = choices.into_iter().map(|c| c.to_string()).collect::<Vec<_>>();
82
83 vim_ui_select
84 .call::<()>((vim_ui_choices.clone(), opts_table.clone(), vim_ui_select_callback))
85 .map_err(|err| {
86 eyre!("cannot call vim.ui.select | choices={vim_ui_choices:#?} opts={opts_table:#?} error={err:#?}")
87 })?;
88
89 Ok(())
90}