mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 10:36:00 +02:00
Redesign custom canonicalize, enable multiple dots expansion earlier. (#1588)
* Expand n dots early where tilde was also expanded. * Remove normalize, not needed. New function absolutize, doesn't follow links neither checks existence. Renamed canonicalize_existing to canonicalize, works as expected. * Remove normalize usages, change canonicalize. * Treat strings as paths
This commit is contained in:
committed by
GitHub
parent
59d516064c
commit
928188b18e
@ -1,6 +1,7 @@
|
||||
mod files;
|
||||
mod lite_parse;
|
||||
mod parse;
|
||||
mod path;
|
||||
mod shapes;
|
||||
mod signature;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::path::Path;
|
||||
|
||||
use crate::lite_parse::{lite_parse, LiteCommand, LitePipeline};
|
||||
use crate::path::expand_path;
|
||||
use crate::signature::SignatureRegistry;
|
||||
use nu_errors::{ArgumentError, ParseError};
|
||||
use nu_protocol::hir::{
|
||||
@ -373,7 +374,7 @@ fn parse_arg(
|
||||
}
|
||||
SyntaxShape::Pattern => {
|
||||
let trimmed = trim_quotes(&lite_arg.item);
|
||||
let expanded = shellexpand::tilde(&trimmed).to_string();
|
||||
let expanded = expand_path(&trimmed);
|
||||
(
|
||||
SpannedExpression::new(Expression::pattern(expanded), lite_arg.span),
|
||||
None,
|
||||
@ -385,7 +386,7 @@ fn parse_arg(
|
||||
SyntaxShape::Unit => parse_unit(&lite_arg),
|
||||
SyntaxShape::Path => {
|
||||
let trimmed = trim_quotes(&lite_arg.item);
|
||||
let expanded = shellexpand::tilde(&trimmed).to_string();
|
||||
let expanded = expand_path(&trimmed);
|
||||
let path = Path::new(&expanded);
|
||||
(
|
||||
SpannedExpression::new(Expression::FilePath(path.to_path_buf()), lite_arg.span),
|
||||
@ -844,7 +845,7 @@ pub fn classify_pipeline(
|
||||
commands.push(ClassifiedCommand::Internal(internal_command))
|
||||
} else {
|
||||
let trimmed = trim_quotes(&lite_cmd.name.item);
|
||||
let name = shellexpand::tilde(&trimmed).to_string();
|
||||
let name = expand_path(&trimmed);
|
||||
// This is an external command we should allow arguments to pass through with minimal parsing
|
||||
commands.push(ClassifiedCommand::External(ExternalCommand {
|
||||
name,
|
||||
|
52
crates/nu-parser/src/path.rs
Normal file
52
crates/nu-parser/src/path.rs
Normal file
@ -0,0 +1,52 @@
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
|
||||
fn expand_ndots(path: &str) -> String {
|
||||
let path = Path::new(path);
|
||||
let mut expanded = PathBuf::new();
|
||||
|
||||
for component in path.components() {
|
||||
match component {
|
||||
Component::Normal(normal) => {
|
||||
if let Some(normal) = normal.to_str() {
|
||||
if normal.chars().all(|c| c == '.') {
|
||||
for _ in 0..(normal.len() - 1) {
|
||||
expanded.push("..");
|
||||
}
|
||||
} else {
|
||||
expanded.push(normal);
|
||||
}
|
||||
} else {
|
||||
expanded.push(normal);
|
||||
}
|
||||
}
|
||||
|
||||
c => expanded.push(c.as_os_str()),
|
||||
}
|
||||
}
|
||||
|
||||
expanded.to_string_lossy().to_string()
|
||||
}
|
||||
|
||||
pub fn expand_path(path: &str) -> String {
|
||||
let tilde_expansion = shellexpand::tilde(path);
|
||||
expand_ndots(&tilde_expansion)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn expand_in_relative_path() {
|
||||
let expected = Path::new("../..");
|
||||
let expanded = PathBuf::from(expand_path("..."));
|
||||
assert_eq!(expected, &expanded);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn expand_in_absolute_path() {
|
||||
let expected = Path::new("/foo/../..");
|
||||
let expanded = PathBuf::from(expand_path("/foo/..."));
|
||||
assert_eq!(expected, &expanded);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user