This commit is contained in:
sxyazi 2023-11-04 06:30:24 +08:00
parent bcefbfd990
commit 510884287b
No known key found for this signature in database
4 changed files with 45 additions and 13 deletions

View file

@ -8,10 +8,6 @@ impl From<&Exec> for Opt {
fn from(e: &Exec) -> Self { Self(e.named.contains_key("submit")) }
}
impl From<bool> for Opt {
fn from(b: bool) -> Self { Self(b) }
}
impl Completion {
pub fn close(&mut self, opt: impl Into<Opt>) -> bool {
let submit = opt.into().0;
@ -22,7 +18,7 @@ impl Completion {
));
}
self.cursor = 0;
self.caches.clear();
self.visible = false;
true
}

View file

@ -46,7 +46,6 @@ impl Completion {
ControlFlow::Continue(v)
});
self.close(false);
self.cands = match flow {
ControlFlow::Continue(v) => v,
ControlFlow::Break(v) => v,
@ -54,6 +53,8 @@ impl Completion {
self.ticket = opt.ticket;
if !self.cands.is_empty() {
self.offset = 0;
self.cursor = 0;
self.visible = true;
}
true

View file

@ -1,3 +1,5 @@
use std::mem;
use tokio::fs;
use yazi_config::keymap::{Exec, KeymapLayer};
@ -18,17 +20,24 @@ impl<'a> From<&'a Exec> for Opt<'a> {
}
impl Completion {
#[inline]
fn split_path(s: &str) -> (String, String) {
match s.rsplit_once(|c| c == '/' || c == '\\') {
Some((p, c)) => (format!("{p}/"), c.to_owned()),
None => (".".to_owned(), s.to_owned()),
}
}
pub fn trigger<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool {
let opt = opt.into();
if self.ticket >= opt.ticket {
if opt.ticket < self.ticket {
return false;
}
self.close(false);
self.ticket = opt.ticket;
let (parent, child) = Self::split_path(opt.before);
let (parent, child) = opt.before.rsplit_once('/').unwrap_or((".", opt.before));
if self.caches.contains_key(parent) {
if self.caches.contains_key(&parent) {
return self.show(
&Exec::call("show", vec![])
.with("cache-name", parent)
@ -38,7 +47,6 @@ impl Completion {
}
let ticket = self.ticket;
let (parent, child) = (parent.to_owned(), child.to_owned());
tokio::spawn(async move {
let mut dir = fs::read_dir(&parent).await?;
let mut cache = Vec::new();
@ -70,6 +78,33 @@ impl Completion {
Ok::<(), anyhow::Error>(())
});
false
mem::replace(&mut self.visible, false)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_explode() {
assert_eq!(Completion::split_path(""), (".".to_owned(), "".to_owned()));
assert_eq!(Completion::split_path(" "), (".".to_owned(), " ".to_owned()));
assert_eq!(Completion::split_path("/"), ("/".to_owned(), "".to_owned()));
assert_eq!(Completion::split_path("//"), ("//".to_owned(), "".to_owned()));
assert_eq!(Completion::split_path("/foo"), ("/".to_owned(), "foo".to_owned()));
assert_eq!(Completion::split_path("/foo/"), ("/foo/".to_owned(), "".to_owned()));
assert_eq!(Completion::split_path("/foo/bar"), ("/foo/".to_owned(), "bar".to_owned()));
// Windows
assert_eq!(Completion::split_path("foo"), (".".to_owned(), "foo".to_owned()));
assert_eq!(Completion::split_path("foo\\"), ("foo/".to_owned(), "".to_owned()));
assert_eq!(Completion::split_path("foo\\bar"), ("foo/".to_owned(), "bar".to_owned()));
assert_eq!(Completion::split_path("foo\\bar\\"), ("foo\\bar/".to_owned(), "".to_owned()));
assert_eq!(Completion::split_path("C:\\"), ("C:/".to_owned(), "".to_owned()));
assert_eq!(Completion::split_path("C:\\foo"), ("C:/".to_owned(), "foo".to_owned()));
assert_eq!(Completion::split_path("C:\\foo\\"), ("C:\\foo/".to_owned(), "".to_owned()));
assert_eq!(Completion::split_path("C:\\foo\\bar"), ("C:\\foo/".to_owned(), "bar".to_owned()));
}
}

View file

@ -11,7 +11,7 @@ impl<'a> From<&'a Exec> for Opt<'a> {
fn from(e: &'a Exec) -> Self {
Self {
word: e.args.first().map(|w| w.as_str()).unwrap_or_default(),
ticket: e.named.get("ticket").and_then(|v| v.parse().ok()).unwrap_or(0),
ticket: e.named.get("ticket").and_then(|s| s.parse().ok()).unwrap_or(0),
}
}
}