mirror of
https://github.com/nushell/nushell.git
synced 2025-08-11 09:24:51 +02:00
For example, when running the following: crates/nu-cli/src nushell currently parses this as an external command. Before running the command, we check to see if it's a directory. If it is, we "auto cd" into that directory, otherwise we go through normal external processing. If we put a trailing slash on it though, shells typically interpret that as "user is explicitly referencing directory". So crates/nu-cli/src/ should not be interpreted as "run an external command". We intercept a trailing slash in the head position of a command in a pipeline as such, and inject a `cd` internal command.
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
use crate::commands::cd::CdArgs;
|
||||
use crate::commands::command::EvaluatedWholeStreamCommandArgs;
|
||||
use crate::commands::cp::CopyArgs;
|
||||
use crate::commands::ls::LsArgs;
|
||||
@ -10,9 +11,7 @@ use crate::prelude::*;
|
||||
use crate::shell::completer::NuCompleter;
|
||||
use crate::shell::shell::Shell;
|
||||
use crate::utils::FileStructure;
|
||||
use nu_errors::ShellError;
|
||||
use nu_parser::expand_ndots;
|
||||
use nu_protocol::{Primitive, ReturnSuccess, UntaggedValue};
|
||||
|
||||
use rustyline::completion::FilenameCompleter;
|
||||
use rustyline::hint::{Hinter, HistoryHinter};
|
||||
use std::collections::HashMap;
|
||||
@ -21,6 +20,11 @@ use std::path::{Component, Path, PathBuf};
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
use nu_errors::ShellError;
|
||||
use nu_parser::expand_ndots;
|
||||
use nu_protocol::{Primitive, ReturnSuccess, UntaggedValue};
|
||||
use nu_source::Tagged;
|
||||
|
||||
pub struct FilesystemShell {
|
||||
pub(crate) path: String,
|
||||
pub(crate) last_path: String,
|
||||
@ -171,21 +175,20 @@ impl Shell for FilesystemShell {
|
||||
Ok(stream.interruptible(ctrl_c).to_output_stream())
|
||||
}
|
||||
|
||||
fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let path = match args.nth(0) {
|
||||
fn cd(&self, args: CdArgs, name: Tag) -> Result<OutputStream, ShellError> {
|
||||
let path = match args.path {
|
||||
None => match dirs::home_dir() {
|
||||
Some(o) => o,
|
||||
_ => {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Cannot change to home directory",
|
||||
"cannot go to home",
|
||||
&args.call_info.name_tag,
|
||||
&name,
|
||||
))
|
||||
}
|
||||
},
|
||||
Some(v) => {
|
||||
let target = v.as_path()?;
|
||||
|
||||
let Tagged { item: target, tag } = v;
|
||||
if target == Path::new("-") {
|
||||
PathBuf::from(&self.last_path)
|
||||
} else {
|
||||
@ -193,7 +196,7 @@ impl Shell for FilesystemShell {
|
||||
ShellError::labeled_error(
|
||||
"Cannot change to directory",
|
||||
"directory not found",
|
||||
&v.tag,
|
||||
&tag,
|
||||
)
|
||||
})?;
|
||||
|
||||
@ -201,7 +204,7 @@ impl Shell for FilesystemShell {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Cannot change to directory",
|
||||
"is not a directory",
|
||||
&v.tag,
|
||||
&tag,
|
||||
));
|
||||
}
|
||||
|
||||
@ -216,7 +219,7 @@ impl Shell for FilesystemShell {
|
||||
ShellError::labeled_error(
|
||||
"Cannot change to directory",
|
||||
format!("cannot stat ({})", e),
|
||||
&v.tag,
|
||||
&tag,
|
||||
)
|
||||
})?;
|
||||
|
||||
@ -224,7 +227,7 @@ impl Shell for FilesystemShell {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Cannot change to directory",
|
||||
"permission denied",
|
||||
&v.tag,
|
||||
&tag,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::commands::cd::CdArgs;
|
||||
use crate::commands::command::EvaluatedWholeStreamCommandArgs;
|
||||
use crate::commands::cp::CopyArgs;
|
||||
use crate::commands::ls::LsArgs;
|
||||
@ -7,12 +8,15 @@ use crate::commands::rm::RemoveArgs;
|
||||
use crate::data::command_dict;
|
||||
use crate::prelude::*;
|
||||
use crate::shell::shell::Shell;
|
||||
|
||||
use std::ffi::OsStr;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
Primitive, ReturnSuccess, ShellTypeName, TaggedDictBuilder, UntaggedValue, Value,
|
||||
};
|
||||
use std::ffi::OsStr;
|
||||
use std::path::PathBuf;
|
||||
use nu_source::Tagged;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct HelpShell {
|
||||
@ -149,12 +153,11 @@ impl Shell for HelpShell {
|
||||
Ok(output.into())
|
||||
}
|
||||
|
||||
fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let path = match args.nth(0) {
|
||||
fn cd(&self, args: CdArgs, _name: Tag) -> Result<OutputStream, ShellError> {
|
||||
let path = match args.path {
|
||||
None => "/".to_string(),
|
||||
Some(v) => {
|
||||
let target = v.as_path()?;
|
||||
|
||||
let Tagged { item: target, .. } = v;
|
||||
let mut cwd = PathBuf::from(&self.path);
|
||||
|
||||
if target == PathBuf::from("..") {
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::commands::cd::CdArgs;
|
||||
use crate::commands::command::EvaluatedWholeStreamCommandArgs;
|
||||
use crate::commands::cp::CopyArgs;
|
||||
use crate::commands::ls::LsArgs;
|
||||
@ -18,7 +19,7 @@ pub trait Shell: std::fmt::Debug {
|
||||
args: LsArgs,
|
||||
context: &RunnablePerItemContext,
|
||||
) -> Result<OutputStream, ShellError>;
|
||||
fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError>;
|
||||
fn cd(&self, args: CdArgs, name: Tag) -> Result<OutputStream, ShellError>;
|
||||
fn cp(&self, args: CopyArgs, name: Tag, path: &str) -> Result<OutputStream, ShellError>;
|
||||
fn mkdir(&self, args: MkdirArgs, name: Tag, path: &str) -> Result<OutputStream, ShellError>;
|
||||
fn mv(&self, args: MoveArgs, name: Tag, path: &str) -> Result<OutputStream, ShellError>;
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::commands::cd::CdArgs;
|
||||
use crate::commands::command::{EvaluatedWholeStreamCommandArgs, RunnablePerItemContext};
|
||||
use crate::commands::cp::CopyArgs;
|
||||
use crate::commands::ls::LsArgs;
|
||||
@ -141,10 +142,10 @@ impl ShellManager {
|
||||
env[self.current_shell()].ls(args, context)
|
||||
}
|
||||
|
||||
pub fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError> {
|
||||
pub fn cd(&self, args: CdArgs, context: &RunnableContext) -> Result<OutputStream, ShellError> {
|
||||
let env = self.shells.lock();
|
||||
|
||||
env[self.current_shell()].cd(args)
|
||||
env[self.current_shell()].cd(args, context.name.clone())
|
||||
}
|
||||
|
||||
pub fn cp(
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::commands::cd::CdArgs;
|
||||
use crate::commands::command::EvaluatedWholeStreamCommandArgs;
|
||||
use crate::commands::cp::CopyArgs;
|
||||
use crate::commands::ls::LsArgs;
|
||||
@ -7,11 +8,14 @@ use crate::commands::rm::RemoveArgs;
|
||||
use crate::prelude::*;
|
||||
use crate::shell::shell::Shell;
|
||||
use crate::utils::ValueStructure;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ReturnSuccess, ShellTypeName, UntaggedValue, Value};
|
||||
|
||||
use std::ffi::OsStr;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ReturnSuccess, ShellTypeName, UntaggedValue, Value};
|
||||
use nu_source::Tagged;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ValueShell {
|
||||
pub(crate) path: String,
|
||||
@ -127,19 +131,18 @@ impl Shell for ValueShell {
|
||||
Ok(output.into())
|
||||
}
|
||||
|
||||
fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let destination = args.nth(0);
|
||||
fn cd(&self, args: CdArgs, name: Tag) -> Result<OutputStream, ShellError> {
|
||||
let destination = args.path;
|
||||
|
||||
let path = match destination {
|
||||
None => "/".to_string(),
|
||||
Some(v) => {
|
||||
let target = v.as_path()?;
|
||||
|
||||
Some(ref v) => {
|
||||
let Tagged { item: target, .. } = v;
|
||||
let mut cwd = PathBuf::from(&self.path);
|
||||
|
||||
if target == PathBuf::from("..") {
|
||||
if target == &PathBuf::from("..") {
|
||||
cwd.pop();
|
||||
} else if target == PathBuf::from("-") {
|
||||
} else if target == &PathBuf::from("-") {
|
||||
cwd = PathBuf::from(&self.last_path);
|
||||
} else {
|
||||
match target.to_str() {
|
||||
@ -169,7 +172,7 @@ impl Shell for ValueShell {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Can not change to path inside",
|
||||
"No such path exists",
|
||||
&args.call_info.name_tag,
|
||||
&name,
|
||||
));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user