mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: make folder openable
This commit is contained in:
parent
e2a4894111
commit
a42da833fe
6 changed files with 47 additions and 36 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
|
@ -1502,18 +1502,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.175"
|
version = "1.0.176"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b"
|
checksum = "76dc28c9523c5d70816e393136b86d48909cfb27cecaa902d338c19ed47164dc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.175"
|
version = "1.0.176"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b23f7ade6f110613c0d63858ddb8b94c1041f550eab58a16b371bdf2c9c80ab4"
|
checksum = "a4e7b8c5dc823e3b90651ff1d3808419cd14e5ad76de04feaf37da114e7a306f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -1522,9 +1522,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.103"
|
version = "1.0.104"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b"
|
checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,15 @@ max_width = 600
|
||||||
max_height = 900
|
max_height = 900
|
||||||
|
|
||||||
[opener]
|
[opener]
|
||||||
|
folder = [
|
||||||
|
{ cmd = "open", args = [ "-R", "$*" ] },
|
||||||
|
{ cmd = "code", args = [ "$*" ] },
|
||||||
|
]
|
||||||
archive = [
|
archive = [
|
||||||
{ cmd = "unar", args = [ "$1" ] },
|
{ cmd = "unar", args = [ "$1" ] },
|
||||||
]
|
]
|
||||||
text = [
|
text = [
|
||||||
{ cmd = "vi", args = [ "$*" ], block = true },
|
{ cmd = "vim", args = [ "$*" ], block = true },
|
||||||
]
|
]
|
||||||
image = [
|
image = [
|
||||||
{ cmd = "open", args = [ "$*" ] },
|
{ cmd = "open", args = [ "$*" ] },
|
||||||
|
|
@ -29,10 +33,12 @@ audio = [
|
||||||
]
|
]
|
||||||
fallback = [
|
fallback = [
|
||||||
{ cmd = "open", args = [ "$*" ] },
|
{ cmd = "open", args = [ "$*" ] },
|
||||||
|
{ cmd = "open", args = [ "-R", "$*" ] },
|
||||||
]
|
]
|
||||||
|
|
||||||
[open]
|
[open]
|
||||||
rules = [
|
rules = [
|
||||||
|
{ name = "*/", use = "folder" },
|
||||||
{ name = "*.html", use = "fallback" },
|
{ name = "*.html", use = "fallback" },
|
||||||
|
|
||||||
{ mime = "text/*", use = "text" },
|
{ mime = "text/*", use = "text" },
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::{collections::{BTreeMap, BTreeSet}, path::Path};
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
|
|
||||||
use super::Opener;
|
use super::Opener;
|
||||||
use crate::config::{Pattern, MERGED_YAZI};
|
use crate::{config::{Pattern, MERGED_YAZI}, misc::MIME_DIR};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Open {
|
pub struct Open {
|
||||||
|
|
@ -22,9 +22,13 @@ struct OpenRule {
|
||||||
impl Open {
|
impl Open {
|
||||||
pub fn new() -> Self { toml::from_str(&MERGED_YAZI).unwrap() }
|
pub fn new() -> Self { toml::from_str(&MERGED_YAZI).unwrap() }
|
||||||
|
|
||||||
pub fn openers(&self, path: impl AsRef<Path>, mime: impl AsRef<str>) -> Option<Vec<&Opener>> {
|
pub fn openers<P, M>(&self, path: P, mime: M) -> Option<Vec<&Opener>>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
M: AsRef<str>,
|
||||||
|
{
|
||||||
self.rules.iter().find_map(|rule| {
|
self.rules.iter().find_map(|rule| {
|
||||||
if rule.name.as_ref().map_or(false, |e| e.match_path(&path, Some(false)))
|
if rule.name.as_ref().map_or(false, |e| e.match_path(&path, Some(mime.as_ref() == MIME_DIR)))
|
||||||
|| rule.mime.as_ref().map_or(false, |m| m.matches(&mime))
|
|| rule.mime.as_ref().map_or(false, |m| m.matches(&mime))
|
||||||
{
|
{
|
||||||
self.openers.get(&rule.use_).map(|v| v.iter().collect())
|
self.openers.get(&rule.use_).map(|v| v.iter().collect())
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::{collections::{BTreeMap, BTreeSet, HashMap, HashSet}, env, mem, path::P
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
|
|
||||||
use super::{PreviewData, Tab, Tabs, Watcher};
|
use super::{PreviewData, Tab, Tabs, Watcher};
|
||||||
use crate::{config::OPEN, core::{external, files::{File, FilesOp}, input::InputOpt, manager::Folder, select::SelectOpt, tasks::Tasks, Position}, emit};
|
use crate::{config::OPEN, core::{external, files::{File, FilesOp}, input::InputOpt, manager::Folder, select::SelectOpt, tasks::Tasks, Position}, emit, misc::MIME_DIR};
|
||||||
|
|
||||||
pub struct Manager {
|
pub struct Manager {
|
||||||
tabs: Tabs,
|
tabs: Tabs,
|
||||||
|
|
@ -56,7 +56,7 @@ impl Manager {
|
||||||
};
|
};
|
||||||
|
|
||||||
if hovered.meta.is_dir() {
|
if hovered.meta.is_dir() {
|
||||||
self.active_mut().preview.go(&hovered.path, "inode/directory");
|
self.active_mut().preview.go(&hovered.path, MIME_DIR);
|
||||||
if self.active().history(&hovered.path).is_some() {
|
if self.active().history(&hovered.path).is_some() {
|
||||||
emit!(Preview(hovered.path, PreviewData::Folder));
|
emit!(Preview(hovered.path, PreviewData::Folder));
|
||||||
}
|
}
|
||||||
|
|
@ -95,10 +95,9 @@ impl Manager {
|
||||||
title: format!("There are {} tasks running, sure to quit? (y/N)", tasks),
|
title: format!("There are {} tasks running, sure to quit? (y/N)", tasks),
|
||||||
value: "".to_string(),
|
value: "".to_string(),
|
||||||
position: Position::Top,
|
position: Position::Top,
|
||||||
}))
|
}));
|
||||||
.await;
|
|
||||||
|
|
||||||
if let Ok(choice) = result {
|
if let Ok(choice) = result.await {
|
||||||
if choice.to_lowercase() == "y" {
|
if choice.to_lowercase() == "y" {
|
||||||
emit!(Quit);
|
emit!(Quit);
|
||||||
}
|
}
|
||||||
|
|
@ -115,15 +114,19 @@ impl Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open(&mut self, interactive: bool) -> bool {
|
pub fn open(&mut self, interactive: bool) -> bool {
|
||||||
let files = self.selected();
|
let mut files = self
|
||||||
if files.len() == 1 && files[0].meta.is_dir() {
|
.selected()
|
||||||
return self.active_mut().enter();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut files = files
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|f| f.meta.is_file())
|
.map(|f| {
|
||||||
.map(|f| (f.path(), self.mimetype.get(&f.path).cloned()))
|
(
|
||||||
|
f.path(),
|
||||||
|
if f.meta.is_dir() {
|
||||||
|
Some(MIME_DIR.to_owned())
|
||||||
|
} else {
|
||||||
|
self.mimetype.get(&f.path).cloned()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if files.is_empty() {
|
if files.is_empty() {
|
||||||
|
|
@ -157,9 +160,8 @@ impl Manager {
|
||||||
title: "Open with:".to_string(),
|
title: "Open with:".to_string(),
|
||||||
items: openers.iter().map(|o| o.cmd.clone()).collect(),
|
items: openers.iter().map(|o| o.cmd.clone()).collect(),
|
||||||
position: Position::Hovered,
|
position: Position::Hovered,
|
||||||
}))
|
}));
|
||||||
.await;
|
if let Ok(choice) = result.await {
|
||||||
if let Ok(choice) = result {
|
|
||||||
emit!(Open(files, Some(openers[choice].clone())));
|
emit!(Open(files, Some(openers[choice].clone())));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -173,10 +175,9 @@ impl Manager {
|
||||||
title: "Create:".to_string(),
|
title: "Create:".to_string(),
|
||||||
value: "".to_string(),
|
value: "".to_string(),
|
||||||
position: Position::Top,
|
position: Position::Top,
|
||||||
}))
|
}));
|
||||||
.await;
|
|
||||||
|
|
||||||
if let Ok(name) = result {
|
if let Ok(name) = result.await {
|
||||||
let path = cwd.join(&name);
|
let path = cwd.join(&name);
|
||||||
if name.ends_with('/') {
|
if name.ends_with('/') {
|
||||||
fs::create_dir_all(path).await.ok();
|
fs::create_dir_all(path).await.ok();
|
||||||
|
|
@ -205,10 +206,9 @@ impl Manager {
|
||||||
title: "Rename:".to_string(),
|
title: "Rename:".to_string(),
|
||||||
value: hovered.file_name().unwrap().to_string_lossy().to_string(),
|
value: hovered.file_name().unwrap().to_string_lossy().to_string(),
|
||||||
position: Position::Hovered,
|
position: Position::Hovered,
|
||||||
}))
|
}));
|
||||||
.await;
|
|
||||||
|
|
||||||
if let Ok(new) = result {
|
if let Ok(new) = result.await {
|
||||||
let to = hovered.parent().unwrap().join(new);
|
let to = hovered.parent().unwrap().join(new);
|
||||||
fs::rename(&hovered, to).await.ok();
|
fs::rename(&hovered, to).await.ok();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,10 +161,9 @@ impl Tasks {
|
||||||
title: "Are you sure delete these files? (y/N)".to_string(),
|
title: "Are you sure delete these files? (y/N)".to_string(),
|
||||||
value: "".to_string(),
|
value: "".to_string(),
|
||||||
position: Position::Hovered,
|
position: Position::Hovered,
|
||||||
}))
|
}));
|
||||||
.await;
|
|
||||||
|
|
||||||
if let Ok(choice) = result {
|
if let Ok(choice) = result.await {
|
||||||
if choice.to_lowercase() != "y" {
|
if choice.to_lowercase() != "y" {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
pub const MIME_DIR: &str = "inode/directory";
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum MimeKind {
|
pub enum MimeKind {
|
||||||
Dir,
|
Dir,
|
||||||
|
|
@ -33,7 +35,7 @@ impl MimeKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(s: &str) -> Self {
|
pub fn new(s: &str) -> Self {
|
||||||
if s == "inode/directory" {
|
if s == MIME_DIR {
|
||||||
Self::Dir
|
Self::Dir
|
||||||
} else if s == "application/json" {
|
} else if s == "application/json" {
|
||||||
Self::JSON
|
Self::JSON
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue