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-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", SyntaxType::Block)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run(
|
|
|
|
&self,
|
2019-08-15 07:02:02 +02:00
|
|
|
call_info: &CallInfo,
|
2019-08-31 02:59:21 +02:00
|
|
|
registry: ®istry::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 PathBuf::from(location).is_dir() {
|
|
|
|
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,
|
|
|
|
Span::unknown(),
|
|
|
|
)
|
|
|
|
.await.unwrap();
|
|
|
|
|
|
|
|
if let Some(uuid) = contents_tag.origin {
|
|
|
|
// If we have loaded something, track its source
|
|
|
|
yield ReturnSuccess::action(CommandAction::AddSpanSource(
|
|
|
|
uuid,
|
|
|
|
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_span: raw_args.call_info.name_span,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
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(Tagged {
|
|
|
|
item,
|
|
|
|
..
|
|
|
|
})) => {
|
|
|
|
yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(
|
|
|
|
Tagged {
|
|
|
|
item: item,
|
|
|
|
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
|
|
|
}
|