Fix bugs. Add shells command
This commit is contained in:
parent
cd3f77f4e8
commit
b1d92306c2
|
@ -162,11 +162,11 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
||||||
command("from-yaml", Box::new(from_yaml::from_yaml)),
|
command("from-yaml", Box::new(from_yaml::from_yaml)),
|
||||||
command("get", Box::new(get::get)),
|
command("get", Box::new(get::get)),
|
||||||
command("enter", Box::new(enter::enter)),
|
command("enter", Box::new(enter::enter)),
|
||||||
command("exit", Box::new(exit::exit)),
|
|
||||||
command("n", Box::new(next::next)),
|
command("n", Box::new(next::next)),
|
||||||
command("p", Box::new(prev::prev)),
|
command("p", Box::new(prev::prev)),
|
||||||
command("lines", Box::new(lines::lines)),
|
command("lines", Box::new(lines::lines)),
|
||||||
command("pick", Box::new(pick::pick)),
|
command("pick", Box::new(pick::pick)),
|
||||||
|
command("shells", Box::new(shells::shells)),
|
||||||
command("split-column", Box::new(split_column::split_column)),
|
command("split-column", Box::new(split_column::split_column)),
|
||||||
command("split-row", Box::new(split_row::split_row)),
|
command("split-row", Box::new(split_row::split_row)),
|
||||||
command("lines", Box::new(lines::lines)),
|
command("lines", Box::new(lines::lines)),
|
||||||
|
@ -185,15 +185,16 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
||||||
Arc::new(Date),
|
Arc::new(Date),
|
||||||
Arc::new(Where),
|
Arc::new(Where),
|
||||||
Arc::new(Config),
|
Arc::new(Config),
|
||||||
|
Arc::new(Exit),
|
||||||
Arc::new(SkipWhile),
|
Arc::new(SkipWhile),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
context.add_sinks(vec![
|
context.add_sinks(vec![
|
||||||
sink("autoview", Box::new(autoview::autoview)),
|
sink("autoview", Box::new(autoview::autoview)),
|
||||||
sink("clip", Box::new(clip::clip)),
|
sink("clip", Box::new(clip::clip)),
|
||||||
sink("save", Box::new(save::save)),
|
|
||||||
sink("table", Box::new(table::table)),
|
sink("table", Box::new(table::table)),
|
||||||
sink("vtable", Box::new(vtable::vtable)),
|
sink("vtable", Box::new(vtable::vtable)),
|
||||||
|
Arc::new(Save),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
let _ = load_plugins(&mut context);
|
let _ = load_plugins(&mut context);
|
||||||
|
|
|
@ -31,6 +31,7 @@ crate mod ps;
|
||||||
crate mod reject;
|
crate mod reject;
|
||||||
crate mod rm;
|
crate mod rm;
|
||||||
crate mod save;
|
crate mod save;
|
||||||
|
crate mod shells;
|
||||||
crate mod size;
|
crate mod size;
|
||||||
crate mod skip_while;
|
crate mod skip_while;
|
||||||
crate mod sort_by;
|
crate mod sort_by;
|
||||||
|
@ -51,7 +52,9 @@ crate use command::command;
|
||||||
crate use config::Config;
|
crate use config::Config;
|
||||||
crate use cp::Copycp;
|
crate use cp::Copycp;
|
||||||
crate use date::Date;
|
crate use date::Date;
|
||||||
|
crate use exit::Exit;
|
||||||
crate use open::Open;
|
crate use open::Open;
|
||||||
crate use rm::Remove;
|
crate use rm::Remove;
|
||||||
|
crate use save::Save;
|
||||||
crate use skip_while::SkipWhile;
|
crate use skip_while::SkipWhile;
|
||||||
crate use where_::Where;
|
crate use where_::Where;
|
||||||
|
|
|
@ -151,7 +151,7 @@ impl InternalCommand {
|
||||||
context.add_span_source(uuid, span_source);
|
context.add_span_source(uuid, span_source);
|
||||||
}
|
}
|
||||||
CommandAction::Exit => std::process::exit(0),
|
CommandAction::Exit => std::process::exit(0),
|
||||||
CommandAction::Enter(location) => {
|
CommandAction::EnterShell(location) => {
|
||||||
let path = std::path::Path::new(&location);
|
let path = std::path::Path::new(&location);
|
||||||
|
|
||||||
if path.is_dir() {
|
if path.is_dir() {
|
||||||
|
@ -195,6 +195,12 @@ impl InternalCommand {
|
||||||
CommandAction::NextShell => {
|
CommandAction::NextShell => {
|
||||||
context.shell_manager.next();
|
context.shell_manager.next();
|
||||||
}
|
}
|
||||||
|
CommandAction::LeaveShell => {
|
||||||
|
context.shell_manager.pop();
|
||||||
|
if context.shell_manager.is_empty() {
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
ReturnSuccess::Value(v) => {
|
ReturnSuccess::Value(v) => {
|
||||||
|
|
|
@ -62,9 +62,10 @@ pub enum CommandAction {
|
||||||
ChangePath(String),
|
ChangePath(String),
|
||||||
AddSpanSource(Uuid, SpanSource),
|
AddSpanSource(Uuid, SpanSource),
|
||||||
Exit,
|
Exit,
|
||||||
Enter(String),
|
EnterShell(String),
|
||||||
PreviousShell,
|
PreviousShell,
|
||||||
NextShell,
|
NextShell,
|
||||||
|
LeaveShell,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
|
|
@ -3,9 +3,10 @@ use crate::errors::ShellError;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn enter(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
pub fn enter(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
|
//TODO: We could also enter a value in the stream
|
||||||
if args.len() == 0 {
|
if args.len() == 0 {
|
||||||
return Err(ShellError::labeled_error(
|
return Err(ShellError::labeled_error(
|
||||||
"First requires an amount",
|
"Enter requires a path",
|
||||||
"needs parameter",
|
"needs parameter",
|
||||||
args.call_info.name_span,
|
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()?;
|
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())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,39 @@
|
||||||
use crate::commands::command::CommandAction;
|
use crate::commands::command::CommandAction;
|
||||||
use crate::errors::ShellError;
|
use crate::errors::ShellError;
|
||||||
|
use crate::parser::registry::{CommandConfig, NamedType};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
pub fn exit(_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
pub struct Exit;
|
||||||
Ok(vec![Ok(ReturnSuccess::Action(CommandAction::Exit))].into())
|
|
||||||
|
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())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,38 @@ use crate::commands::to_toml::value_to_toml_value;
|
||||||
use crate::commands::to_yaml::value_to_yaml_value;
|
use crate::commands::to_yaml::value_to_yaml_value;
|
||||||
use crate::errors::ShellError;
|
use crate::errors::ShellError;
|
||||||
use crate::object::{Primitive, Value};
|
use crate::object::{Primitive, Value};
|
||||||
|
use crate::parser::registry::{CommandConfig, NamedType};
|
||||||
|
use crate::prelude::*;
|
||||||
use crate::SpanSource;
|
use crate::SpanSource;
|
||||||
|
use indexmap::IndexMap;
|
||||||
use std::path::{Path, PathBuf};
|
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> {
|
pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||||
let cwd = args.ctx.shell_manager.path();
|
let cwd = args.ctx.shell_manager.path();
|
||||||
let mut full_path = PathBuf::from(cwd);
|
let mut full_path = PathBuf::from(cwd);
|
||||||
|
|
18
src/commands/shells.rs
Normal file
18
src/commands/shells.rs
Normal 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())
|
||||||
|
}
|
|
@ -96,10 +96,6 @@ impl Context {
|
||||||
command.run(command_args)
|
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 {
|
crate fn has_command(&self, name: &str) -> bool {
|
||||||
self.commands.contains_key(name)
|
self.commands.contains_key(name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,10 @@ impl FilesystemShell {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Shell for FilesystemShell {
|
impl Shell for FilesystemShell {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"filesystem".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
fn ls(&self, call_info: CallInfo, _input: InputStream) -> Result<OutputStream, ShellError> {
|
fn ls(&self, call_info: CallInfo, _input: InputStream) -> Result<OutputStream, ShellError> {
|
||||||
let cwd = self.path.clone();
|
let cwd = self.path.clone();
|
||||||
let mut full_path = PathBuf::from(&self.path);
|
let mut full_path = PathBuf::from(&self.path);
|
||||||
|
|
|
@ -8,6 +8,7 @@ where
|
||||||
Self: Completer<Candidate = rustyline::completion::Pair>,
|
Self: Completer<Candidate = rustyline::completion::Pair>,
|
||||||
Self: Hinter,
|
Self: Hinter,
|
||||||
{
|
{
|
||||||
|
fn name(&self) -> String;
|
||||||
fn ls(&self, call_info: CallInfo, input: InputStream) -> Result<OutputStream, ShellError>;
|
fn ls(&self, call_info: CallInfo, input: InputStream) -> Result<OutputStream, ShellError>;
|
||||||
fn cd(&self, call_info: CallInfo, input: InputStream) -> Result<OutputStream, ShellError>;
|
fn cd(&self, call_info: CallInfo, input: InputStream) -> Result<OutputStream, ShellError>;
|
||||||
fn path(&self) -> String;
|
fn path(&self) -> String;
|
||||||
|
|
|
@ -25,6 +25,14 @@ impl ShellManager {
|
||||||
self.set_path(self.path());
|
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 {
|
pub fn path(&self) -> String {
|
||||||
self.shells.lock().unwrap().last().unwrap().path()
|
self.shells.lock().unwrap().last().unwrap().path()
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,10 @@ impl ValueShell {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Shell for ValueShell {
|
impl Shell for ValueShell {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"value".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
fn ls(&self, _call_info: CallInfo, _input: InputStream) -> Result<OutputStream, ShellError> {
|
fn ls(&self, _call_info: CallInfo, _input: InputStream) -> Result<OutputStream, ShellError> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.members()
|
.members()
|
||||||
|
@ -110,7 +114,6 @@ impl Completer for ValueShell {
|
||||||
_ctx: &rustyline::Context<'_>,
|
_ctx: &rustyline::Context<'_>,
|
||||||
) -> Result<(usize, Vec<completion::Pair>), ReadlineError> {
|
) -> Result<(usize, Vec<completion::Pair>), ReadlineError> {
|
||||||
let mut completions = vec![];
|
let mut completions = vec![];
|
||||||
//let commands = vec!["testme", "whatever"];
|
|
||||||
|
|
||||||
let mut possible_completion = vec![];
|
let mut possible_completion = vec![];
|
||||||
let members = self.members();
|
let members = self.members();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user