nushell/src/commands/enter.rs

158 lines
7.0 KiB
Rust
Raw Normal View History

2019-08-07 19:49:11 +02:00
use crate::commands::command::CommandAction;
2019-08-15 07:02:02 +02:00
use crate::commands::PerItemCommand;
2019-08-31 02:59:21 +02:00
use crate::commands::UnevaluatedCallInfo;
2019-09-18 08:37:04 +02:00
use crate::data::meta::Span;
2019-08-07 19:49:11 +02:00
use crate::errors::ShellError;
2019-08-14 19:02:39 +02:00
use crate::parser::registry;
2019-08-07 19:49:11 +02:00
use crate::prelude::*;
2019-08-31 02:59:21 +02:00
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
2019-08-14 19:02:39 +02:00
impl PerItemCommand for Enter {
fn name(&self) -> &str {
"enter"
2019-08-07 19:49:11 +02:00
}
2019-08-14 19:02:39 +02:00
fn signature(&self) -> registry::Signature {
Signature::build("enter").required("location", SyntaxShape::Block)
2019-08-14 19:02:39 +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,
2019-08-15 07:02:02 +02:00
call_info: &CallInfo,
2019-08-31 02:59:21 +02:00
registry: &registry::CommandRegistry,
raw_args: &RawCommandArgs,
2019-08-15 07:02:02 +02:00
_input: Tagged<Value>,
2019-08-24 21:36:19 +02:00
) -> Result<OutputStream, ShellError> {
2019-08-31 02:59:21 +02:00
let registry = registry.clone();
let raw_args = raw_args.clone();
2019-08-14 19:02:39 +02:00
match call_info.args.expect_nth(0)? {
Tagged {
item: Value::Primitive(Primitive::String(location)),
..
2019-08-31 02:59:21 +02:00
} => {
let location = location.to_string();
let location_clone = location.to_string();
if location.starts_with("help") {
let spec = location.split(":").collect::<Vec<&str>>();
let (_, command) = (spec[0], spec[1]);
if registry.has(command) {
Ok(vec![Ok(ReturnSuccess::Action(CommandAction::EnterHelpShell(
Value::string(command).tagged(Tag::unknown()),
)))]
.into())
} else {
Ok(vec![Ok(ReturnSuccess::Action(CommandAction::EnterHelpShell(
Value::nothing().tagged(Tag::unknown()),
)))]
.into())
}
} else if PathBuf::from(location).is_dir() {
2019-08-31 02:59:21 +02:00
Ok(vec![Ok(ReturnSuccess::Action(CommandAction::EnterShell(
location_clone,
)))]
.into())
} else {
let stream = async_stream_block! {
// If it's a file, attempt to open the file as a value and enter it
let cwd = raw_args.shell_manager.path();
let full_path = std::path::PathBuf::from(cwd);
let (file_extension, contents, contents_tag, span_source) =
crate::commands::open::fetch(
&full_path,
&location_clone,
2019-09-18 08:37:04 +02:00
Span::unknown(),
2019-08-31 02:59:21 +02:00
)
.await.unwrap();
if contents_tag.origin != uuid::Uuid::nil() {
2019-08-31 02:59:21 +02:00
// If we have loaded something, track its source
yield ReturnSuccess::action(CommandAction::AddSpanSource(
contents_tag.origin,
2019-08-31 02:59:21 +02:00
span_source,
));
}
match contents {
Value::Primitive(Primitive::String(_)) => {
let tagged_contents = contents.tagged(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,
shell_manager: raw_args.shell_manager,
call_info: UnevaluatedCallInfo {
args: crate::parser::hir::Call {
head: raw_args.call_info.args.head,
positional: None,
named: None,
},
source: raw_args.call_info.source,
source_map: raw_args.call_info.source_map,
name_tag: raw_args.call_info.name_tag,
2019-08-31 02:59:21 +02:00
},
};
let mut result = converter.run(
new_args.with_input(vec![tagged_contents]),
&registry,
2019-09-17 04:09:15 +02:00
false
2019-08-31 02:59:21 +02:00
);
let result_vec: Vec<Result<ReturnSuccess, ShellError>> =
result.drain_vec().await;
for res in result_vec {
match res {
Ok(ReturnSuccess::Value(Tagged {
item,
..
})) => {
yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(
Tagged {
item,
2019-08-31 02:59:21 +02:00
tag: contents_tag,
})));
}
x => yield x,
}
}
} else {
yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(tagged_contents)));
}
} else {
yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(tagged_contents)));
}
}
_ => {
let tagged_contents = contents.tagged(contents_tag);
yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(tagged_contents)));
}
}
};
Ok(stream.to_output_stream())
}
}
2019-08-14 19:02:39 +02:00
x => Ok(
vec![Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(
x.clone(),
)))]
.into(),
),
}
}
2019-08-07 19:49:11 +02:00
}