mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
Refactor the open command
This commit is contained in:
parent
9fe0c1bdb7
commit
9788e53f5c
7 changed files with 54 additions and 27 deletions
|
|
@ -317,7 +317,7 @@ impl Files {
|
|||
impl Files {
|
||||
// --- Items
|
||||
#[inline]
|
||||
pub fn position(&self, url: &Url) -> Option<usize> { self.iter().position(|f| &f.url == url) }
|
||||
pub fn position(&self, url: &Url) -> Option<usize> { self.iter().position(|f| f.url == *url) }
|
||||
|
||||
// --- Ticket
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ use yazi_config::{popup::SelectCfg, ARGS, OPEN};
|
|||
use yazi_plugin::isolate;
|
||||
use yazi_shared::{emit, event::{Cmd, EventQuit}, fs::{File, Url}, Layer, MIME_DIR};
|
||||
|
||||
use crate::{manager::Manager, select::Select, tasks::Tasks};
|
||||
use crate::{folder::Folder, manager::Manager, select::Select, tasks::Tasks};
|
||||
|
||||
pub struct Opt {
|
||||
targets: Vec<(Url, Option<String>)>,
|
||||
targets: Vec<(Url, String)>,
|
||||
interactive: bool,
|
||||
}
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ impl From<Cmd> for Opt {
|
|||
|
||||
impl Manager {
|
||||
pub fn open(&mut self, opt: impl Into<Opt>, tasks: &Tasks) {
|
||||
let selected = self.selected();
|
||||
let selected = self.selected_or_hovered();
|
||||
if selected.is_empty() {
|
||||
return;
|
||||
} else if Self::quit_with_selected(&selected) {
|
||||
|
|
@ -31,13 +31,13 @@ impl Manager {
|
|||
}
|
||||
|
||||
let (mut done, mut todo) = (Vec::with_capacity(selected.len()), vec![]);
|
||||
for f in selected {
|
||||
if f.is_dir() {
|
||||
done.push((f.url(), Some(MIME_DIR.to_owned())));
|
||||
} else if self.mimetype.get(&f.url).is_some() {
|
||||
done.push((f.url(), None));
|
||||
for u in selected {
|
||||
if self.mimetype.get(u).is_some() {
|
||||
done.push((u.clone(), String::new()));
|
||||
} else if self.guess_its_folder(u) {
|
||||
done.push((u.clone(), MIME_DIR.to_owned()));
|
||||
} else {
|
||||
todo.push(f.clone());
|
||||
todo.push(u.clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -48,8 +48,15 @@ impl Manager {
|
|||
}
|
||||
|
||||
tokio::spawn(async move {
|
||||
done.extend(todo.iter().map(|f| (f.url(), None)));
|
||||
if let Err(e) = isolate::preload("mime", todo, true).await {
|
||||
let mut files = Vec::with_capacity(todo.len());
|
||||
for u in todo {
|
||||
if let Ok(f) = File::from(u).await {
|
||||
files.push(f);
|
||||
}
|
||||
}
|
||||
|
||||
done.extend(files.iter().map(|f| (f.url(), String::new())));
|
||||
if let Err(e) = isolate::preload("mime", files, true).await {
|
||||
error!("preload in watcher failed: {e}");
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +65,7 @@ impl Manager {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn _open_do(interactive: bool, targets: Vec<(Url, Option<String>)>) {
|
||||
pub fn _open_do(interactive: bool, targets: Vec<(Url, String)>) {
|
||||
emit!(Call(
|
||||
Cmd::new("open_do").with_bool("interactive", interactive).with_data(targets),
|
||||
Layer::Manager
|
||||
|
|
@ -74,7 +81,9 @@ impl Manager {
|
|||
let targets: Vec<_> = opt
|
||||
.targets
|
||||
.into_iter()
|
||||
.filter_map(|(u, m)| m.or_else(|| self.mimetype.get(&u).cloned()).map(|m| (u, m)))
|
||||
.filter_map(|(u, m)| {
|
||||
Some(m).filter(|m| !m.is_empty()).or_else(|| self.mimetype.get(&u).cloned()).map(|m| (u, m))
|
||||
})
|
||||
.collect();
|
||||
|
||||
if targets.is_empty() {
|
||||
|
|
@ -98,13 +107,30 @@ impl Manager {
|
|||
});
|
||||
}
|
||||
|
||||
fn quit_with_selected(selected: &[&File]) -> bool {
|
||||
fn guess_its_folder(&self, url: &Url) -> bool {
|
||||
let Some(p) = url.parent_url() else {
|
||||
return true;
|
||||
};
|
||||
|
||||
let find = |folder: Option<&Folder>| {
|
||||
folder.is_some_and(|folder| {
|
||||
folder.cwd == p && folder.files.iter().any(|f| f.is_dir() && f.url == *url)
|
||||
})
|
||||
};
|
||||
|
||||
find(Some(self.current()))
|
||||
|| find(self.parent())
|
||||
|| find(self.hovered_folder())
|
||||
|| find(self.active().history.get(&p))
|
||||
}
|
||||
|
||||
fn quit_with_selected(selected: &[&Url]) -> bool {
|
||||
if ARGS.chooser_file.is_none() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let paths = selected.iter().fold(OsString::new(), |mut s, &f| {
|
||||
s.push(f.url.as_os_str());
|
||||
let paths = selected.iter().fold(OsString::new(), |mut s, &u| {
|
||||
s.push(u.as_os_str());
|
||||
s.push("\n");
|
||||
s
|
||||
});
|
||||
|
|
|
|||
|
|
@ -35,11 +35,7 @@ impl Manager {
|
|||
return render!(self.active_mut().preview.reset());
|
||||
};
|
||||
|
||||
let folder = Some(())
|
||||
.filter(|_| hovered.is_dir())
|
||||
.and_then(|_| self.active().history.get(&hovered.url))
|
||||
.map(|f| (f.offset, f.mtime));
|
||||
|
||||
let folder = self.active().hovered_folder().map(|f| (f.offset, f.mtime));
|
||||
if !self.active().preview.same_url(&hovered.url) {
|
||||
self.active_mut().preview.skip = folder.map(|f| f.0).unwrap_or_default();
|
||||
render!(self.active_mut().preview.reset());
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@ impl Manager {
|
|||
#[inline]
|
||||
pub fn hovered(&self) -> Option<&File> { self.tabs.active().current.hovered() }
|
||||
|
||||
#[inline]
|
||||
pub fn hovered_folder(&self) -> Option<&Folder> { self.tabs.active().hovered_folder() }
|
||||
|
||||
#[inline]
|
||||
pub fn selected_or_hovered(&self) -> Vec<&Url> { self.tabs.active().selected_or_hovered() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,11 @@ impl Tab {
|
|||
self.history.remove(url).unwrap_or_else(|| Folder::from(url))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hovered_folder(&self) -> Option<&Folder> {
|
||||
self.current.hovered().filter(|&h| h.is_dir()).and_then(|h| self.history.get(&h.url))
|
||||
}
|
||||
|
||||
pub fn apply_files_attrs(&mut self) {
|
||||
let apply = |f: &mut Folder| {
|
||||
if f.stage == FolderStage::Loading {
|
||||
|
|
|
|||
|
|
@ -26,10 +26,7 @@ impl Preview {
|
|||
reg.add_field_method_get("skip", |_, me| Ok(me.skip));
|
||||
reg.add_field_method_get("folder", |_, me| {
|
||||
me.tab()
|
||||
.current
|
||||
.hovered()
|
||||
.filter(|&f| f.is_dir())
|
||||
.and_then(|f| me.tab().history.get(&f.url))
|
||||
.hovered_folder()
|
||||
.map(|f| {
|
||||
let limit = LAYOUT.load().preview.height as usize;
|
||||
Folder::make(Some(me.skip..f.files.len().min(me.skip + limit)), f, me.tab())
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ struct SelectedIter(btree_set::Iter<'static, yazi_shared::fs::Url>);
|
|||
|
||||
impl SelectedIter {
|
||||
#[inline]
|
||||
fn make(selected: &BTreeSet<yazi_shared::fs::Url>) -> mlua::Result<AnyUserData<'static>> {
|
||||
fn make(selected: &'static BTreeSet<yazi_shared::fs::Url>) -> mlua::Result<AnyUserData<'static>> {
|
||||
SCOPE.create_any_userdata(Self(selected.iter()))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue