WIP
This commit is contained in:
parent
52ea14cb25
commit
ab8176d4c7
16
src/cli.rs
16
src/cli.rs
|
@ -223,19 +223,11 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cwd = {
|
let cwd = context.shell_manager.path();
|
||||||
context
|
|
||||||
.env
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.last()
|
|
||||||
.unwrap()
|
|
||||||
.path()
|
|
||||||
.display()
|
|
||||||
.to_string()
|
|
||||||
};
|
|
||||||
|
|
||||||
rl.set_helper(Some(crate::shell::Helper::new(context.env.clone())));
|
rl.set_helper(Some(crate::shell::Helper::new(
|
||||||
|
context.shell_manager.clone(),
|
||||||
|
)));
|
||||||
|
|
||||||
let readline = rl.readline(&format!(
|
let readline = rl.readline(&format!(
|
||||||
"{}{}> ",
|
"{}{}> ",
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
use crate::errors::ShellError;
|
use crate::errors::ShellError;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::shell::shell::Shell;
|
|
||||||
|
|
||||||
pub fn cd(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
pub fn cd(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let env = args.env.lock().unwrap();
|
args.shell_manager.cd(args.call_info, args.input)
|
||||||
|
|
||||||
env.last().unwrap().cd(args.call_info, args.input)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,13 +145,7 @@ impl InternalCommand {
|
||||||
match item? {
|
match item? {
|
||||||
ReturnSuccess::Action(action) => match action {
|
ReturnSuccess::Action(action) => match action {
|
||||||
CommandAction::ChangePath(path) => {
|
CommandAction::ChangePath(path) => {
|
||||||
let result = context
|
context.shell_manager.set_path(&path);
|
||||||
.env
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.last_mut()
|
|
||||||
.unwrap()
|
|
||||||
.set_path(path);
|
|
||||||
}
|
}
|
||||||
CommandAction::AddSpanSource(uuid, span_source) => {
|
CommandAction::AddSpanSource(uuid, span_source) => {
|
||||||
context.add_span_source(uuid, span_source);
|
context.add_span_source(uuid, span_source);
|
||||||
|
@ -159,20 +153,14 @@ impl InternalCommand {
|
||||||
CommandAction::Exit => std::process::exit(0),
|
CommandAction::Exit => std::process::exit(0),
|
||||||
CommandAction::Enter(location) => {
|
CommandAction::Enter(location) => {
|
||||||
context
|
context
|
||||||
.env
|
.shell_manager
|
||||||
.lock()
|
.push(Box::new(FilesystemShell::with_location(location)?));
|
||||||
.unwrap()
|
|
||||||
.push(Box::new(Environment::with_location(location)?));
|
|
||||||
}
|
}
|
||||||
CommandAction::PreviousShell => {
|
CommandAction::PreviousShell => {
|
||||||
let mut x = context.env.lock().unwrap();
|
context.shell_manager.prev();
|
||||||
let shell = x.pop().unwrap();
|
|
||||||
x.insert(0, shell);
|
|
||||||
}
|
}
|
||||||
CommandAction::NextShell => {
|
CommandAction::NextShell => {
|
||||||
let mut x = context.env.lock().unwrap();
|
context.shell_manager.next();
|
||||||
let shell = x.remove(0);
|
|
||||||
x.push(shell);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -321,7 +309,7 @@ impl ExternalCommand {
|
||||||
|
|
||||||
process = Exec::shell(new_arg_string);
|
process = Exec::shell(new_arg_string);
|
||||||
}
|
}
|
||||||
process = process.cwd(context.env.lock().unwrap().last().unwrap().path());
|
process = process.cwd(context.shell_manager.path());
|
||||||
|
|
||||||
let mut process = match stream_next {
|
let mut process = match stream_next {
|
||||||
StreamNext::Last => process,
|
StreamNext::Last => process,
|
||||||
|
|
|
@ -4,7 +4,6 @@ use crate::errors::ShellError;
|
||||||
use crate::object::Value;
|
use crate::object::Value;
|
||||||
use crate::parser::registry::{self, Args};
|
use crate::parser::registry::{self, Args};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::shell::shell::Shell;
|
|
||||||
use getset::Getters;
|
use getset::Getters;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -21,7 +20,7 @@ pub struct CallInfo {
|
||||||
#[get = "crate"]
|
#[get = "crate"]
|
||||||
pub struct CommandArgs {
|
pub struct CommandArgs {
|
||||||
pub host: Arc<Mutex<dyn Host + Send>>,
|
pub host: Arc<Mutex<dyn Host + Send>>,
|
||||||
pub env: Arc<Mutex<Vec<Box<dyn Shell>>>>,
|
pub shell_manager: ShellManager,
|
||||||
pub call_info: CallInfo,
|
pub call_info: CallInfo,
|
||||||
pub input: InputStream,
|
pub input: InputStream,
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::parser::hir::SyntaxType;
|
||||||
use crate::parser::registry::{CommandConfig, NamedType, PositionalType};
|
use crate::parser::registry::{CommandConfig, NamedType, PositionalType};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
pub struct Copycp;
|
pub struct Copycp;
|
||||||
|
|
||||||
|
@ -32,22 +32,8 @@ impl Command for Copycp {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cp(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
pub fn cp(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let mut source = args
|
let mut source = PathBuf::from(args.shell_manager.path());
|
||||||
.env
|
let mut destination = PathBuf::from(args.shell_manager.path());
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.last()
|
|
||||||
.unwrap()
|
|
||||||
.path()
|
|
||||||
.to_path_buf();
|
|
||||||
let mut destination = args
|
|
||||||
.env
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.last()
|
|
||||||
.unwrap()
|
|
||||||
.path()
|
|
||||||
.to_path_buf();
|
|
||||||
|
|
||||||
let mut dst = String::new();
|
let mut dst = String::new();
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,5 @@ use crate::errors::ShellError;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let env = args.env.lock().unwrap();
|
args.shell_manager.ls(args.call_info, args.input)
|
||||||
|
|
||||||
env.last().unwrap().ls(args.call_info, args.input)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,13 +12,7 @@ command! {
|
||||||
let span = args.call_info.name_span;
|
let span = args.call_info.name_span;
|
||||||
|
|
||||||
let cwd = args
|
let cwd = args
|
||||||
.env
|
.shell_manager.path();
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.last()
|
|
||||||
.unwrap()
|
|
||||||
.path()
|
|
||||||
.to_path_buf();
|
|
||||||
|
|
||||||
let full_path = PathBuf::from(cwd);
|
let full_path = PathBuf::from(cwd);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::prelude::*;
|
||||||
|
|
||||||
use glob::glob;
|
use glob::glob;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub struct Remove;
|
pub struct Remove;
|
||||||
|
|
||||||
|
@ -33,14 +34,7 @@ impl Command for Remove {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rm(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
pub fn rm(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let mut full_path = args
|
let mut full_path = PathBuf::from(args.shell_manager.path());
|
||||||
.env
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.last()
|
|
||||||
.unwrap()
|
|
||||||
.path()
|
|
||||||
.to_path_buf();
|
|
||||||
|
|
||||||
match args
|
match args
|
||||||
.nth(0)
|
.nth(0)
|
||||||
|
|
|
@ -9,15 +9,7 @@ use crate::SpanSource;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
|
pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||||
let cwd = args
|
let cwd = args.ctx.shell_manager.path();
|
||||||
.ctx
|
|
||||||
.env
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.last()
|
|
||||||
.unwrap()
|
|
||||||
.path()
|
|
||||||
.to_path_buf();
|
|
||||||
let mut full_path = PathBuf::from(cwd);
|
let mut full_path = PathBuf::from(cwd);
|
||||||
|
|
||||||
let save_raw = if args.call_info.args.has("raw") {
|
let save_raw = if args.call_info.args.has("raw") {
|
||||||
|
|
|
@ -38,7 +38,7 @@ pub struct Context {
|
||||||
sinks: IndexMap<String, Arc<dyn Sink>>,
|
sinks: IndexMap<String, Arc<dyn Sink>>,
|
||||||
crate source_map: SourceMap,
|
crate source_map: SourceMap,
|
||||||
crate host: Arc<Mutex<dyn Host + Send>>,
|
crate host: Arc<Mutex<dyn Host + Send>>,
|
||||||
crate env: Arc<Mutex<Vec<Box<dyn Shell>>>>,
|
crate shell_manager: ShellManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
|
@ -48,7 +48,7 @@ impl Context {
|
||||||
sinks: indexmap::IndexMap::new(),
|
sinks: indexmap::IndexMap::new(),
|
||||||
source_map: SourceMap::new(),
|
source_map: SourceMap::new(),
|
||||||
host: Arc::new(Mutex::new(crate::env::host::BasicHost)),
|
host: Arc::new(Mutex::new(crate::env::host::BasicHost)),
|
||||||
env: Arc::new(Mutex::new(vec![Box::new(Environment::basic()?)])),
|
shell_manager: ShellManager::basic()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ impl Context {
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
let command_args = CommandArgs {
|
let command_args = CommandArgs {
|
||||||
host: self.host.clone(),
|
host: self.host.clone(),
|
||||||
env: self.env.clone(),
|
shell_manager: self.shell_manager.clone(),
|
||||||
call_info: CallInfo {
|
call_info: CallInfo {
|
||||||
name_span,
|
name_span,
|
||||||
source_map,
|
source_map,
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
crate mod environment;
|
|
||||||
crate mod host;
|
crate mod host;
|
||||||
|
|
||||||
crate use self::environment::Environment;
|
|
||||||
crate use self::host::Host;
|
crate use self::host::Host;
|
||||||
|
|
|
@ -38,12 +38,13 @@ crate use crate::commands::command::{
|
||||||
};
|
};
|
||||||
crate use crate::context::{Context, SpanSource};
|
crate use crate::context::{Context, SpanSource};
|
||||||
crate use crate::env::host::handle_unexpected;
|
crate use crate::env::host::handle_unexpected;
|
||||||
crate use crate::env::{Environment, Host};
|
crate use crate::env::Host;
|
||||||
crate use crate::errors::ShellError;
|
crate use crate::errors::ShellError;
|
||||||
crate use crate::object::meta::{Tag, Tagged, TaggedItem};
|
crate use crate::object::meta::{Tag, Tagged, TaggedItem};
|
||||||
crate use crate::object::types::ExtractType;
|
crate use crate::object::types::ExtractType;
|
||||||
crate use crate::object::{Primitive, Value};
|
crate use crate::object::{Primitive, Value};
|
||||||
crate use crate::shell::shell::Shell;
|
crate use crate::shell::filesystem_shell::FilesystemShell;
|
||||||
|
crate use crate::shell::shell_manager::ShellManager;
|
||||||
crate use crate::stream::{InputStream, OutputStream};
|
crate use crate::stream::{InputStream, OutputStream};
|
||||||
crate use crate::Span;
|
crate use crate::Span;
|
||||||
crate use crate::Text;
|
crate use crate::Text;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
crate mod completer;
|
crate mod completer;
|
||||||
|
crate mod filesystem_shell;
|
||||||
crate mod helper;
|
crate mod helper;
|
||||||
crate mod shell;
|
crate mod shell;
|
||||||
|
crate mod shell_manager;
|
||||||
|
|
||||||
crate use helper::Helper;
|
crate use helper::Helper;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::prelude::*;
|
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use rustyline::completion::Completer;
|
use rustyline::completion::Completer;
|
||||||
use rustyline::completion::{self, FilenameCompleter};
|
use rustyline::completion::{self, FilenameCompleter};
|
||||||
|
|
|
@ -7,15 +7,15 @@ use rustyline::completion::{self, Completer, FilenameCompleter};
|
||||||
use rustyline::error::ReadlineError;
|
use rustyline::error::ReadlineError;
|
||||||
use rustyline::hint::{Hinter, HistoryHinter};
|
use rustyline::hint::{Hinter, HistoryHinter};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
pub struct Environment {
|
pub struct FilesystemShell {
|
||||||
crate path: PathBuf,
|
crate path: PathBuf,
|
||||||
completer: NuCompleter,
|
completer: NuCompleter,
|
||||||
hinter: HistoryHinter,
|
hinter: HistoryHinter,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Environment {
|
impl Clone for FilesystemShell {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Environment {
|
FilesystemShell {
|
||||||
path: self.path.clone(),
|
path: self.path.clone(),
|
||||||
completer: NuCompleter {
|
completer: NuCompleter {
|
||||||
file_completer: FilenameCompleter::new(),
|
file_completer: FilenameCompleter::new(),
|
||||||
|
@ -25,11 +25,11 @@ impl Clone for Environment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Environment {
|
impl FilesystemShell {
|
||||||
pub fn basic() -> Result<Environment, std::io::Error> {
|
pub fn basic() -> Result<FilesystemShell, std::io::Error> {
|
||||||
let path = std::env::current_dir()?;
|
let path = std::env::current_dir()?;
|
||||||
|
|
||||||
Ok(Environment {
|
Ok(FilesystemShell {
|
||||||
path,
|
path,
|
||||||
completer: NuCompleter {
|
completer: NuCompleter {
|
||||||
file_completer: FilenameCompleter::new(),
|
file_completer: FilenameCompleter::new(),
|
||||||
|
@ -38,10 +38,10 @@ impl Environment {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_location(location: String) -> Result<Environment, std::io::Error> {
|
pub fn with_location(location: String) -> Result<FilesystemShell, std::io::Error> {
|
||||||
let path = std::path::PathBuf::from(location);
|
let path = std::path::PathBuf::from(location);
|
||||||
|
|
||||||
Ok(Environment {
|
Ok(FilesystemShell {
|
||||||
path,
|
path,
|
||||||
completer: NuCompleter {
|
completer: NuCompleter {
|
||||||
file_completer: FilenameCompleter::new(),
|
file_completer: FilenameCompleter::new(),
|
||||||
|
@ -49,13 +49,9 @@ impl Environment {
|
||||||
hinter: HistoryHinter {},
|
hinter: HistoryHinter {},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn path(&self) -> &Path {
|
|
||||||
self.path.as_path()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Shell for Environment {
|
impl Shell for FilesystemShell {
|
||||||
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);
|
||||||
|
@ -179,12 +175,12 @@ impl Shell for Environment {
|
||||||
self.path.clone()
|
self.path.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_path(&mut self, path: std::path::PathBuf) {
|
fn set_path(&mut self, path: &std::path::PathBuf) {
|
||||||
self.path = path;
|
self.path = path.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Completer for Environment {
|
impl Completer for FilesystemShell {
|
||||||
type Candidate = completion::Pair;
|
type Candidate = completion::Pair;
|
||||||
|
|
||||||
fn complete(
|
fn complete(
|
||||||
|
@ -197,7 +193,7 @@ impl Completer for Environment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hinter for Environment {
|
impl Hinter for FilesystemShell {
|
||||||
fn hint(&self, line: &str, pos: usize, ctx: &rustyline::Context<'_>) -> Option<String> {
|
fn hint(&self, line: &str, pos: usize, ctx: &rustyline::Context<'_>) -> Option<String> {
|
||||||
self.hinter.hint(line, pos, ctx)
|
self.hinter.hint(line, pos, ctx)
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@ use crate::parser::nom_input;
|
||||||
use crate::parser::parse::token_tree::TokenNode;
|
use crate::parser::parse::token_tree::TokenNode;
|
||||||
use crate::parser::parse::tokens::RawToken;
|
use crate::parser::parse::tokens::RawToken;
|
||||||
use crate::parser::{Pipeline, PipelineElement};
|
use crate::parser::{Pipeline, PipelineElement};
|
||||||
use crate::shell::shell::Shell;
|
use crate::shell::shell_manager::ShellManager;
|
||||||
use crate::Tagged;
|
use crate::Tagged;
|
||||||
use ansi_term::Color;
|
use ansi_term::Color;
|
||||||
use rustyline::completion::{self, Completer};
|
use rustyline::completion::{self, Completer};
|
||||||
|
@ -10,14 +10,13 @@ use rustyline::error::ReadlineError;
|
||||||
use rustyline::highlight::Highlighter;
|
use rustyline::highlight::Highlighter;
|
||||||
use rustyline::hint::Hinter;
|
use rustyline::hint::Hinter;
|
||||||
use std::borrow::Cow::{self, Owned};
|
use std::borrow::Cow::{self, Owned};
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
|
|
||||||
crate struct Helper {
|
crate struct Helper {
|
||||||
helper: Arc<Mutex<Vec<Box<dyn Shell>>>>,
|
helper: ShellManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Helper {
|
impl Helper {
|
||||||
crate fn new(helper: Arc<Mutex<Vec<Box<dyn Shell>>>>) -> Helper {
|
crate fn new(helper: ShellManager) -> Helper {
|
||||||
Helper { helper }
|
Helper { helper }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,23 +30,13 @@ impl Completer for Helper {
|
||||||
pos: usize,
|
pos: usize,
|
||||||
ctx: &rustyline::Context<'_>,
|
ctx: &rustyline::Context<'_>,
|
||||||
) -> Result<(usize, Vec<completion::Pair>), ReadlineError> {
|
) -> Result<(usize, Vec<completion::Pair>), ReadlineError> {
|
||||||
self.helper
|
self.helper.complete(line, pos, ctx)
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.last()
|
|
||||||
.unwrap()
|
|
||||||
.complete(line, pos, ctx)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hinter for Helper {
|
impl Hinter for Helper {
|
||||||
fn hint(&self, line: &str, pos: usize, ctx: &rustyline::Context<'_>) -> Option<String> {
|
fn hint(&self, line: &str, pos: usize, ctx: &rustyline::Context<'_>) -> Option<String> {
|
||||||
self.helper
|
self.helper.hint(line, pos, ctx)
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.last()
|
|
||||||
.unwrap()
|
|
||||||
.hint(line, pos, ctx)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
src/shell/shell.rs
Normal file
15
src/shell/shell.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
use crate::commands::command::CallInfo;
|
||||||
|
use crate::errors::ShellError;
|
||||||
|
use crate::stream::{InputStream, OutputStream};
|
||||||
|
use rustyline::{completion::Completer, hint::Hinter};
|
||||||
|
|
||||||
|
pub trait Shell
|
||||||
|
where
|
||||||
|
Self: Completer<Candidate = rustyline::completion::Pair>,
|
||||||
|
Self: Hinter,
|
||||||
|
{
|
||||||
|
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) -> std::path::PathBuf;
|
||||||
|
fn set_path(&mut self, path: &std::path::PathBuf);
|
||||||
|
}
|
92
src/shell/shell_manager.rs
Normal file
92
src/shell/shell_manager.rs
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
use crate::commands::command::CallInfo;
|
||||||
|
use crate::errors::ShellError;
|
||||||
|
use crate::shell::filesystem_shell::FilesystemShell;
|
||||||
|
use crate::shell::shell::Shell;
|
||||||
|
use crate::stream::{InputStream, OutputStream};
|
||||||
|
use rustyline::completion::{self, Completer};
|
||||||
|
use rustyline::error::ReadlineError;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ShellManager {
|
||||||
|
crate shells: Arc<Mutex<Vec<Box<dyn Shell>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShellManager {
|
||||||
|
pub fn basic() -> Result<ShellManager, Box<dyn Error>> {
|
||||||
|
Ok(ShellManager {
|
||||||
|
shells: Arc::new(Mutex::new(vec![Box::new(FilesystemShell::basic()?)])),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push(&mut self, shell: Box<dyn Shell>) {
|
||||||
|
self.shells.lock().unwrap().push(shell)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> String {
|
||||||
|
self.shells
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.last()
|
||||||
|
.unwrap()
|
||||||
|
.path()
|
||||||
|
.display()
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_path(&mut self, path: &std::path::PathBuf) {
|
||||||
|
self.shells
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.last_mut()
|
||||||
|
.unwrap()
|
||||||
|
.set_path(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn complete(
|
||||||
|
&self,
|
||||||
|
line: &str,
|
||||||
|
pos: usize,
|
||||||
|
ctx: &rustyline::Context<'_>,
|
||||||
|
) -> Result<(usize, Vec<completion::Pair>), ReadlineError> {
|
||||||
|
self.shells
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.last()
|
||||||
|
.unwrap()
|
||||||
|
.complete(line, pos, ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hint(&self, line: &str, pos: usize, ctx: &rustyline::Context<'_>) -> Option<String> {
|
||||||
|
self.shells
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.last()
|
||||||
|
.unwrap()
|
||||||
|
.hint(line, pos, ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next(&mut self) {
|
||||||
|
let mut x = self.shells.lock().unwrap();
|
||||||
|
let shell = x.pop().unwrap();
|
||||||
|
x.insert(0, shell);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prev(&mut self) {
|
||||||
|
let mut x = self.shells.lock().unwrap();
|
||||||
|
let shell = x.remove(0);
|
||||||
|
x.push(shell);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ls(&self, call_info: CallInfo, input: InputStream) -> Result<OutputStream, ShellError> {
|
||||||
|
let env = self.shells.lock().unwrap();
|
||||||
|
|
||||||
|
env.last().unwrap().ls(call_info, input)
|
||||||
|
}
|
||||||
|
pub fn cd(&self, call_info: CallInfo, input: InputStream) -> Result<OutputStream, ShellError> {
|
||||||
|
let env = self.shells.lock().unwrap();
|
||||||
|
|
||||||
|
env.last().unwrap().cd(call_info, input)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user