Fix bugs. Add shells command

This commit is contained in:
Jonathan Turner 2019-08-08 05:20:38 +12:00
parent cd3f77f4e8
commit b1d92306c2
13 changed files with 119 additions and 13 deletions

View File

@ -162,11 +162,11 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
command("from-yaml", Box::new(from_yaml::from_yaml)),
command("get", Box::new(get::get)),
command("enter", Box::new(enter::enter)),
command("exit", Box::new(exit::exit)),
command("n", Box::new(next::next)),
command("p", Box::new(prev::prev)),
command("lines", Box::new(lines::lines)),
command("pick", Box::new(pick::pick)),
command("shells", Box::new(shells::shells)),
command("split-column", Box::new(split_column::split_column)),
command("split-row", Box::new(split_row::split_row)),
command("lines", Box::new(lines::lines)),
@ -185,15 +185,16 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
Arc::new(Date),
Arc::new(Where),
Arc::new(Config),
Arc::new(Exit),
Arc::new(SkipWhile),
]);
context.add_sinks(vec![
sink("autoview", Box::new(autoview::autoview)),
sink("clip", Box::new(clip::clip)),
sink("save", Box::new(save::save)),
sink("table", Box::new(table::table)),
sink("vtable", Box::new(vtable::vtable)),
Arc::new(Save),
]);
}
let _ = load_plugins(&mut context);

View File

@ -31,6 +31,7 @@ crate mod ps;
crate mod reject;
crate mod rm;
crate mod save;
crate mod shells;
crate mod size;
crate mod skip_while;
crate mod sort_by;
@ -51,7 +52,9 @@ crate use command::command;
crate use config::Config;
crate use cp::Copycp;
crate use date::Date;
crate use exit::Exit;
crate use open::Open;
crate use rm::Remove;
crate use save::Save;
crate use skip_while::SkipWhile;
crate use where_::Where;

View File

