Skip to content

Commit

Permalink
fix: align the behavior of the end-of-options marker (--) with that…
Browse files Browse the repository at this point in the history
… of the shell (#2431)
  • Loading branch information
sxyazi committed Mar 3, 2025
1 parent 46125ed commit 38d5b2f
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 29 deletions.
4 changes: 2 additions & 2 deletions scripts/validate-form/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function bugReportBody(creator, content, hash) {
- The bug can still be reproduced on the [newest nightly build](https://yazi-rs.github.io/docs/installation/#binaries).
- The debug information (\`yazi --debug\`) is updated for the newest nightly.
- The *required* fields in the checklist are checked.
- The non-optional items in the checklist are checked.
Issues with \`${LABEL_NAME}\` will be marked ready once edited with the proper content, or closed after 2 days of inactivity.
`
Expand All @@ -27,7 +27,7 @@ function featureRequestBody(creator, content) {
- The requested feature does not exist in the [newest nightly build](https://yazi-rs.github.io/docs/installation/#binaries).
- The debug information (\`yazi --debug\`) is updated for the newest nightly.
- The *required* fields in the checklist are checked.
- The non-optional items in the checklist are checked.
Issues with \`${LABEL_NAME}\` will be marked ready once edited with the proper content, or closed after 2 days of inactivity.
`
Expand Down
5 changes: 4 additions & 1 deletion yazi-cli/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,10 @@ macro_rules! impl_emit_body {
impl $name {
#[allow(dead_code)]
pub(super) fn body(self) -> Result<String> {
Ok(serde_json::to_string(&(self.name, Cmd::parse_args(self.args.into_iter(), false)?))?)
Ok(serde_json::to_string(&(
self.name,
Cmd::parse_args(self.args.into_iter(), None, false)?,
))?)
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion yazi-core/src/tab/commands/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ impl Tab {
}

pub fn search_do(&mut self, opt: impl TryInto<SearchOpt>) {
let Ok(opt) = opt.try_into() else {
let Ok(opt): Result<SearchOpt, _> = opt.try_into() else {
return error!("Failed to parse search option for `search_do`");
};

Expand Down
12 changes: 2 additions & 10 deletions yazi-proxy/src/options/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,8 @@ impl TryFrom<CmdCow> for PluginOpt {
};

let args = if let Some(s) = c.second_str() {
Cmd::parse_args(yazi_shared::shell::split_unix(s)?.into_iter(), true)?
} else if let Some(s) = c.str("args") {
crate::deprecate!(
format!("The `args` parameter of the `plugin` command has been deprecated. Please use the second positional argument of `plugin` instead.
For example, replace `plugin test --args=foobar` with `plugin test foobar`, for your `plugin {}` command.
See #2299 for more information: https://github.com/sxyazi/yazi/pull/2299", id)
);
Cmd::parse_args(yazi_shared::shell::split_unix(s)?.into_iter(), true)?
let (words, last) = yazi_shared::shell::split_unix(s, true)?;
Cmd::parse_args(words.into_iter(), last, true)?
} else {
Default::default()
};
Expand Down
4 changes: 3 additions & 1 deletion yazi-proxy/src/options/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ impl TryFrom<CmdCow> for SearchOpt {
via,
subject,
// TODO: use second positional argument instead of `args` parameter
args: yazi_shared::shell::split_unix(c.str("args").unwrap_or_default()).map_err(|_| ())?,
args: yazi_shared::shell::split_unix(c.str("args").unwrap_or_default(), false)
.map_err(|_| ())?
.0,
args_raw: c.take_str("args").unwrap_or_default(),
})
}
Expand Down
15 changes: 9 additions & 6 deletions yazi-shared/src/event/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,16 @@ impl Cmd {
// Parse
pub fn parse_args(
words: impl Iterator<Item = String>,
last: Option<String>,
obase: bool,
) -> Result<HashMap<DataKey, Data>> {
let mut i = 0i64;
words
.into_iter()
.map(|word| {
let Some(arg) = word.strip_prefix("--") else {
.map(|s| (s, true))
.chain(last.into_iter().map(|s| (s, false)))
.map(|(word, normal)| {
let Some(arg) = word.strip_prefix("--").filter(|_| normal) else {
i += 1;
return Ok((DataKey::Integer(i - obase as i64), Data::String(word)));
};
Expand Down Expand Up @@ -175,13 +178,13 @@ impl FromStr for Cmd {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let args = crate::shell::split_unix(s)?;
if args.is_empty() || args[0].is_empty() {
let (words, last) = crate::shell::split_unix(s, true)?;
if words.is_empty() || words[0].is_empty() {
bail!("command name cannot be empty");
}

let mut me = Self::new(&args[0]);
me.args = Cmd::parse_args(args.into_iter().skip(1), true)?;
let mut me = Self::new(&words[0]);
me.args = Cmd::parse_args(words.into_iter().skip(1), last, true)?;
Ok(me)
}
}
Expand Down
6 changes: 3 additions & 3 deletions yazi-shared/src/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ pub fn escape_os_str(s: &OsStr) -> Cow<OsStr> {
}

#[inline]
pub fn split_unix(s: &str) -> anyhow::Result<Vec<String>> {
unix::split(s).map_err(|()| anyhow::anyhow!("missing closing quote"))
pub fn split_unix(s: &str, eoo: bool) -> anyhow::Result<(Vec<String>, Option<String>)> {
unix::split(s, eoo).map_err(|()| anyhow::anyhow!("missing closing quote"))
}

#[cfg(windows)]
Expand All @@ -52,7 +52,7 @@ pub fn split_windows(s: &str) -> anyhow::Result<Vec<String>> { Ok(windows::split
pub fn split_native(s: &str) -> anyhow::Result<Vec<String>> {
#[cfg(unix)]
{
split_unix(s)
Ok(split_unix(s, false)?.0)
}
#[cfg(windows)]
{
Expand Down
9 changes: 4 additions & 5 deletions yazi-shared/src/shell/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ fn allowed(b: u8) -> bool {
matches!(b, b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' | b'-' | b'_' | b'=' | b'/' | b',' | b'.' | b'+')
}

pub fn split(s: &str) -> Result<Vec<String>, ()> {
pub fn split(s: &str, eoo: bool) -> Result<(Vec<String>, Option<String>), ()> {
enum State {
/// Within a delimiter.
Delimiter,
Expand Down Expand Up @@ -74,9 +74,8 @@ pub fn split(s: &str) -> Result<Vec<String>, ()> {

macro_rules! flush {
() => {
if word == "--" {
words.push(chars.collect());
break;
if word == "--" && eoo {
return Ok((words, Some(chars.collect())));
}
words.push(mem::take(&mut word));
};
Expand Down Expand Up @@ -176,7 +175,7 @@ pub fn split(s: &str) -> Result<Vec<String>, ()> {
}
}

Ok(words)
Ok((words, None))
}

#[cfg(test)]
Expand Down

0 comments on commit 38d5b2f

Please # to comment.