2019-08-31 02:59:21 +02:00
|
|
|
use crate::commands::UnevaluatedCallInfo;
|
2020-04-27 04:04:54 +02:00
|
|
|
use crate::commands::WholeStreamCommand;
|
Extract core stuff into own crates
This commit extracts five new crates:
- nu-source, which contains the core source-code handling logic in Nu,
including Text, Span, and also the pretty.rs-based debug logic
- nu-parser, which is the parser and expander logic
- nu-protocol, which is the bulk of the types and basic conveniences
used by plugins
- nu-errors, which contains ShellError, ParseError and error handling
conveniences
- nu-textview, which is the textview plugin extracted into a crate
One of the major consequences of this refactor is that it's no longer
possible to `impl X for Spanned<Y>` outside of the `nu-source` crate, so
a lot of types became more concrete (Value became a concrete type
instead of Spanned<Value>, for example).
This also turned a number of inherent methods in the main nu crate into
plain functions (impl Value {} became a bunch of functions in the
`value` namespace in `crate::data::value`).
2019-11-26 03:30:48 +01:00
|
|
|
use crate::context::CommandRegistry;
|
2019-08-07 19:49:11 +02:00
|
|
|
use crate::prelude::*;
|
Extract core stuff into own crates
This commit extracts five new crates:
- nu-source, which contains the core source-code handling logic in Nu,
including Text, Span, and also the pretty.rs-based debug logic
- nu-parser, which is the parser and expander logic
- nu-protocol, which is the bulk of the types and basic conveniences
used by plugins
- nu-errors, which contains ShellError, ParseError and error handling
conveniences
- nu-textview, which is the textview plugin extracted into a crate
One of the major consequences of this refactor is that it's no longer
possible to `impl X for Spanned<Y>` outside of the `nu-source` crate, so
a lot of types became more concrete (Value became a concrete type
instead of Spanned<Value>, for example).
This also turned a number of inherent methods in the main nu crate into
plain functions (impl Value {} became a bunch of functions in the
`value` namespace in `crate::data::value`).
2019-11-26 03:30:48 +01:00
|
|
|
use nu_errors::ShellError;
|
|
|
|
use nu_protocol::{
|
2020-04-27 04:04:54 +02:00
|
|
|
CommandAction, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
Extract core stuff into own crates
This commit extracts five new crates:
- nu-source, which contains the core source-code handling logic in Nu,
including Text, Span, and also the pretty.rs-based debug logic
- nu-parser, which is the parser and expander logic
- nu-protocol, which is the bulk of the types and basic conveniences
used by plugins
- nu-errors, which contains ShellError, ParseError and error handling
conveniences
- nu-textview, which is the textview plugin extracted into a crate
One of the major consequences of this refactor is that it's no longer
possible to `impl X for Spanned<Y>` outside of the `nu-source` crate, so
a lot of types became more concrete (Value became a concrete type
instead of Spanned<Value>, for example).
This also turned a number of inherent methods in the main nu crate into
plain functions (impl Value {} became a bunch of functions in the
`value` namespace in `crate::data::value`).
2019-11-26 03:30:48 +01:00
|
|
|
};
|
2020-04-27 04:04:54 +02:00
|
|
|
use nu_source::Tagged;
|
|
|
|
use std::path::PathBuf;
|
2019-08-07 19:49:11 +02:00
|
|
|
|
2019-08-14 19:02:39 +02:00
|
|
|
pub struct Enter;
|
2019-08-09 06:51:21 +02:00
|
|
|
|
2020-04-27 04:04:54 +02:00
|
|
|
#[derive(Deserialize)]
|
|
|
|
pub struct EnterArgs {
|
|
|
|
location: Tagged<PathBuf>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl WholeStreamCommand for Enter {
|
2019-08-14 19:02:39 +02:00
|
|
|
fn name(&self) -> &str {
|
|
|
|
"enter"
|
2019-08-07 19:49:11 +02:00
|
|
|
}
|
|
|
|
|
Extract core stuff into own crates
This commit extracts five new crates:
- nu-source, which contains the core source-code handling logic in Nu,
including Text, Span, and also the pretty.rs-based debug logic
- nu-parser, which is the parser and expander logic
- nu-protocol, which is the bulk of the types and basic conveniences
used by plugins
- nu-errors, which contains ShellError, ParseError and error handling
conveniences
- nu-textview, which is the textview plugin extracted into a crate
One of the major consequences of this refactor is that it's no longer
possible to `impl X for Spanned<Y>` outside of the `nu-source` crate, so
a lot of types became more concrete (Value became a concrete type
instead of Spanned<Value>, for example).
This also turned a number of inherent methods in the main nu crate into
plain functions (impl Value {} became a bunch of functions in the
`value` namespace in `crate::data::value`).
2019-11-26 03:30:48 +01:00
|
|
|
fn signature(&self) -> Signature {
|
2019-10-28 06:15:35 +01:00
|
|
|
Signature::build("enter").required(
|
|
|
|
"location",
|
|
|
|
SyntaxShape::Path,
|
|
|
|
"the location to create a new shell from",
|
|
|
|
)
|
2019-08-14 19:02:39 +02:00
|
|
|
}
|
|
|
|
|
2019-08-30 00:52:32 +02:00
|
|
|
fn usage(&self) -> &str {
|
|
|
|
"Create a new shell and begin at this path."
|
|
|
|
}
|
|
|
|
|
2019-08-14 19:02:39 +02:00
|
|
|
fn run(
|
|
|
|
&self,
|
2020-04-27 04:04:54 +02:00
|
|
|
args: CommandArgs,
|
Extract core stuff into own crates
This commit extracts five new crates:
- nu-source, which contains the core source-code handling logic in Nu,
including Text, Span, and also the pretty.rs-based debug logic
- nu-parser, which is the parser and expander logic
- nu-protocol, which is the bulk of the types and basic conveniences
used by plugins
- nu-errors, which contains ShellError, ParseError and error handling
conveniences
- nu-textview, which is the textview plugin extracted into a crate
One of the major consequences of this refactor is that it's no longer
possible to `impl X for Spanned<Y>` outside of the `nu-source` crate, so
a lot of types became more concrete (Value became a concrete type
instead of Spanned<Value>, for example).
This also turned a number of inherent methods in the main nu crate into
plain functions (impl Value {} became a bunch of functions in the
`value` namespace in `crate::data::value`).
2019-11-26 03:30:48 +01:00
|
|
|
registry: &CommandRegistry,
|
2019-08-24 21:36:19 +02:00
|
|
|
) -> Result<OutputStream, ShellError> {
|
2020-04-27 04:04:54 +02:00
|
|
|
Ok(args.process_raw(registry, enter)?.run())
|
|
|
|
}
|
|
|
|
}
|
2019-08-30 00:52:32 +02:00
|
|
|
|
2020-04-27 04:04:54 +02:00
|
|
|
fn enter(
|
|
|
|
EnterArgs { location }: EnterArgs,
|
|
|
|
RunnableContext {
|
|
|
|
registry,
|
|
|
|
name: tag,
|
|
|
|
..
|
|
|
|
}: RunnableContext,
|
|
|
|
raw_args: RawCommandArgs,
|
|
|
|
) -> Result<OutputStream, ShellError> {
|
|
|
|
let location_string = location.display().to_string();
|
|
|
|
let location_clone = location_string.clone();
|
2019-09-03 11:05:52 +02:00
|
|
|
|
2020-04-27 04:04:54 +02:00
|
|
|
if location_string.starts_with("help") {
|
|
|
|
let spec = location_string.split(':').collect::<Vec<&str>>();
|
2019-09-03 11:05:52 +02:00
|
|
|
|
2020-04-27 04:04:54 +02:00
|
|
|
if spec.len() == 2 {
|
|
|
|
let (_, command) = (spec[0], spec[1]);
|
2019-08-31 02:59:21 +02:00
|
|
|
|
2020-04-27 04:04:54 +02:00
|
|
|
if registry.has(command) {
|
|
|
|
return Ok(vec![Ok(ReturnSuccess::Action(CommandAction::EnterHelpShell(
|
|
|
|
UntaggedValue::string(command).into_value(Tag::unknown()),
|
|
|
|
)))]
|
|
|
|
.into());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(vec![Ok(ReturnSuccess::Action(CommandAction::EnterHelpShell(
|
|
|
|
UntaggedValue::nothing().into_value(Tag::unknown()),
|
|
|
|
)))]
|
|
|
|
.into())
|
|
|
|
} else if location.is_dir() {
|
|
|
|
Ok(vec![Ok(ReturnSuccess::Action(CommandAction::EnterShell(
|
|
|
|
location_clone,
|
|
|
|
)))]
|
|
|
|
.into())
|
|
|
|
} else {
|
|
|
|
let stream = async_stream! {
|
|
|
|
// If it's a file, attempt to open the file as a value and enter it
|
|
|
|
let cwd = raw_args.shell_manager.path();
|
2019-08-31 02:59:21 +02:00
|
|
|
|
2020-04-27 04:04:54 +02:00
|
|
|
let full_path = std::path::PathBuf::from(cwd);
|
2019-08-31 02:59:21 +02:00
|
|
|
|
2020-04-27 04:04:54 +02:00
|
|
|
let (file_extension, contents, contents_tag) =
|
|
|
|
crate::commands::open::fetch(
|
|
|
|
&full_path,
|
|
|
|
&PathBuf::from(location_clone),
|
|
|
|
tag.span,
|
|
|
|
).await?;
|
2019-08-31 02:59:21 +02:00
|
|
|
|
2020-04-27 04:04:54 +02:00
|
|
|
match contents {
|
|
|
|
UntaggedValue::Primitive(Primitive::String(_)) => {
|
|
|
|
let tagged_contents = contents.into_value(&contents_tag);
|
|
|
|
|
|
|
|
if let Some(extension) = file_extension {
|
|
|
|
let command_name = format!("from-{}", extension);
|
|
|
|
if let Some(converter) =
|
|
|
|
registry.get_command(&command_name)
|
|
|
|
{
|
|
|
|
let new_args = RawCommandArgs {
|
|
|
|
host: raw_args.host,
|
|
|
|
ctrl_c: raw_args.ctrl_c,
|
|
|
|
shell_manager: raw_args.shell_manager,
|
|
|
|
call_info: UnevaluatedCallInfo {
|
|
|
|
args: nu_protocol::hir::Call {
|
|
|
|
head: raw_args.call_info.args.head,
|
|
|
|
positional: None,
|
|
|
|
named: None,
|
|
|
|
span: Span::unknown(),
|
|
|
|
is_last: false,
|
|
|
|
},
|
|
|
|
name_tag: raw_args.call_info.name_tag,
|
|
|
|
scope: raw_args.call_info.scope.clone()
|
|
|
|
},
|
|
|
|
};
|
|
|
|
let mut result = converter.run(
|
|
|
|
new_args.with_input(vec![tagged_contents]),
|
|
|
|
®istry,
|
|
|
|
);
|
|
|
|
let result_vec: Vec<Result<ReturnSuccess, ShellError>> =
|
|
|
|
result.drain_vec().await;
|
|
|
|
for res in result_vec {
|
|
|
|
match res {
|
|
|
|
Ok(ReturnSuccess::Value(Value {
|
|
|
|
value,
|
|
|
|
..
|
|
|
|
})) => {
|
|
|
|
yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(
|
|
|
|
Value {
|
|
|
|
value,
|
|
|
|
tag: contents_tag.clone(),
|
|
|
|
})));
|
2019-08-31 02:59:21 +02:00
|
|
|
}
|
2020-04-27 04:04:54 +02:00
|
|
|
x => yield x,
|
2019-08-31 02:59:21 +02:00
|
|
|
}
|
|
|
|
}
|
2020-04-27 04:04:54 +02:00
|
|
|
} else {
|
|
|
|
yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(tagged_contents)));
|
2019-08-31 02:59:21 +02:00
|
|
|
}
|
2020-04-27 04:04:54 +02:00
|
|
|
} else {
|
|
|
|
yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(tagged_contents)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
let tagged_contents = contents.into_value(contents_tag);
|
|
|
|
|
|
|
|
yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(tagged_contents)));
|
2019-08-31 02:59:21 +02:00
|
|
|
}
|
|
|
|
}
|
2020-04-27 04:04:54 +02:00
|
|
|
};
|
|
|
|
Ok(stream.to_output_stream())
|
2019-08-14 19:02:39 +02:00
|
|
|
}
|
2019-08-07 19:49:11 +02:00
|
|
|
}
|