Create nu_glob::is_glob function (#14717)

# Description

Adds an `is_glob` function to the nu-glob crate that takes a string
pattern and returns whether or not it's a glob that would be expanded by
nu-glob. Right now, this just means checking if it contains `*`, `?`, or
`[`.

Previously, this same code was duplicated in the following places:
- `ls`: Determining whether to read a folder's contents or expand a glob
- `run_external.rs` in nu-command: Arguments to externals only have
n-dots and tilde expansion applied if they weren't globs
- `glob_from` in nu-engine:
  - `glob_from` can get the prefix in a simpler way for non-globs
- If the canonical path for a non-glob path contains glob
metacharacters, it needs to be escaped
- `completion_common.rs` in nu-cli: File/folder completions containing
glob metacharacters need to be wrapped in quotes

All of these locations can use `nu_glob::is_glob` now instead of rolling
their own checks. This does mean that nu-cli now has a dependency on
nu-glob.

# User-Facing Changes

Users of nu-glob will now be able to check if a given pattern is a glob
expanded by nu-glob.

For users of Nushell, completion suggestions for files containing `]`
will no longer be wrapped in quotes if they contain no other glob
metacharacters. This is because unmatched `]`s are ignored by nu-glob,
but we used to consider such file completions contaminated anyway.

# Tests + Formatting

This is a very basic function, so I just added some doctests.

# After Submitting

This is meant to be used in
https://github.com/nushell/nushell/pull/14674.
This commit is contained in:
Yash Thakur
2025-01-01 19:04:17 -05:00
committed by GitHub
parent f69b22f00b
commit 62bd6fe08b
7 changed files with 31 additions and 15 deletions

View File

@ -33,8 +33,6 @@ struct Args {
call_span: Span,
}
const GLOB_CHARS: &[char] = &['*', '?', '['];
impl Command for Ls {
fn name(&self) -> &str {
"ls"
@ -291,7 +289,7 @@ fn ls_for_one_pattern(
{
return Ok(Value::test_nothing().into_pipeline_data());
}
just_read_dir = !(pat.item.is_expand() && pat.item.as_ref().contains(GLOB_CHARS));
just_read_dir = !(pat.item.is_expand() && nu_glob::is_glob(pat.item.as_ref()));
}
// it's absolute path if:

View File

@ -340,11 +340,9 @@ fn expand_glob(
span: Span,
signals: &Signals,
) -> Result<Vec<OsString>, ShellError> {
const GLOB_CHARS: &[char] = &['*', '?', '['];
// For an argument that doesn't include the GLOB_CHARS, just do the `expand_tilde`
// For an argument that isn't a glob, just do the `expand_tilde`
// and `expand_ndots` expansion
if !arg.contains(GLOB_CHARS) {
if !nu_glob::is_glob(arg) {
let path = expand_ndots_safe(expand_tilde(arg));
return Ok(vec![path.into()]);
}