[ls, path relative-to] Fix use of ls ~ | path relative-to ~
(#5212)
* [ls] implement 1b. > `ls ~` does not return paths relative to the current directory. We now return `/Users/blah` instead of `../../blah` * expand lhs and rhs on `path relative-to` /Users/nimazzuc/projects/nushell〉'~' | path relative-to '~' /Users/nimazzuc/projects/nushell〉'~/foo' | path relative-to '~' foo /Users/nimazzuc/projects/nushell〉'/Users/nimazzuc/foo' | path relative-to '~' foo /Users/nimazzuc/projects/nushell〉'~/foo' | path relative-to '/Users/nimazzuc' foo * format
This commit is contained in:
parent
4d31139a44
commit
6e85b04923
|
@ -3,6 +3,7 @@ use crate::DirInfo;
|
||||||
use chrono::{DateTime, Local};
|
use chrono::{DateTime, Local};
|
||||||
use nu_engine::env::current_dir;
|
use nu_engine::env::current_dir;
|
||||||
use nu_engine::CallExt;
|
use nu_engine::CallExt;
|
||||||
|
use nu_path::expand_to_real_path;
|
||||||
use nu_protocol::ast::Call;
|
use nu_protocol::ast::Call;
|
||||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
|
@ -76,7 +77,7 @@ impl Command for Ls {
|
||||||
let (path, p_tag, absolute_path) = match pattern_arg {
|
let (path, p_tag, absolute_path) = match pattern_arg {
|
||||||
Some(p) => {
|
Some(p) => {
|
||||||
let p_tag = p.span;
|
let p_tag = p.span;
|
||||||
let mut p = PathBuf::from(p.item);
|
let mut p = expand_to_real_path(p.item);
|
||||||
|
|
||||||
let expanded = nu_path::expand_path_with(&p, &cwd);
|
let expanded = nu_path::expand_path_with(&p, &cwd);
|
||||||
if expanded.is_dir() {
|
if expanded.is_dir() {
|
||||||
|
@ -223,6 +224,11 @@ impl Command for Ls {
|
||||||
example: "ls subdir",
|
example: "ls subdir",
|
||||||
result: None,
|
result: None,
|
||||||
},
|
},
|
||||||
|
Example {
|
||||||
|
description: "List all files with full path in the parent directory",
|
||||||
|
example: "ls -f ..",
|
||||||
|
result: None,
|
||||||
|
},
|
||||||
Example {
|
Example {
|
||||||
description: "List all rust files",
|
description: "List all rust files",
|
||||||
example: "ls *.rs",
|
example: "ls *.rs",
|
||||||
|
@ -234,8 +240,8 @@ impl Command for Ls {
|
||||||
result: None,
|
result: None,
|
||||||
},
|
},
|
||||||
Example {
|
Example {
|
||||||
description: "List all dirs with full path name in your home directory",
|
description: "List all dirs in your home directory",
|
||||||
example: "ls -f ~ | where type == dir",
|
example: "ls ~ | where type == dir",
|
||||||
result: None,
|
result: None,
|
||||||
},
|
},
|
||||||
Example {
|
Example {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use nu_engine::CallExt;
|
use nu_engine::CallExt;
|
||||||
|
use nu_path::expand_to_real_path;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
engine::Command, Example, ShellError, Signature, Span, Spanned, SyntaxShape, Value,
|
engine::Command, Example, ShellError, Signature, Span, Spanned, SyntaxShape, Value,
|
||||||
};
|
};
|
||||||
|
@ -114,7 +115,9 @@ path."#
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relative_to(path: &Path, span: Span, args: &Arguments) -> Value {
|
fn relative_to(path: &Path, span: Span, args: &Arguments) -> Value {
|
||||||
match path.strip_prefix(Path::new(&args.path.item)) {
|
let lhs = expand_to_real_path(path);
|
||||||
|
let rhs = expand_to_real_path(&args.path.item);
|
||||||
|
match lhs.strip_prefix(&rhs) {
|
||||||
Ok(p) => Value::string(p.to_string_lossy(), span),
|
Ok(p) => Value::string(p.to_string_lossy(), span),
|
||||||
Err(e) => Value::Error {
|
Err(e) => Value::Error {
|
||||||
error: ShellError::CantConvert(e.to_string(), "string".into(), span),
|
error: ShellError::CantConvert(e.to_string(), "string".into(), span),
|
||||||
|
|
|
@ -398,7 +398,7 @@ impl ExternalCommand {
|
||||||
/// Spawn a command without shelling out to an external shell
|
/// Spawn a command without shelling out to an external shell
|
||||||
pub fn spawn_simple_command(&self, cwd: &str) -> Result<std::process::Command, ShellError> {
|
pub fn spawn_simple_command(&self, cwd: &str) -> Result<std::process::Command, ShellError> {
|
||||||
let head = trim_enclosing_quotes(&self.name.item);
|
let head = trim_enclosing_quotes(&self.name.item);
|
||||||
let head = nu_path::expand_path_for_external_programs(head)
|
let head = nu_path::expand_to_real_path(head)
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
|
@ -409,7 +409,7 @@ impl ExternalCommand {
|
||||||
item: trim_enclosing_quotes(&arg.item),
|
item: trim_enclosing_quotes(&arg.item),
|
||||||
span: arg.span,
|
span: arg.span,
|
||||||
};
|
};
|
||||||
arg.item = nu_path::expand_path_for_external_programs(arg.item)
|
arg.item = nu_path::expand_to_real_path(arg.item)
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_path(path: impl AsRef<Path>) -> PathBuf {
|
fn expand_path(path: impl AsRef<Path>) -> PathBuf {
|
||||||
let path = expand_tilde(path);
|
let path = expand_to_real_path(path);
|
||||||
let path = expand_ndots(path);
|
|
||||||
expand_dots(path)
|
expand_dots(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,12 +73,13 @@ where
|
||||||
expand_path(path)
|
expand_path(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve similarly to other shells - tilde is expanded, and ndot path components are expanded.
|
/// Resolve to a path that is accepted by the system and no further - tilde is expanded, and ndot path components are expanded.
|
||||||
///
|
///
|
||||||
/// This function will take a leading tilde path component, and expand it to the user's home directory;
|
/// This function will take a leading tilde path component, and expand it to the user's home directory;
|
||||||
/// it will also expand any path elements consisting of only dots into the correct number of `..` path elements.
|
/// it will also expand any path elements consisting of only dots into the correct number of `..` path elements.
|
||||||
/// It does not touch the system at all, except for getting the home directory of the current user.
|
/// It does not do any normalization except to what will be accepted by Path::open,
|
||||||
pub fn expand_path_for_external_programs<P>(path: P) -> PathBuf
|
/// and it does not touch the system at all, except for getting the home directory of the current user.
|
||||||
|
pub fn expand_to_real_path<P>(path: P) -> PathBuf
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,7 @@ mod helpers;
|
||||||
mod tilde;
|
mod tilde;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
pub use expansions::{canonicalize_with, expand_path_for_external_programs, expand_path_with};
|
pub use expansions::{canonicalize_with, expand_path_with, expand_to_real_path};
|
||||||
pub use helpers::{config_dir, home_dir};
|
pub use helpers::{config_dir, home_dir};
|
||||||
pub use tilde::expand_tilde;
|
pub use tilde::expand_tilde;
|
||||||
pub use util::trim_trailing_slash;
|
pub use util::trim_trailing_slash;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user