Skip to content

Commit

Permalink
Refactor the open command
Browse files Browse the repository at this point in the history
  • Loading branch information
sxyazi committed Feb 14, 2024
1 parent 45ac509 commit 182e224
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 28 deletions.
2 changes: 1 addition & 1 deletion cspell.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":"0.2","language":"en","flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank"]}
{"version":"0.2","language":"en","flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","mimetypes"]}
2 changes: 1 addition & 1 deletion yazi-core/src/folder/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
58 changes: 42 additions & 16 deletions yazi-core/src/manager/commands/open.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand All @@ -23,21 +23,21 @@ 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) {
return;
}

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());
}
}

Expand All @@ -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}");
}

Expand All @@ -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
Expand All @@ -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() {
Expand All @@ -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
});
Expand Down
6 changes: 1 addition & 5 deletions yazi-core/src/manager/commands/peek.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
3 changes: 3 additions & 0 deletions yazi-core/src/manager/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() }
}
5 changes: 5 additions & 0 deletions yazi-core/src/tab/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
5 changes: 1 addition & 4 deletions yazi-fm/src/lives/preview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
2 changes: 1 addition & 1 deletion yazi-fm/src/lives/selected.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()))
}
}

0 comments on commit 182e224

Please sign in to comment.