mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 16:25:58 +02:00
Unify glob behavior on open
, rm
, cp-old
, mv
, umv
, cp
and du
commands (#11621)
# Description This pr is a follow up to [#11569](https://github.com/nushell/nushell/pull/11569#issuecomment-1902279587) > Revert the logic in https://github.com/nushell/nushell/pull/10694 and apply the logic in this pr to mv, cp, rv will require a larger change, I need to think how to achieve the bahavior And sorry @bobhy for reverting some of your changes. This pr is going to unify glob behavior on the given commands: * open * rm * cp-old * mv * umv * cp * du So they have the same behavior to `ls`, which is: If given parameter is quoted by single quote(`'`) or double quote(`"`), don't auto-expand the glob pattern. If not quoted, auto-expand the glob pattern. Fixes: #9558 Fixes: #10211 Fixes: #9310 Fixes: #10364 # TODO But there is one thing remains: if we give a variable to the command, it will always auto-expand the glob pattern, e.g: ```nushell let path = "a[123]b" rm $path ``` I don't think it's expected. But I also think user might want to auto-expand the glob pattern in variables. So I'll introduce a new command called `glob escape`, then if user doesn't want to auto-expand the glob pattern, he can just do this: `rm ($path | glob escape)` # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> # Tests + Formatting Done # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. --> ## NOTE This pr changes the semantic of `GlobPattern`, before this pr, it will `expand path` after evaluated, this makes `nu_engine::glob_from` have no chance to glob things right if a path contains glob pattern. e.g: [#9310 ](https://github.com/nushell/nushell/issues/9310#issuecomment-1886824030) #10211 I think changing the semantic is fine, because it makes glob works if path contains something like '*'. It maybe a breaking change if a custom command's argument are annotated by `: glob`.
This commit is contained in:
@ -40,7 +40,6 @@ pub enum Expr {
|
||||
Filepath(String, bool),
|
||||
Directory(String, bool),
|
||||
GlobPattern(String, bool),
|
||||
LsGlobPattern(String, bool),
|
||||
String(String),
|
||||
CellPath(CellPath),
|
||||
FullCellPath(Box<FullCellPath>),
|
||||
|
@ -209,7 +209,6 @@ impl Expression {
|
||||
Expr::Garbage => false,
|
||||
Expr::Nothing => false,
|
||||
Expr::GlobPattern(_, _) => false,
|
||||
Expr::LsGlobPattern(_, _) => false,
|
||||
Expr::Int(_) => false,
|
||||
Expr::Keyword(_, _, expr) => expr.has_in_variable(working_set),
|
||||
Expr::List(list) => {
|
||||
@ -389,7 +388,6 @@ impl Expression {
|
||||
Expr::Garbage => {}
|
||||
Expr::Nothing => {}
|
||||
Expr::GlobPattern(_, _) => {}
|
||||
Expr::LsGlobPattern(_, _) => {}
|
||||
Expr::MatchBlock(_) => {}
|
||||
Expr::Int(_) => {}
|
||||
Expr::Keyword(_, _, expr) => expr.replace_span(working_set, replaced, new_span),
|
||||
|
@ -286,9 +286,8 @@ pub trait Eval {
|
||||
}
|
||||
Expr::Overlay(_) => Self::eval_overlay(state, expr.span),
|
||||
Expr::GlobPattern(pattern, quoted) => {
|
||||
Self::eval_glob_pattern(state, mut_state, pattern.clone(), *quoted, expr.span)
|
||||
}
|
||||
Expr::LsGlobPattern(pattern, quoted) => {
|
||||
// GlobPattern is similar to Filepath
|
||||
// But we don't want to expand path during eval time, it's required for `nu_engine::glob_from` to run correctly
|
||||
if *quoted {
|
||||
Ok(Value::quoted_string(pattern, expr.span))
|
||||
} else {
|
||||
@ -381,14 +380,6 @@ pub trait Eval {
|
||||
|
||||
fn eval_overlay(state: Self::State<'_>, span: Span) -> Result<Value, ShellError>;
|
||||
|
||||
fn eval_glob_pattern(
|
||||
state: Self::State<'_>,
|
||||
mut_state: &mut Self::MutState,
|
||||
pattern: String,
|
||||
quoted: bool,
|
||||
span: Span,
|
||||
) -> Result<Value, ShellError>;
|
||||
|
||||
/// For expressions that should never actually be evaluated
|
||||
fn unreachable(expr: &Expression) -> Result<Value, ShellError>;
|
||||
}
|
||||
|
@ -388,16 +388,6 @@ impl Eval for EvalConst {
|
||||
Err(ShellError::NotAConstant { span })
|
||||
}
|
||||
|
||||
fn eval_glob_pattern(
|
||||
_: &StateWorkingSet,
|
||||
_: &mut (),
|
||||
_: String,
|
||||
_: bool,
|
||||
span: Span,
|
||||
) -> Result<Value, ShellError> {
|
||||
Err(ShellError::NotAConstant { span })
|
||||
}
|
||||
|
||||
fn unreachable(expr: &Expression) -> Result<Value, ShellError> {
|
||||
Err(ShellError::NotAConstant { span: expr.span })
|
||||
}
|
||||
|
@ -1264,23 +1264,6 @@ This is an internal Nushell error, please file an issue https://github.com/nushe
|
||||
span: Span,
|
||||
},
|
||||
|
||||
/// Error expanding glob pattern
|
||||
///
|
||||
/// ## Resolution
|
||||
///
|
||||
/// Correct glob pattern or file access issue
|
||||
#[error("Error expanding glob pattern")]
|
||||
#[diagnostic(
|
||||
code(nu::shell::error_expanding_glob),
|
||||
help("Correct glob pattern or file access issue")
|
||||
)]
|
||||
//todo: add error detail
|
||||
ErrorExpandingGlob {
|
||||
msg: String,
|
||||
#[label("{msg}")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
/// Tried spreading a non-list inside a list or command call.
|
||||
///
|
||||
/// ## Resolution
|
||||
|
@ -64,9 +64,6 @@ pub enum SyntaxShape {
|
||||
/// A glob pattern is allowed, eg `foo*`
|
||||
GlobPattern,
|
||||
|
||||
/// A special glob pattern for ls.
|
||||
LsGlobPattern,
|
||||
|
||||
/// Only an integer value is allowed
|
||||
Int,
|
||||
|
||||
@ -154,7 +151,6 @@ impl SyntaxShape {
|
||||
SyntaxShape::Filesize => Type::Filesize,
|
||||
SyntaxShape::FullCellPath => Type::Any,
|
||||
SyntaxShape::GlobPattern => Type::String,
|
||||
SyntaxShape::LsGlobPattern => Type::String,
|
||||
SyntaxShape::Error => Type::Error,
|
||||
SyntaxShape::ImportPattern => Type::Any,
|
||||
SyntaxShape::Int => Type::Int,
|
||||
@ -205,7 +201,6 @@ impl Display for SyntaxShape {
|
||||
SyntaxShape::Filepath => write!(f, "path"),
|
||||
SyntaxShape::Directory => write!(f, "directory"),
|
||||
SyntaxShape::GlobPattern => write!(f, "glob"),
|
||||
SyntaxShape::LsGlobPattern => write!(f, "glob"),
|
||||
SyntaxShape::ImportPattern => write!(f, "import"),
|
||||
SyntaxShape::Block => write!(f, "block"),
|
||||
SyntaxShape::Closure(args) => {
|
||||
|
@ -1,8 +1,11 @@
|
||||
use serde::Deserialize;
|
||||
use std::fmt::Display;
|
||||
|
||||
/// A simple wrapper to String.
|
||||
///
|
||||
/// But it tracks if the string is originally quoted.
|
||||
/// So commands can make decision on path auto-expanding behavior.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub enum NuPath {
|
||||
/// A quoted path(except backtick), in this case, nushell shouldn't auto-expand path.
|
||||
Quoted(String),
|
||||
@ -10,6 +13,15 @@ pub enum NuPath {
|
||||
UnQuoted(String),
|
||||
}
|
||||
|
||||
impl NuPath {
|
||||
pub fn strip_ansi_string_unlikely(self) -> Self {
|
||||
match self {
|
||||
NuPath::Quoted(s) => NuPath::Quoted(nu_utils::strip_ansi_string_unlikely(s)),
|
||||
NuPath::UnQuoted(s) => NuPath::UnQuoted(nu_utils::strip_ansi_string_unlikely(s)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for NuPath {
|
||||
fn as_ref(&self) -> &str {
|
||||
match self {
|
||||
@ -17,3 +29,9 @@ impl AsRef<str> for NuPath {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for NuPath {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.as_ref())
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user