@ -151,7 +151,7 @@ impl InternalCommand {
context.add_span_source(uuid, span_source);
}
CommandAction::Exit => std::process::exit(0),
CommandAction::Enter(location) => {
CommandAction::EnterShell(location) => {
let path = std::path::Path::new(&location);
if path.is_dir() {
@ -195,6 +195,12 @@ impl InternalCommand {
CommandAction::NextShell => {
context.shell_manager.next();
}
CommandAction::LeaveShell => {
context.shell_manager.pop();
if context.shell_manager.is_empty() {
std::process::exit(0);
}
}
},
ReturnSuccess::Value(v) => {

View File

@ -62,9 +62,10 @@ pub enum CommandAction {
ChangePath(String),
AddSpanSource(Uuid, SpanSource),
Exit,
Enter(String),
EnterShell(String),
PreviousShell,
NextShell,
LeaveShell,
}
#[derive(Debug, Serialize, Deserialize)]

View File

@ -3,9 +3,10 @@ use crate::errors::ShellError;
use crate::prelude::*;
pub fn enter(args: CommandArgs) -> Result<OutputStream, ShellError> {
//TODO: We could also enter a value in the stream
if args.len() == 0 {
return Err(ShellError::labeled_error(
"First requires an amount",
"Enter requires a path",
"needs parameter",
args.call_info.name_span,
));
@ -13,5 +14,8 @@ pub fn enter(args: CommandArgs) -> Result<OutputStream, ShellError> {
let location = args.expect_nth(0)?.as_string()?;
Ok(vec![Ok(ReturnSuccess::Action(CommandAction::Enter(location)))].into())
Ok(vec![Ok(ReturnSuccess::Action(CommandAction::EnterShell(
location,
)))]
.into())
}

View File

@ -1,7 +1,39 @@
use crate::commands::command::CommandAction;
use crate::errors::ShellError;
use crate::parser::registry::{CommandConfig, NamedType};
use crate::prelude::*;
use indexmap::IndexMap;
pub fn exit(_args: CommandArgs) -> Result<OutputStream, ShellError> {
Ok(vec![Ok(ReturnSuccess::Action(CommandAction::Exit))].into())
pub struct Exit;
impl Command for Exit {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
exit(args)
}
fn name(&self) -> &str {
"exit"
}
fn config(&self) -> CommandConfig {
let mut named: IndexMap<String, NamedType> = IndexMap::new();
named.insert("now".to_string(), NamedType::Switch);
CommandConfig {
name: self.name().to_string(),
positional: vec![],
rest_positional: false,
named,
is_sink: false,
is_filter: false,
}
}
}
pub fn exit(args: CommandArgs) -> Result<OutputStream, ShellError> {
if args.call_info.args.has("now") {
Ok(vec![Ok(ReturnSuccess::Action(CommandAction::Exit))].into())
} else {
Ok(vec![Ok(ReturnSuccess::Action(CommandAction::LeaveShell))].into())
}
}

View File

@ -5,9 +5,38 @@ use crate::commands::to_toml::value_to_toml_value;
use crate::commands::to_yaml::value_to_yaml_value;
use crate::errors::ShellError;
use crate::object::{Primitive, Value};
use crate::parser::registry::{CommandConfig, NamedType};
use crate::prelude::*;
use crate::SpanSource;
use indexmap::IndexMap;
use std::path::{Path, PathBuf};
pub struct Save;
impl Sink for Save {
fn run(&self, args: SinkCommandArgs) -> Result<(), ShellError> {
save(args)
}
fn name(&self) -> &str {
"save"
}
fn config(&self) -> CommandConfig {
let mut named: IndexMap<String, NamedType> = IndexMap::new();
named.insert("raw".to_string(), NamedType::Switch);
CommandConfig {
name: self.name().to_string(),
positional: vec![],
rest_positional: false,
named,
is_sink: false,
is_filter: false,
}
}
}
pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
let cwd = args.ctx.shell_manager.path();
let mut full_path = PathBuf::from(cwd);

18
src/commands/shells.rs Normal file
View File

@ -0,0 +1,18 @@
use crate::errors::ShellError;
use crate::object::TaggedDictBuilder;
use crate::prelude::*;
pub fn shells(args: CommandArgs) -> Result<OutputStream, ShellError> {
let mut shells_out = VecDeque::new();
let span = args.call_info.name_span;
for shell in args.shell_manager.shells.lock().unwrap().iter() {
let mut dict = TaggedDictBuilder::new(Tag::unknown_origin(span));
dict.insert("name", shell.name());
dict.insert("path", shell.path());
shells_out.push_back(dict.into_tagged_value());
}
Ok(shells_out.to_output_stream())
}

View File

@ -96,10 +96,6 @@ impl Context {
command.run(command_args)
}
pub fn clone_commands(&self) -> indexmap::IndexMap<String, Arc<dyn Command>> {
self.commands.clone()
}
crate fn has_command(&self, name: &str) -> bool {
self.commands.contains_key(name)
}

View File

@ -50,6 +50,10 @@ impl FilesystemShell {
}
impl Shell for FilesystemShell {
fn name(&self) -> String {
"filesystem".to_string()
}
fn ls(&self, call_info: CallInfo, _input: InputStream) -> Result<OutputStream, ShellError> {
let cwd = self.path.clone();
let mut full_path = PathBuf::from(&self.path);

View File

@ -8,6 +8,7 @@ where
Self: Completer<Candidate = rustyline::completion::Pair>,
Self: Hinter,
{
fn name(&self) -> String;
fn ls(&self, call_info: CallInfo, input: InputStream) -> Result<OutputStream, ShellError>;
fn cd(&self, call_info: CallInfo, input: InputStream) -> Result<OutputStream, ShellError>;
fn path(&self) -> String;

View File

@ -25,6 +25,14 @@ impl ShellManager {
self.set_path(self.path());
}
pub fn pop(&mut self) {
self.shells.lock().unwrap().pop();
}
pub fn is_empty(&self) -> bool {
self.shells.lock().unwrap().is_empty()
}
pub fn path(&self) -> String {
self.shells.lock().unwrap().last().unwrap().path()
}

View File

@ -56,6 +56,10 @@ impl ValueShell {
}
impl Shell for ValueShell {
fn name(&self) -> String {
"value".to_string()
}
fn ls(&self, _call_info: CallInfo, _input: InputStream) -> Result<OutputStream, ShellError> {
Ok(self
.members()
@ -110,7 +114,6 @@ impl Completer for ValueShell {
_ctx: &rustyline::Context<'_>,
) -> Result<(usize, Vec<completion::Pair>), ReadlineError> {
let mut completions = vec![];
//let commands = vec!["testme", "whatever"];
let mut possible_completion = vec![];
let members = self.members();