mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 01:54:57 +02:00
Merge branch 'master' into remove_bind_by_move
This commit is contained in:
70
src/cli.rs
70
src/cli.rs
@ -272,11 +272,7 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
||||
if ctrlcbreak {
|
||||
std::process::exit(0);
|
||||
} else {
|
||||
context
|
||||
.host
|
||||
.lock()
|
||||
.unwrap()
|
||||
.stdout("CTRL-C pressed (again to quit)");
|
||||
context.with_host(|host| host.stdout("CTRL-C pressed (again to quit)"));
|
||||
ctrlcbreak = true;
|
||||
continue;
|
||||
}
|
||||
@ -285,18 +281,19 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
||||
LineResult::Error(mut line, err) => {
|
||||
rl.add_history_entry(line.clone());
|
||||
let diag = err.to_diagnostic();
|
||||
let host = context.host.lock().unwrap();
|
||||
let writer = host.err_termcolor();
|
||||
line.push_str(" ");
|
||||
let files = crate::parser::Files::new(line);
|
||||
let _ = std::panic::catch_unwind(move || {
|
||||
let _ = language_reporting::emit(
|
||||
&mut writer.lock(),
|
||||
&files,
|
||||
&diag,
|
||||
&language_reporting::DefaultConfig,
|
||||
);
|
||||
});
|
||||
context.with_host(|host| {
|
||||
let writer = host.err_termcolor();
|
||||
line.push_str(" ");
|
||||
let files = crate::parser::Files::new(line);
|
||||
let _ = std::panic::catch_unwind(move || {
|
||||
let _ = language_reporting::emit(
|
||||
&mut writer.lock(),
|
||||
&files,
|
||||
&diag,
|
||||
&language_reporting::DefaultConfig,
|
||||
);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
LineResult::Break => {
|
||||
@ -304,11 +301,9 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
|
||||
LineResult::FatalError(_, err) => {
|
||||
context
|
||||
.host
|
||||
.lock()
|
||||
.unwrap()
|
||||
.stdout(&format!("A surprising fatal error occurred.\n{:?}", err));
|
||||
context.with_host(|host| {
|
||||
host.stdout(&format!("A surprising fatal error occurred.\n{:?}", err))
|
||||
});
|
||||
}
|
||||
}
|
||||
ctrlcbreak = false;
|
||||
@ -330,31 +325,6 @@ enum LineResult {
|
||||
FatalError(String, ShellError),
|
||||
}
|
||||
|
||||
impl std::ops::Try for LineResult {
|
||||
type Ok = Option<String>;
|
||||
type Error = (String, ShellError);
|
||||
|
||||
fn into_result(self) -> Result<Option<String>, (String, ShellError)> {
|
||||
match self {
|
||||
LineResult::Success(s) => Ok(Some(s)),
|
||||
LineResult::Error(string, err) => Err((string, err)),
|
||||
LineResult::Break => Ok(None),
|
||||
LineResult::CtrlC => Ok(None),
|
||||
LineResult::FatalError(string, err) => Err((string, err)),
|
||||
}
|
||||
}
|
||||
fn from_error(v: (String, ShellError)) -> Self {
|
||||
LineResult::Error(v.0, v.1)
|
||||
}
|
||||
|
||||
fn from_ok(v: Option<String>) -> Self {
|
||||
match v {
|
||||
None => LineResult::Break,
|
||||
Some(v) => LineResult::Success(v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context) -> LineResult {
|
||||
match &readline {
|
||||
Ok(line) if line.trim() == "" => LineResult::Success(line.clone()),
|
||||
@ -371,8 +341,10 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
|
||||
debug!("=== Parsed ===");
|
||||
debug!("{:#?}", result);
|
||||
|
||||
let mut pipeline = classify_pipeline(&result, ctx, &Text::from(line))
|
||||
.map_err(|err| (line.clone(), err))?;
|
||||
let mut pipeline = match classify_pipeline(&result, ctx, &Text::from(line)) {
|
||||
Ok(pipeline) => pipeline,
|
||||
Err(err) => return LineResult::Error(line.clone(), err),
|
||||
};
|
||||
|
||||
match pipeline.commands.last() {
|
||||
Some(ClassifiedCommand::External(_)) => {}
|
||||
|
@ -315,19 +315,23 @@ impl ExternalCommand {
|
||||
if arg_string.contains("$it") {
|
||||
let mut first = true;
|
||||
for i in &inputs {
|
||||
if i.as_string().is_err() {
|
||||
let mut span = name_span;
|
||||
for arg in &self.args {
|
||||
if arg.item.contains("$it") {
|
||||
span = arg.span();
|
||||
let i = match i.as_string() {
|
||||
Err(_err) => {
|
||||
let mut span = name_span;
|
||||
for arg in &self.args {
|
||||
if arg.item.contains("$it") {
|
||||
span = arg.span();
|
||||
}
|
||||
}
|
||||
return Err(ShellError::labeled_error(
|
||||
"External $it needs string data",
|
||||
"given object instead of string data",
|
||||
span,
|
||||
));
|
||||
}
|
||||
return Err(ShellError::labeled_error(
|
||||
"External $it needs string data",
|
||||
"given object instead of string data",
|
||||
span,
|
||||
));
|
||||
}
|
||||
Ok(val) => val,
|
||||
};
|
||||
|
||||
if !first {
|
||||
new_arg_string.push_str("&&");
|
||||
new_arg_string.push_str(&self.name);
|
||||
@ -341,7 +345,7 @@ impl ExternalCommand {
|
||||
}
|
||||
|
||||
new_arg_string.push_str(" ");
|
||||
new_arg_string.push_str(&arg.replace("$it", &i.as_string().unwrap()));
|
||||
new_arg_string.push_str(&arg.replace("$it", &i));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -366,7 +370,7 @@ impl ExternalCommand {
|
||||
process = process.stdin(stdin);
|
||||
}
|
||||
|
||||
let mut popen = process.popen().unwrap();
|
||||
let mut popen = process.popen()?;
|
||||
|
||||
match stream_next {
|
||||
StreamNext::Last => {
|
||||
|
@ -596,14 +596,10 @@ impl Command {
|
||||
.unwrap();
|
||||
// We don't have an $it or block, so just execute what we have
|
||||
|
||||
command
|
||||
.run(&call_info, ®istry, &raw_args.shell_manager, nothing)?
|
||||
.into()
|
||||
// let out = match command.run(&call_info, ®istry, &raw_args.shell_manager, nothing) {
|
||||
// Ok(o) => o,
|
||||
// Err(e) => VecDeque::from(vec![ReturnValue::Err(e)]),
|
||||
// };
|
||||
// Ok(out.to_output_stream())
|
||||
match command.run(&call_info, ®istry, &raw_args.shell_manager, nothing) {
|
||||
Ok(o) => o,
|
||||
Err(e) => OutputStream::one(Err(e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ impl CommandRegistry {
|
||||
pub struct Context {
|
||||
registry: CommandRegistry,
|
||||
crate source_map: SourceMap,
|
||||
crate host: Arc<Mutex<dyn Host + Send>>,
|
||||
host: Arc<Mutex<dyn Host + Send>>,
|
||||
crate shell_manager: ShellManager,
|
||||
}
|
||||
|
||||
@ -93,6 +93,12 @@ impl Context {
|
||||
})
|
||||
}
|
||||
|
||||
crate fn with_host(&mut self, block: impl FnOnce(&mut dyn Host)) {
|
||||
let mut host = self.host.lock().unwrap();
|
||||
|
||||
block(&mut *host)
|
||||
}
|
||||
|
||||
pub fn add_commands(&mut self, commands: Vec<Arc<Command>>) {
|
||||
for command in commands {
|
||||
self.registry.insert(command.name().to_string(), command);
|
||||
@ -103,10 +109,6 @@ impl Context {
|
||||
self.source_map.insert(uuid, span_source);
|
||||
}
|
||||
|
||||
// pub fn clone_commands(&self) -> CommandRegistry {
|
||||
// self.registry.clone()
|
||||
// }
|
||||
|
||||
crate fn has_command(&self, name: &str) -> bool {
|
||||
self.registry.has(name)
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(generators)]
|
||||
#![feature(try_trait)]
|
||||
#![feature(specialization)]
|
||||
#![feature(proc_macro_hygiene)]
|
||||
|
||||
@ -30,7 +29,7 @@ pub use crate::env::host::BasicHost;
|
||||
pub use crate::object::base::OF64;
|
||||
pub use crate::parser::hir::SyntaxType;
|
||||
pub use crate::plugin::{serve_plugin, Plugin};
|
||||
pub use crate::utils::{AbsolutePath, RelativePath};
|
||||
pub use crate::utils::{AbsoluteFile, AbsolutePath, RelativePath};
|
||||
pub use cli::cli;
|
||||
pub use errors::ShellError;
|
||||
pub use object::base::{Primitive, Value};
|
||||
|
@ -16,10 +16,6 @@ macro_rules! trace_stream {
|
||||
(target: $target:tt, $desc:tt = $expr:expr) => {{
|
||||
if log::log_enabled!(target: $target, log::Level::Trace) {
|
||||
use futures::stream::StreamExt;
|
||||
// Blocking is generally quite bad, but this is for debugging
|
||||
// let mut local = futures::executor::LocalPool::new();
|
||||
// let objects = local.run_until($expr.into_vec());
|
||||
// let objects: Vec<_> = futures::executor::block_on($expr.into_vec());
|
||||
|
||||
let objects = $expr.values.inspect(|o| {
|
||||
trace!(target: $target, "{} = {:#?}", $desc, o.debug());
|
||||
|
@ -84,22 +84,6 @@ impl OutputStream {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Try for OutputStream {
|
||||
type Ok = OutputStream;
|
||||
type Error = ShellError;
|
||||
fn into_result(self) -> Result<Self::Ok, Self::Error> {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn from_error(v: Self::Error) -> Self {
|
||||
OutputStream::one(Err(v))
|
||||
}
|
||||
|
||||
fn from_ok(v: Self::Ok) -> Self {
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
impl Stream for OutputStream {
|
||||
type Item = ReturnValue;
|
||||
|
||||
|
57
src/utils.rs
57
src/utils.rs
@ -1,7 +1,52 @@
|
||||
use crate::errors::ShellError;
|
||||
use std::fmt;
|
||||
use std::ops::Div;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub struct AbsoluteFile {
|
||||
inner: PathBuf,
|
||||
}
|
||||
|
||||
impl AbsoluteFile {
|
||||
pub fn new(path: impl AsRef<Path>) -> AbsoluteFile {
|
||||
let path = path.as_ref();
|
||||
|
||||
if !path.is_absolute() {
|
||||
panic!(
|
||||
"AbsoluteFile::new must take an absolute path :: {}",
|
||||
path.display()
|
||||
)
|
||||
} else if path.is_dir() {
|
||||
// At the moment, this is not an invariant, but rather a way to catch bugs
|
||||
// in tests.
|
||||
panic!(
|
||||
"AbsoluteFile::new must not take a directory :: {}",
|
||||
path.display()
|
||||
)
|
||||
} else {
|
||||
AbsoluteFile {
|
||||
inner: path.to_path_buf(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dir(&self) -> AbsolutePath {
|
||||
AbsolutePath::new(self.inner.parent().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AbsoluteFile> for PathBuf {
|
||||
fn from(file: AbsoluteFile) -> Self {
|
||||
file.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for AbsoluteFile {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.inner.display())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AbsolutePath {
|
||||
inner: PathBuf,
|
||||
}
|
||||
@ -20,6 +65,12 @@ impl AbsolutePath {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for AbsolutePath {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.inner.display())
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<&str> for &AbsolutePath {
|
||||
type Output = AbsolutePath;
|
||||
|
||||
@ -72,6 +123,12 @@ impl<T: AsRef<str>> Div<T> for &RelativePath {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RelativePath {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.inner.display())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub struct Res {
|
||||
pub loc: PathBuf,
|
||||
|
Reference in New Issue
Block a user