mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
fix: align the behavior of the end-of-options marker (--) with that of the shell (#2431)
This commit is contained in:
parent
46125eda6e
commit
38d5b2fc87
8 changed files with 28 additions and 29 deletions
|
|
@ -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 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 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.
|
Issues with \`${LABEL_NAME}\` will be marked ready once edited with the proper content, or closed after 2 days of inactivity.
|
||||||
`
|
`
|
||||||
|
|
@ -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 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 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.
|
Issues with \`${LABEL_NAME}\` will be marked ready once edited with the proper content, or closed after 2 days of inactivity.
|
||||||
`
|
`
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,10 @@ macro_rules! impl_emit_body {
|
||||||
impl $name {
|
impl $name {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(super) fn body(self) -> Result<String> {
|
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)?,
|
||||||
|
))?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ impl Tab {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn search_do(&mut self, opt: impl TryInto<SearchOpt>) {
|
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`");
|
return error!("Failed to parse search option for `search_do`");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,16 +27,8 @@ impl TryFrom<CmdCow> for PluginOpt {
|
||||||
};
|
};
|
||||||
|
|
||||||
let args = if let Some(s) = c.second_str() {
|
let args = if let Some(s) = c.second_str() {
|
||||||
Cmd::parse_args(yazi_shared::shell::split_unix(s)?.into_iter(), true)?
|
let (words, last) = yazi_shared::shell::split_unix(s, true)?;
|
||||||
} else if let Some(s) = c.str("args") {
|
Cmd::parse_args(words.into_iter(), last, true)?
|
||||||
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)?
|
|
||||||
} else {
|
} else {
|
||||||
Default::default()
|
Default::default()
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,9 @@ impl TryFrom<CmdCow> for SearchOpt {
|
||||||
via,
|
via,
|
||||||
subject,
|
subject,
|
||||||
// TODO: use second positional argument instead of `args` parameter
|
// 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(),
|
args_raw: c.take_str("args").unwrap_or_default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,13 +119,16 @@ impl Cmd {
|
||||||
// Parse
|
// Parse
|
||||||
pub fn parse_args(
|
pub fn parse_args(
|
||||||
words: impl Iterator<Item = String>,
|
words: impl Iterator<Item = String>,
|
||||||
|
last: Option<String>,
|
||||||
obase: bool,
|
obase: bool,
|
||||||
) -> Result<HashMap<DataKey, Data>> {
|
) -> Result<HashMap<DataKey, Data>> {
|
||||||
let mut i = 0i64;
|
let mut i = 0i64;
|
||||||
words
|
words
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|word| {
|
.map(|s| (s, true))
|
||||||
let Some(arg) = word.strip_prefix("--") else {
|
.chain(last.into_iter().map(|s| (s, false)))
|
||||||
|
.map(|(word, normal)| {
|
||||||
|
let Some(arg) = word.strip_prefix("--").filter(|_| normal) else {
|
||||||
i += 1;
|
i += 1;
|
||||||
return Ok((DataKey::Integer(i - obase as i64), Data::String(word)));
|
return Ok((DataKey::Integer(i - obase as i64), Data::String(word)));
|
||||||
};
|
};
|
||||||
|
|
@ -175,13 +178,13 @@ impl FromStr for Cmd {
|
||||||
type Err = anyhow::Error;
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
let args = crate::shell::split_unix(s)?;
|
let (words, last) = crate::shell::split_unix(s, true)?;
|
||||||
if args.is_empty() || args[0].is_empty() {
|
if words.is_empty() || words[0].is_empty() {
|
||||||
bail!("command name cannot be empty");
|
bail!("command name cannot be empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut me = Self::new(&args[0]);
|
let mut me = Self::new(&words[0]);
|
||||||
me.args = Cmd::parse_args(args.into_iter().skip(1), true)?;
|
me.args = Cmd::parse_args(words.into_iter().skip(1), last, true)?;
|
||||||
Ok(me)
|
Ok(me)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@ pub fn escape_os_str(s: &OsStr) -> Cow<OsStr> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn split_unix(s: &str) -> anyhow::Result<Vec<String>> {
|
pub fn split_unix(s: &str, eoo: bool) -> anyhow::Result<(Vec<String>, Option<String>)> {
|
||||||
unix::split(s).map_err(|()| anyhow::anyhow!("missing closing quote"))
|
unix::split(s, eoo).map_err(|()| anyhow::anyhow!("missing closing quote"))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
|
@ -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>> {
|
pub fn split_native(s: &str) -> anyhow::Result<Vec<String>> {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
split_unix(s)
|
Ok(split_unix(s, false)?.0)
|
||||||
}
|
}
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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'+')
|
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 {
|
enum State {
|
||||||
/// Within a delimiter.
|
/// Within a delimiter.
|
||||||
Delimiter,
|
Delimiter,
|
||||||
|
|
@ -74,9 +74,8 @@ pub fn split(s: &str) -> Result<Vec<String>, ()> {
|
||||||
|
|
||||||
macro_rules! flush {
|
macro_rules! flush {
|
||||||
() => {
|
() => {
|
||||||
if word == "--" {
|
if word == "--" && eoo {
|
||||||
words.push(chars.collect());
|
return Ok((words, Some(chars.collect())));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
words.push(mem::take(&mut word));
|
words.push(mem::take(&mut word));
|
||||||
};
|
};
|
||||||
|
|
@ -176,7 +175,7 @@ pub fn split(s: &str) -> Result<Vec<String>, ()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(words)
|
Ok((words, None))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue