Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ There is a wrapper of yazi, that provides the ability to change the current work

```bash
function ya() {
tmp="$(mktemp -t "yazi-cwd")"
tmp="$(mktemp -t "yazi-cwd.XXXXX")"
yazi --cwd-file="$tmp"
if cwd="$(cat -- "$tmp")" && [ -n "$cwd" ] && [ "$cwd" != "$PWD" ]; then
cd -- "$cwd"
Expand Down
2 changes: 1 addition & 1 deletion app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ impl App {

Event::Open(targets, opener) => {
if let Some(opener) = opener {
tasks.file_open_with(&opener, &targets.iter().map(|(f, _)| f).collect::<Vec<_>>());
tasks.file_open_with(&opener, &targets.into_iter().map(|(f, _)| f).collect::<Vec<_>>());
} else {
tasks.file_open(&targets);
}
Expand Down
22 changes: 12 additions & 10 deletions config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ edition = "2021"
shared = { path = "../shared" }

# External dependencies
anyhow = "^1"
clap = { version = "^4", features = [ "derive" ] }
crossterm = "^0"
futures = "^0"
glob = "^0"
once_cell = "^1"
ratatui = "^0"
serde = { version = "^1", features = [ "derive" ] }
toml = { version = "^0", features = [ "preserve_order" ] }
xdg = "^2"
anyhow = "^1"
clap = { version = "^4", features = [ "derive" ] }
crossterm = "^0"
futures = "^0"
glob = "^0"
once_cell = "^1"
ratatui = "^0"
regex = "^1"
serde = { version = "^1", features = [ "derive" ] }
shell-words = "^1"
toml = { version = "^0", features = [ "preserve_order" ] }
xdg = "^2"
1 change: 1 addition & 0 deletions config/docs/keymap.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- cd: Change the current directory.

- `path`: the path to change to.
- `--interactive`: Use an interactive UI to input the path.

### Selection

Expand Down
13 changes: 6 additions & 7 deletions config/docs/yazi.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,20 @@ Configure available openers, for example:
```toml
[opener]
archive = [
{ cmd = "unar", args = [ "$0" ] },
{ exec = "unar $1" },
]
text = [
{ cmd = "nvim", args = [ "$*" ], block = true },
{ exec = "nvim $*", block = true },
]
# ...
```

Available parameters are as follows:

- cmd: The program to open the selected files
- args: Arguments to be passed
- `"$n"`: The N-th selected file
- `"$*"`: All selected files
- `"foo"`: Literal string to be passed
- exec: The command to open the selected files, with the following variables available:
- `$n`: The N-th selected file
- `$*`: All selected files
- `foo`: Literal string to be passed
- block: Open in a blocking manner. After setting this, Yazi will hide into a secondary screen and display the program on the main screen until it exits. During this time, it can receive I/O signals, which is useful for interactive programs.

## open
Expand Down
24 changes: 12 additions & 12 deletions config/preset/yazi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,30 @@ max_height = 900

[opener]
folder = [
{ cmd = "open", args = [ "-R", "$*" ], display_name = "Reveal in Finder" },
{ cmd = "vim", args = [ "$*" ] },
{ exec = "open -R $*", display_name = "Reveal in Finder" },
{ exec = "vim $*" },
]
archive = [
{ cmd = "unar", args = [ "$0" ], display_name = "Extract here" },
{ exec = "unar $1", display_name = "Extract here" },
]
text = [
{ cmd = "vim", args = [ "$*" ], block = true },
{ exec = "vim $*", block = true },
]
image = [
{ cmd = "open", args = [ "$*" ], display_name = "Open" },
{ cmd = "exiftool", args = [ "$0" ], block = true, display_name = "Show EXIF" },
{ exec = "open $*", display_name = "Open" },
{ exec = "exiftool $1; echo '\n\nPress enter to exit'; read", block = true, display_name = "Show EXIF" },
]
video = [
{ cmd = "mpv", args = [ "$*" ] },
{ cmd = "mediainfo", args = [ "$0" ], block = true, display_name = "Show media info" },
{ exec = "mpv $*" },
{ exec = "mediainfo $1; echo '\n\nPress enter to exit'; read", block = true, display_name = "Show media info" },
]
audio = [
{ cmd = "mpv", args = [ "$*" ] },
{ cmd = "mediainfo", args = [ "$0" ], block = true, display_name = "Show media info" },
{ exec = "mpv $*" },
{ exec = "mediainfo $1; echo '\n\nPress enter to exit'; read", block = true, display_name = "Show media info" },
]
fallback = [
{ cmd = "open", args = [ "$*" ], display_name = "Open" },
{ cmd = "open", args = [ "-R", "$*" ], display_name = "Reveal in Finder" },
{ exec = "open $*", display_name = "Open" },
{ exec = "open -R $*", display_name = "Reveal in Finder" },
]

[open]
Expand Down
62 changes: 31 additions & 31 deletions config/src/keymap/exec.rs
Original file line number Diff line number Diff line change
@@ -1,49 +1,49 @@
use std::{collections::BTreeMap, fmt};
use std::{collections::BTreeMap, fmt::{self, Debug}};

use anyhow::bail;
use serde::{de::{self, Visitor}, Deserializer};

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug)]
pub struct Exec {
pub cmd: String,
pub args: Vec<String>,
pub named: BTreeMap<String, String>,
}

impl From<&str> for Exec {
fn from(value: &str) -> Self {
let mut exec = Self::default();
for x in value.split_whitespace() {
if let Some(kv) = x.strip_prefix("--") {
let mut it = kv.splitn(2, '=');
let key = it.next().unwrap();
let value = it.next().unwrap_or("");
exec.named.insert(key.to_string(), value.to_string());
} else if exec.cmd.is_empty() {
exec.cmd = x.to_string();
impl TryFrom<&str> for Exec {
type Error = anyhow::Error;

fn try_from(s: &str) -> Result<Self, Self::Error> {
let s = shell_words::split(s)?;
if s.is_empty() {
bail!("`exec` cannot be empty");
}

let mut exec = Self { cmd: s[0].clone(), args: Vec::new(), named: BTreeMap::new() };
for arg in s.into_iter().skip(1) {
if arg.starts_with("--") {
let mut arg = arg.splitn(2, '=');
let key = arg.next().unwrap().trim_start_matches('-');
let val = arg.next().unwrap_or("").to_string();
exec.named.insert(key.to_string(), val);
} else {
exec.args.push(x.to_string());
exec.args.push(arg);
}
}
exec
Ok(exec)
}
}

impl ToString for Exec {
fn to_string(&self) -> String {
let mut s = self.cmd.clone();
for arg in &self.args {
s.push(' ');
s.push_str(arg);
let mut s = Vec::with_capacity(self.args.len() + self.named.len() + 1);
s.push(self.cmd.clone());
s.extend(self.args.iter().cloned());
for (key, val) in self.named.iter() {
s.push(format!("--{}={}", key, val));
}
for (name, value) in &self.named {
s.push_str(" --");
s.push_str(name);
if !value.is_empty() {
s.push('=');
s.push_str(value);
}
}
s

shell_words::join(s)
}
}

Expand All @@ -58,7 +58,7 @@ impl Exec {
type Value = Vec<Exec>;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a command string, e.g. tab_switch 0")
formatter.write_str("a exec string, e.g. tab_switch 0")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
Expand All @@ -67,7 +67,7 @@ impl Exec {
{
let mut execs = Vec::new();
while let Some(value) = &seq.next_element::<String>()? {
execs.push(Exec::from(value.as_str()));
execs.push(Exec::try_from(value.as_str()).map_err(de::Error::custom)?);
}
Ok(execs)
}
Expand All @@ -76,7 +76,7 @@ impl Exec {
where
E: de::Error,
{
Ok(value.split(';').map(Exec::from).collect())
Ok(vec![Exec::try_from(value).map_err(de::Error::custom)?])
}
}

Expand Down
63 changes: 53 additions & 10 deletions config/src/open/opener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ use serde::{Deserialize, Deserializer};

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Opener {
pub cmd: String,
pub args: Vec<String>,
pub exec: String,
pub block: bool,
pub display_name: String,
pub spread: bool,
Expand All @@ -16,20 +15,64 @@ impl<'de> Deserialize<'de> for Opener {
{
#[derive(Deserialize)]
pub struct Shadow {
pub cmd: String,
pub args: Vec<String>,
// TODO: Deprecate this field in v0.1.5
pub cmd: Option<String>,
// TODO: Deprecate this field in v0.1.5
pub args: Option<Vec<String>>,

pub exec: Option<String>,
#[serde(default)]
pub block: bool,
pub display_name: Option<String>,
#[serde(skip)]
pub spread: bool,
}

let shadow = Shadow::deserialize(deserializer)?;
let mut shadow = Shadow::deserialize(deserializer)?;

// -- TODO: Deprecate this in v0.1.5
if shadow.exec.is_none() {
if shadow.cmd.is_none() {
return Err(serde::de::Error::missing_field("exec"));
}
if shadow.args.is_none() {
return Err(serde::de::Error::missing_field("args"));
}

println!(
"WARNING: `cmd` and `args` are deprecated in favor of `exec` in Yazi v0.1.5, see https://github.com/sxyazi/yazi/pull/45"
);

let display_name = if let Some(s) = shadow.display_name { s } else { shadow.cmd.clone() };
let spread = shadow.args.contains(&"$*".to_string());
// Replace the $0 to $1, $1 to $2, and so on
shadow.args = Some(
shadow
.args
.unwrap()
.into_iter()
.map(|s| {
if !s.starts_with('$') {
return shell_words::quote(&s).into();
}
if let Ok(idx) = s[1..].parse::<usize>() {
return format!("${}", idx + 1);
}
s
})
.collect(),
);
shadow.exec = Some(format!("{} {}", shadow.cmd.unwrap(), shadow.args.unwrap().join(" ")));
}
let exec = shadow.exec.unwrap();
// TODO: Deprecate this in v0.1.5 --

if exec.is_empty() {
return Err(serde::de::Error::custom("`exec` cannot be empty"));
}
let display_name = if let Some(s) = shadow.display_name {
s
} else {
exec.split_whitespace().next().unwrap().to_string()
};

Ok(Self { cmd: shadow.cmd, args: shadow.args, block: shadow.block, display_name, spread })
let spread = exec.contains("$*") || exec.contains("$@");
Ok(Self { exec, block: shadow.block, display_name, spread })
}
}
2 changes: 2 additions & 0 deletions core/src/external/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod jq;
mod lsar;
mod pdftoppm;
mod rg;
mod shell;
mod unar;
mod zoxide;

Expand All @@ -19,5 +20,6 @@ pub use jq::*;
pub use lsar::*;
pub use pdftoppm::*;
pub use rg::*;
pub use shell::*;
pub use unar::*;
pub use zoxide::*;
Loading