2023-02-14 20:14:50 +00:00
|
|
|
use blocking::unblock;
|
2023-02-06 17:59:48 +00:00
|
|
|
use dialoguer::{theme::ColorfulTheme, Confirm, Input, MultiSelect, Select};
|
2023-02-06 05:13:12 +00:00
|
|
|
use mlua::prelude::*;
|
|
|
|
|
2023-02-14 20:14:50 +00:00
|
|
|
use crate::{
|
|
|
|
lua::stdio::{PromptKind, PromptOptions, PromptResult},
|
|
|
|
utils::{
|
|
|
|
formatting::{
|
|
|
|
format_style, pretty_format_multi_value, style_from_color_str, style_from_style_str,
|
|
|
|
},
|
|
|
|
table::TableBuilder,
|
2023-02-06 05:13:12 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2023-02-11 11:39:39 +00:00
|
|
|
pub fn create(lua: &'static Lua) -> LuaResult<LuaTable> {
|
2023-02-10 11:14:28 +00:00
|
|
|
TableBuilder::new(lua)?
|
|
|
|
.with_function("color", |_, color: String| {
|
|
|
|
let ansi_string = format_style(style_from_color_str(&color)?);
|
|
|
|
Ok(ansi_string)
|
|
|
|
})?
|
|
|
|
.with_function("style", |_, style: String| {
|
|
|
|
let ansi_string = format_style(style_from_style_str(&style)?);
|
|
|
|
Ok(ansi_string)
|
|
|
|
})?
|
|
|
|
.with_function("format", |_, args: LuaMultiValue| {
|
|
|
|
pretty_format_multi_value(&args)
|
|
|
|
})?
|
|
|
|
.with_function("write", |_, s: String| {
|
|
|
|
print!("{s}");
|
|
|
|
Ok(())
|
|
|
|
})?
|
|
|
|
.with_function("ewrite", |_, s: String| {
|
|
|
|
eprint!("{s}");
|
|
|
|
Ok(())
|
|
|
|
})?
|
2023-02-14 20:14:50 +00:00
|
|
|
.with_async_function("prompt", |_, options: PromptOptions| {
|
|
|
|
unblock(move || prompt(options))
|
|
|
|
})?
|
2023-02-10 11:14:28 +00:00
|
|
|
.build_readonly()
|
2023-02-06 05:13:12 +00:00
|
|
|
}
|
2023-02-06 17:59:48 +00:00
|
|
|
|
|
|
|
fn prompt_theme() -> ColorfulTheme {
|
|
|
|
ColorfulTheme::default()
|
|
|
|
}
|
|
|
|
|
2023-02-14 20:14:50 +00:00
|
|
|
fn prompt(options: PromptOptions) -> LuaResult<PromptResult> {
|
|
|
|
let theme = prompt_theme();
|
|
|
|
match options.kind {
|
|
|
|
PromptKind::Text => {
|
|
|
|
let input: String = Input::with_theme(&theme)
|
|
|
|
.allow_empty(true)
|
2023-02-16 17:17:56 +00:00
|
|
|
.with_prompt(options.text.unwrap_or_default())
|
|
|
|
.with_initial_text(options.default_string.unwrap_or_default())
|
2023-02-14 20:14:50 +00:00
|
|
|
.interact_text()?;
|
|
|
|
Ok(PromptResult::String(input))
|
|
|
|
}
|
|
|
|
PromptKind::Confirm => {
|
|
|
|
let mut prompt = Confirm::with_theme(&theme);
|
|
|
|
if let Some(b) = options.default_bool {
|
|
|
|
prompt.default(b);
|
2023-02-06 17:59:48 +00:00
|
|
|
};
|
2023-02-14 20:14:50 +00:00
|
|
|
let result = prompt
|
|
|
|
.with_prompt(&options.text.expect("Missing text in prompt options"))
|
|
|
|
.interact()?;
|
|
|
|
Ok(PromptResult::Boolean(result))
|
2023-02-06 17:59:48 +00:00
|
|
|
}
|
2023-02-14 20:14:50 +00:00
|
|
|
PromptKind::Select => {
|
|
|
|
let chosen = Select::with_theme(&prompt_theme())
|
2023-02-16 17:17:56 +00:00
|
|
|
.with_prompt(&options.text.unwrap_or_default())
|
2023-02-14 20:14:50 +00:00
|
|
|
.items(&options.options.expect("Missing options in prompt options"))
|
|
|
|
.interact_opt()?;
|
|
|
|
Ok(match chosen {
|
|
|
|
Some(idx) => PromptResult::Index(idx + 1),
|
|
|
|
None => PromptResult::None,
|
|
|
|
})
|
2023-02-06 17:59:48 +00:00
|
|
|
}
|
2023-02-14 20:14:50 +00:00
|
|
|
PromptKind::MultiSelect => {
|
|
|
|
let chosen = MultiSelect::with_theme(&prompt_theme())
|
2023-02-16 17:17:56 +00:00
|
|
|
.with_prompt(&options.text.unwrap_or_default())
|
2023-02-14 20:14:50 +00:00
|
|
|
.items(&options.options.expect("Missing options in prompt options"))
|
|
|
|
.interact_opt()?;
|
|
|
|
Ok(match chosen {
|
|
|
|
None => PromptResult::None,
|
|
|
|
Some(indices) => {
|
|
|
|
PromptResult::Indices(indices.iter().map(|idx| *idx + 1).collect())
|
2023-02-06 17:59:48 +00:00
|
|
|
}
|
2023-02-14 20:14:50 +00:00
|
|
|
})
|
2023-02-06 17:59:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|