62 lines
1.7 KiB
Rust
62 lines
1.7 KiB
Rust
use skim::prelude::*;
|
|
|
|
use crate::{
|
|
ssh_config::{SshItem, SshItems},
|
|
state::State,
|
|
};
|
|
|
|
pub struct UserFuzzyFind {}
|
|
|
|
impl UserFuzzyFind {
|
|
pub async fn get_ssh_item_from_user<'a>(
|
|
&self,
|
|
items: &'a SshItems,
|
|
) -> anyhow::Result<&'a SshItem> {
|
|
let skim_options = SkimOptionsBuilder::default()
|
|
.no_multi(true)
|
|
.build()
|
|
.expect("failed to build skim config");
|
|
|
|
let (tx, rx): (SkimItemSender, SkimItemReceiver) = skim::prelude::unbounded();
|
|
|
|
for item in items.to_vec().into_iter().cloned() {
|
|
tx.send(Arc::new(item))
|
|
.expect("we should never have enough items that we exceed unbounded");
|
|
}
|
|
|
|
let chosen_items = Skim::run_with(&skim_options, Some(rx))
|
|
.and_then(|output| if output.is_abort { None } else { Some(output) })
|
|
.map(|item| item.selected_items)
|
|
.ok_or(anyhow::anyhow!("failed to find an ssh item"))?;
|
|
|
|
let chosen_item = chosen_items
|
|
.first()
|
|
.expect("there should never be more than 1 skip item");
|
|
|
|
let output = chosen_item.output();
|
|
|
|
let chosen_ssh_item = items
|
|
.get_choice(&output) // Cow, str, String
|
|
.expect("always find an ssh item from a choice");
|
|
tracing::debug!("the user chose item: {chosen_ssh_item:#?}");
|
|
|
|
Ok(chosen_ssh_item)
|
|
}
|
|
}
|
|
|
|
pub trait UserFuzzyFindState {
|
|
fn user_fuzzy_find(&self) -> UserFuzzyFind;
|
|
}
|
|
|
|
impl UserFuzzyFindState for State {
|
|
fn user_fuzzy_find(&self) -> UserFuzzyFind {
|
|
UserFuzzyFind {}
|
|
}
|
|
}
|
|
|
|
impl SkimItem for SshItem {
|
|
fn text(&'_ self) -> std::borrow::Cow<'_, str> {
|
|
format!("{self}").into()
|
|
}
|
|
}
|