mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
98 lines
2.3 KiB
Rust
98 lines
2.3 KiB
Rust
use std::time::Duration;
|
|
|
|
use tokio::pin;
|
|
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
|
|
use yazi_config::popup::InputCfg;
|
|
use yazi_shared::{emit, event::Cmd, render, Debounce, InputError, Layer};
|
|
|
|
use crate::{folder::FilterCase, input::Input, tab::{Finder, Tab}};
|
|
|
|
pub struct Opt {
|
|
query: Option<String>,
|
|
prev: bool,
|
|
case: FilterCase,
|
|
}
|
|
|
|
impl From<Cmd> for Opt {
|
|
fn from(mut c: Cmd) -> Self {
|
|
Self {
|
|
query: c.take_first(),
|
|
prev: c.named.contains_key("previous"),
|
|
case: FilterCase::from(&c),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct ArrowOpt {
|
|
prev: bool,
|
|
}
|
|
|
|
impl From<Cmd> for ArrowOpt {
|
|
fn from(c: Cmd) -> Self { Self { prev: c.named.contains_key("previous") } }
|
|
}
|
|
|
|
impl Tab {
|
|
pub fn find(&mut self, opt: impl Into<Opt>) {
|
|
let opt = opt.into() as Opt;
|
|
tokio::spawn(async move {
|
|
let rx = Input::_show(InputCfg::find(opt.prev));
|
|
|
|
let rx = Debounce::new(UnboundedReceiverStream::new(rx), Duration::from_millis(50));
|
|
pin!(rx);
|
|
|
|
while let Some(Ok(s)) | Some(Err(InputError::Typed(s))) = rx.next().await {
|
|
emit!(Call(
|
|
Cmd::args("find_do", vec![s])
|
|
.with_bool("previous", opt.prev)
|
|
.with_bool("smart", opt.case == FilterCase::Smart)
|
|
.with_bool("insensitive", opt.case == FilterCase::Insensitive),
|
|
Layer::Manager
|
|
));
|
|
}
|
|
});
|
|
}
|
|
|
|
pub fn find_do(&mut self, opt: impl Into<Opt>) {
|
|
let opt = opt.into() as Opt;
|
|
let Some(query) = opt.query else {
|
|
return;
|
|
};
|
|
if query.is_empty() {
|
|
self.escape_find();
|
|
return;
|
|
}
|
|
|
|
let Ok(finder) = Finder::new(&query, opt.case) else {
|
|
return;
|
|
};
|
|
if matches!(&self.finder, Some(f) if f.filter == finder.filter) {
|
|
return;
|
|
}
|
|
|
|
let step = if opt.prev {
|
|
finder.prev(&self.current.files, self.current.cursor, true)
|
|
} else {
|
|
finder.next(&self.current.files, self.current.cursor, true)
|
|
};
|
|
|
|
if let Some(step) = step {
|
|
self.arrow(step);
|
|
}
|
|
|
|
self.finder = Some(finder);
|
|
render!();
|
|
}
|
|
|
|
pub fn find_arrow(&mut self, opt: impl Into<ArrowOpt>) {
|
|
let Some(finder) = &mut self.finder else {
|
|
return;
|
|
};
|
|
|
|
render!(finder.catchup(&self.current.files));
|
|
if opt.into().prev {
|
|
finder.prev(&self.current.files, self.current.cursor, false).map(|s| self.arrow(s));
|
|
} else {
|
|
finder.next(&self.current.files, self.current.cursor, false).map(|s| self.arrow(s));
|
|
}
|
|
}
|
|
}
|