forked from extern/nushell
new glob
command (#5087)
This commit is contained in:
127
crates/nu-command/src/filesystem/glob.rs
Normal file
127
crates/nu-command/src/filesystem/glob.rs
Normal file
@ -0,0 +1,127 @@
|
||||
use nu_engine::env::current_dir;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
Category, Example, IntoInterruptiblePipelineData, PipelineData, ShellError, Signature, Spanned,
|
||||
SyntaxShape, Value,
|
||||
};
|
||||
use wax::Glob as WaxGlob;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Glob;
|
||||
|
||||
impl Command for Glob {
|
||||
fn name(&self) -> &str {
|
||||
"glob"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("glob")
|
||||
.required("glob", SyntaxShape::String, "the glob expression")
|
||||
.named(
|
||||
"depth",
|
||||
SyntaxShape::Int,
|
||||
"directory depth to search",
|
||||
Some('d'),
|
||||
)
|
||||
.category(Category::FileSystem)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Creates a list of files and/or folders based on the glob pattern provided."
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "Search for *.rs files",
|
||||
example: "glob *.rs",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Search for *.rs and *.toml files recursively up to 2 folders deep",
|
||||
example: "glob **/*.{rs,toml} --depth 2",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description:
|
||||
"Search for files and folders that begin with uppercase C and lowercase c",
|
||||
example: r#"glob "[Cc]*""#,
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description:
|
||||
"Search for files and folders like abc or xyz substituting a character for ?",
|
||||
example: r#"glob "{a?c,x?z}""#,
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "A case-insensitive search for files and folders that begin with c",
|
||||
example: r#"glob "(?i)c*""#,
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Search for files for folders that do not begin with c, C, b, M, or s",
|
||||
example: r#"glob "[!cCbMs]*""#,
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Search for files or folders with 3 a's in a row in the name",
|
||||
example: "glob <a*:3>",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Search for files or folders with only a, b, c, or d in the file name between 1 and 10 times",
|
||||
example: "glob <[a-d]:1,10>",
|
||||
result: None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"For more glob pattern help please refer to https://github.com/olson-sean-k/wax"#
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let span = call.head;
|
||||
let path = current_dir(engine_state, stack)?;
|
||||
let glob_pattern: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
let depth = call.get_flag(engine_state, stack, "depth")?;
|
||||
|
||||
let folder_depth = if let Some(depth) = depth {
|
||||
depth
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
|
||||
let glob = match WaxGlob::new(&glob_pattern.item) {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
return Err(ShellError::LabeledError(
|
||||
"error with glob pattern".to_string(),
|
||||
format!("{}", e),
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
let glob_results: Vec<Value> = glob
|
||||
.walk(path, folder_depth)
|
||||
.flatten()
|
||||
.map(|entry| Value::String {
|
||||
val: entry.into_path().to_string_lossy().to_string(),
|
||||
span,
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(glob_results
|
||||
.into_iter()
|
||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
mod cd;
|
||||
mod cp;
|
||||
mod glob;
|
||||
mod ls;
|
||||
mod mkdir;
|
||||
mod mv;
|
||||
@ -11,6 +12,7 @@ mod util;
|
||||
|
||||
pub use cd::Cd;
|
||||
pub use cp::Cp;
|
||||
pub use glob::Glob;
|
||||
pub use ls::Ls;
|
||||
pub use mkdir::Mkdir;
|
||||
pub use mv::Mv;
|
||||
|
Reference in New Issue
Block a user