mirror of
https://github.com/nushell/nushell.git
synced 2025-04-21 19:58:21 +02:00
Add initial ctrl-c support
This commit is contained in:
parent
1308eb45d5
commit
bac8b8a450
24
Cargo.lock
generated
24
Cargo.lock
generated
@ -264,6 +264,16 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ctrlc"
|
||||||
|
version = "3.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a19c6cedffdc8c03a3346d723eb20bd85a13362bb96dc2ac000842c6381ec7bf"
|
||||||
|
dependencies = [
|
||||||
|
"nix",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dialoguer"
|
name = "dialoguer"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
@ -339,6 +349,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"assert_cmd",
|
"assert_cmd",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
|
"ctrlc",
|
||||||
"dialoguer",
|
"dialoguer",
|
||||||
"miette",
|
"miette",
|
||||||
"nu-cli",
|
"nu-cli",
|
||||||
@ -558,6 +569,19 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.23.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f305c2c2e4c39a82f7bf0bf65fb557f9070ce06781d4f2454295cc34b1c43188"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cc",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"memoffset",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ntapi"
|
name = "ntapi"
|
||||||
version = "0.3.6"
|
version = "0.3.6"
|
||||||
|
@ -22,6 +22,7 @@ nu-protocol = { path = "./crates/nu-protocol" }
|
|||||||
nu-table = { path = "./crates/nu-table" }
|
nu-table = { path = "./crates/nu-table" }
|
||||||
nu-term-grid = { path = "./crates/nu-term-grid" }
|
nu-term-grid = { path = "./crates/nu-term-grid" }
|
||||||
miette = "3.0.0"
|
miette = "3.0.0"
|
||||||
|
ctrlc = "3.2.1"
|
||||||
# mimalloc = { version = "*", default-features = false }
|
# mimalloc = { version = "*", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
2
TODO.md
2
TODO.md
@ -32,8 +32,8 @@
|
|||||||
- [x] Config file loading
|
- [x] Config file loading
|
||||||
- [x] block variable captures
|
- [x] block variable captures
|
||||||
- [x] improved history and config paths
|
- [x] improved history and config paths
|
||||||
|
- [x] ctrl-c support
|
||||||
- [ ] Support for `$in`
|
- [ ] Support for `$in`
|
||||||
- [ ] ctrl-c support
|
|
||||||
- [ ] operator overflow
|
- [ ] operator overflow
|
||||||
- [ ] shells
|
- [ ] shells
|
||||||
- [ ] plugins
|
- [ ] plugins
|
||||||
|
@ -26,12 +26,12 @@ impl Command for SubCommand {
|
|||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
_engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
_stack: &mut Stack,
|
_stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||||
into_binary(call, input)
|
into_binary(engine_state, call, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -86,13 +86,15 @@ impl Command for SubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn into_binary(
|
fn into_binary(
|
||||||
|
engine_state: &EngineState,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||||
let head = call.head;
|
let head = call.head;
|
||||||
// let column_paths: Vec<CellPath> = call.rest(context, 0)?;
|
// let column_paths: Vec<CellPath> = call.rest(context, 0)?;
|
||||||
|
|
||||||
input.map(move |v| {
|
input.map(
|
||||||
|
move |v| {
|
||||||
action(v, head)
|
action(v, head)
|
||||||
// FIXME: Add back in cell_path support
|
// FIXME: Add back in cell_path support
|
||||||
// if column_paths.is_empty() {
|
// if column_paths.is_empty() {
|
||||||
@ -106,7 +108,9 @@ fn into_binary(
|
|||||||
|
|
||||||
// Ok(ret)
|
// Ok(ret)
|
||||||
// }
|
// }
|
||||||
})
|
},
|
||||||
|
engine_state.ctrlc.clone(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn int_to_endian(n: i64) -> Vec<u8> {
|
fn int_to_endian(n: i64) -> Vec<u8> {
|
||||||
|
@ -26,12 +26,12 @@ impl Command for SubCommand {
|
|||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
_engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
_stack: &mut Stack,
|
_stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||||
into_filesize(call, input)
|
into_filesize(engine_state, call, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -114,13 +114,15 @@ impl Command for SubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn into_filesize(
|
fn into_filesize(
|
||||||
|
engine_state: &EngineState,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||||
let head = call.head;
|
let head = call.head;
|
||||||
// let call_paths: Vec<ColumnPath> = args.rest(0)?;
|
// let call_paths: Vec<ColumnPath> = args.rest(0)?;
|
||||||
|
|
||||||
input.map(move |v| {
|
input.map(
|
||||||
|
move |v| {
|
||||||
action(v, head)
|
action(v, head)
|
||||||
|
|
||||||
// FIXME: Add back cell_path support
|
// FIXME: Add back cell_path support
|
||||||
@ -137,7 +139,9 @@ fn into_filesize(
|
|||||||
|
|
||||||
// Ok(ret)
|
// Ok(ret)
|
||||||
// }
|
// }
|
||||||
})
|
},
|
||||||
|
engine_state.ctrlc.clone(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn action(input: Value, span: Span) -> Value {
|
pub fn action(input: Value, span: Span) -> Value {
|
||||||
|
@ -26,12 +26,12 @@ impl Command for SubCommand {
|
|||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
_engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
_stack: &mut Stack,
|
_stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||||
into_int(call, input)
|
into_int(engine_state, call, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -90,13 +90,15 @@ impl Command for SubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn into_int(
|
fn into_int(
|
||||||
|
engine_state: &EngineState,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||||
let head = call.head;
|
let head = call.head;
|
||||||
// let column_paths: Vec<CellPath> = call.rest(context, 0)?;
|
// let column_paths: Vec<CellPath> = call.rest(context, 0)?;
|
||||||
|
|
||||||
input.map(move |v| {
|
input.map(
|
||||||
|
move |v| {
|
||||||
action(v, head)
|
action(v, head)
|
||||||
// FIXME: Add back cell_path support
|
// FIXME: Add back cell_path support
|
||||||
// if column_paths.is_empty() {
|
// if column_paths.is_empty() {
|
||||||
@ -110,7 +112,9 @@ fn into_int(
|
|||||||
|
|
||||||
// Ok(ret)
|
// Ok(ret)
|
||||||
// }
|
// }
|
||||||
})
|
},
|
||||||
|
engine_state.ctrlc.clone(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn action(input: Value, span: Span) -> Value {
|
pub fn action(input: Value, span: Span) -> Value {
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use nu_engine::{eval_block, eval_expression};
|
use nu_engine::{eval_block, eval_expression};
|
||||||
use nu_protocol::ast::Call;
|
use nu_protocol::ast::Call;
|
||||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||||
use nu_protocol::{Example, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value};
|
use nu_protocol::{
|
||||||
|
Example, IntoInterruptiblePipelineData, PipelineData, Signature, Span, SyntaxShape, Value,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct For;
|
pub struct For;
|
||||||
@ -55,6 +57,7 @@ impl Command for For {
|
|||||||
.as_block()
|
.as_block()
|
||||||
.expect("internal error: expected block");
|
.expect("internal error: expected block");
|
||||||
|
|
||||||
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
let block = engine_state.get_block(block_id).clone();
|
let block = engine_state.get_block(block_id).clone();
|
||||||
let mut stack = stack.collect_captures(&block.captures);
|
let mut stack = stack.collect_captures(&block.captures);
|
||||||
@ -71,7 +74,7 @@ impl Command for For {
|
|||||||
Err(error) => Value::Error { error },
|
Err(error) => Value::Error { error },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data(ctrlc)),
|
||||||
Value::Range { val, .. } => Ok(val
|
Value::Range { val, .. } => Ok(val
|
||||||
.into_range_iter()?
|
.into_range_iter()?
|
||||||
.map(move |x| {
|
.map(move |x| {
|
||||||
@ -83,7 +86,7 @@ impl Command for For {
|
|||||||
Err(error) => Value::Error { error },
|
Err(error) => Value::Error { error },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data(ctrlc)),
|
||||||
x => {
|
x => {
|
||||||
stack.add_var(var_id, x);
|
stack.add_var(var_id, x);
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::Call,
|
ast::Call,
|
||||||
engine::{Command, EngineState, Stack},
|
engine::{Command, EngineState, Stack},
|
||||||
span, Example, IntoPipelineData, PipelineData, ShellError, Signature, Spanned, SyntaxShape,
|
span, Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, ShellError,
|
||||||
Value,
|
Signature, Spanned, SyntaxShape, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
use nu_engine::{get_full_help, CallExt};
|
use nu_engine::{get_full_help, CallExt};
|
||||||
@ -121,7 +121,9 @@ fn help(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(found_cmds_vec.into_iter().into_pipeline_data());
|
return Ok(found_cmds_vec
|
||||||
|
.into_iter()
|
||||||
|
.into_pipeline_data(engine_state.ctrlc.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !rest.is_empty() {
|
if !rest.is_empty() {
|
||||||
@ -155,7 +157,9 @@ fn help(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(found_cmds_vec.into_iter().into_pipeline_data())
|
Ok(found_cmds_vec
|
||||||
|
.into_iter()
|
||||||
|
.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||||
} else {
|
} else {
|
||||||
let mut name = String::new();
|
let mut name = String::new();
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
|
@ -7,6 +7,7 @@ use crate::*;
|
|||||||
|
|
||||||
pub fn create_default_context() -> EngineState {
|
pub fn create_default_context() -> EngineState {
|
||||||
let mut engine_state = EngineState::new();
|
let mut engine_state = EngineState::new();
|
||||||
|
|
||||||
let delta = {
|
let delta = {
|
||||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ use nu_protocol::ast::Call;
|
|||||||
use nu_protocol::engine::Command;
|
use nu_protocol::engine::Command;
|
||||||
use nu_protocol::engine::EngineState;
|
use nu_protocol::engine::EngineState;
|
||||||
use nu_protocol::engine::Stack;
|
use nu_protocol::engine::Stack;
|
||||||
use nu_protocol::IntoPipelineData;
|
use nu_protocol::IntoInterruptiblePipelineData;
|
||||||
use nu_protocol::PipelineData;
|
use nu_protocol::PipelineData;
|
||||||
use nu_protocol::{Signature, Value};
|
use nu_protocol::{Signature, Value};
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ impl Command for ListGitBranches {
|
|||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
_engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
_stack: &mut Stack,
|
_stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
@ -62,7 +62,9 @@ impl Command for ListGitBranches {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Ok(lines.into_iter().into_pipeline_data())
|
Ok(lines
|
||||||
|
.into_iter()
|
||||||
|
.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||||
} else {
|
} else {
|
||||||
Ok(PipelineData::new())
|
Ok(PipelineData::new())
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use chrono::{DateTime, Utc};
|
|||||||
use nu_engine::eval_expression;
|
use nu_engine::eval_expression;
|
||||||
use nu_protocol::ast::Call;
|
use nu_protocol::ast::Call;
|
||||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||||
use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape, Value};
|
use nu_protocol::{IntoInterruptiblePipelineData, PipelineData, Signature, SyntaxShape, Value};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Ls;
|
pub struct Ls;
|
||||||
@ -112,6 +112,6 @@ impl Command for Ls {
|
|||||||
},
|
},
|
||||||
_ => Value::Nothing { span: call_span },
|
_ => Value::Nothing { span: call_span },
|
||||||
})
|
})
|
||||||
.into_pipeline_data())
|
.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,9 @@ use std::env::current_dir;
|
|||||||
use nu_engine::CallExt;
|
use nu_engine::CallExt;
|
||||||
use nu_protocol::ast::Call;
|
use nu_protocol::ast::Call;
|
||||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||||
use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value};
|
use nu_protocol::{
|
||||||
|
IntoInterruptiblePipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Mkdir;
|
pub struct Mkdir;
|
||||||
@ -69,6 +71,8 @@ impl Command for Mkdir {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(stream.into_iter().into_pipeline_data())
|
Ok(stream
|
||||||
|
.into_iter()
|
||||||
|
.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,9 @@ use super::util::get_interactive_confirmation;
|
|||||||
use nu_engine::CallExt;
|
use nu_engine::CallExt;
|
||||||
use nu_protocol::ast::Call;
|
use nu_protocol::ast::Call;
|
||||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||||
use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value};
|
use nu_protocol::{
|
||||||
|
IntoInterruptiblePipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Rm;
|
pub struct Rm;
|
||||||
@ -170,7 +172,9 @@ fn rm(
|
|||||||
// let temp = rm_helper(call, args).flatten();
|
// let temp = rm_helper(call, args).flatten();
|
||||||
// let temp = input.flatten(call.head, move |_| rm_helper(call, args));
|
// let temp = input.flatten(call.head, move |_| rm_helper(call, args));
|
||||||
|
|
||||||
Ok(response.into_iter().into_pipeline_data())
|
Ok(response
|
||||||
|
.into_iter()
|
||||||
|
.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||||
// Ok(Value::Nothing { span })
|
// Ok(Value::Nothing { span })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
use nu_engine::eval_block;
|
use nu_engine::eval_block;
|
||||||
use nu_protocol::ast::Call;
|
use nu_protocol::ast::Call;
|
||||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||||
use nu_protocol::{Example, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value};
|
use nu_protocol::{
|
||||||
|
Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, Signature, Span,
|
||||||
|
SyntaxShape, Value,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Each;
|
pub struct Each;
|
||||||
@ -63,6 +66,7 @@ impl Command for Each {
|
|||||||
.expect("internal error: expected block");
|
.expect("internal error: expected block");
|
||||||
|
|
||||||
let numbered = call.has_flag("numbered");
|
let numbered = call.has_flag("numbered");
|
||||||
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
let block = engine_state.get_block(block_id).clone();
|
let block = engine_state.get_block(block_id).clone();
|
||||||
let mut stack = stack.collect_captures(&block.captures);
|
let mut stack = stack.collect_captures(&block.captures);
|
||||||
@ -101,7 +105,7 @@ impl Command for Each {
|
|||||||
Err(error) => Value::Error { error },
|
Err(error) => Value::Error { error },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data(ctrlc)),
|
||||||
PipelineData::Value(Value::List { vals: val, .. }) => Ok(val
|
PipelineData::Value(Value::List { vals: val, .. }) => Ok(val
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
@ -134,7 +138,7 @@ impl Command for Each {
|
|||||||
Err(error) => Value::Error { error },
|
Err(error) => Value::Error { error },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data(ctrlc)),
|
||||||
PipelineData::Stream(stream) => Ok(stream
|
PipelineData::Stream(stream) => Ok(stream
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(move |(idx, x)| {
|
.map(move |(idx, x)| {
|
||||||
@ -166,7 +170,7 @@ impl Command for Each {
|
|||||||
Err(error) => Value::Error { error },
|
Err(error) => Value::Error { error },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data(ctrlc)),
|
||||||
PipelineData::Value(Value::Record { cols, vals, .. }) => {
|
PipelineData::Value(Value::Record { cols, vals, .. }) => {
|
||||||
let mut output_cols = vec![];
|
let mut output_cols = vec![];
|
||||||
let mut output_vals = vec![];
|
let mut output_vals = vec![];
|
||||||
|
@ -3,7 +3,8 @@ use nu_engine::CallExt;
|
|||||||
use nu_protocol::ast::Call;
|
use nu_protocol::ast::Call;
|
||||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
Example, IntoInterruptiblePipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape,
|
||||||
|
Value,
|
||||||
};
|
};
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ impl Command for Last {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(beginning_rows_to_skip.try_into().unwrap());
|
.skip(beginning_rows_to_skip.try_into().unwrap());
|
||||||
|
|
||||||
Ok(iter.into_pipeline_data())
|
Ok(iter.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use nu_protocol::ast::Call;
|
use nu_protocol::ast::Call;
|
||||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||||
use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, Value};
|
use nu_protocol::{IntoInterruptiblePipelineData, PipelineData, ShellError, Signature, Value};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Lines;
|
pub struct Lines;
|
||||||
@ -22,7 +22,7 @@ impl Command for Lines {
|
|||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
_engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
_stack: &mut Stack,
|
_stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
@ -46,7 +46,7 @@ impl Command for Lines {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(iter.into_pipeline_data())
|
Ok(iter.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
PipelineData::Stream(stream) => {
|
PipelineData::Stream(stream) => {
|
||||||
let iter = stream
|
let iter = stream
|
||||||
@ -74,7 +74,7 @@ impl Command for Lines {
|
|||||||
})
|
})
|
||||||
.flatten();
|
.flatten();
|
||||||
|
|
||||||
Ok(iter.into_pipeline_data())
|
Ok(iter.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
PipelineData::Value(val) => Err(ShellError::UnsupportedInput(
|
PipelineData::Value(val) => Err(ShellError::UnsupportedInput(
|
||||||
format!("Not supported input: {}", val.as_string()?),
|
format!("Not supported input: {}", val.as_string()?),
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
use nu_engine::eval_block;
|
use nu_engine::eval_block;
|
||||||
use nu_protocol::ast::Call;
|
use nu_protocol::ast::Call;
|
||||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||||
use nu_protocol::{Example, IntoPipelineData, PipelineData, Signature, SyntaxShape, Value};
|
use nu_protocol::{
|
||||||
|
Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, Signature, SyntaxShape,
|
||||||
|
Value,
|
||||||
|
};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -46,6 +49,7 @@ impl Command for ParEach {
|
|||||||
.expect("internal error: expected block");
|
.expect("internal error: expected block");
|
||||||
|
|
||||||
let numbered = call.has_flag("numbered");
|
let numbered = call.has_flag("numbered");
|
||||||
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
let block = engine_state.get_block(block_id);
|
let block = engine_state.get_block(block_id);
|
||||||
let mut stack = stack.collect_captures(&block.captures);
|
let mut stack = stack.collect_captures(&block.captures);
|
||||||
@ -92,7 +96,7 @@ impl Command for ParEach {
|
|||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data(ctrlc)),
|
||||||
PipelineData::Value(Value::List { vals: val, .. }) => Ok(val
|
PipelineData::Value(Value::List { vals: val, .. }) => Ok(val
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
@ -133,7 +137,7 @@ impl Command for ParEach {
|
|||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data(ctrlc)),
|
||||||
PipelineData::Stream(stream) => Ok(stream
|
PipelineData::Stream(stream) => Ok(stream
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.par_bridge()
|
.par_bridge()
|
||||||
@ -173,7 +177,7 @@ impl Command for ParEach {
|
|||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data(ctrlc)),
|
||||||
PipelineData::Value(Value::Record { cols, vals, .. }) => {
|
PipelineData::Value(Value::Record { cols, vals, .. }) => {
|
||||||
let mut output_cols = vec![];
|
let mut output_cols = vec![];
|
||||||
let mut output_vals = vec![];
|
let mut output_vals = vec![];
|
||||||
|
@ -2,7 +2,8 @@ use nu_engine::CallExt;
|
|||||||
use nu_protocol::ast::{Call, CellPath};
|
use nu_protocol::ast::{Call, CellPath};
|
||||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, ShellError, Signature,
|
||||||
|
Span, SyntaxShape, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -35,7 +36,7 @@ impl Command for Select {
|
|||||||
let columns: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
|
let columns: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
|
|
||||||
select(span, columns, input)
|
select(engine_state, span, columns, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -55,6 +56,7 @@ impl Command for Select {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn select(
|
fn select(
|
||||||
|
engine_state: &EngineState,
|
||||||
span: Span,
|
span: Span,
|
||||||
columns: Vec<CellPath>,
|
columns: Vec<CellPath>,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
@ -84,7 +86,9 @@ fn select(
|
|||||||
output.push(Value::Record { cols, vals, span })
|
output.push(Value::Record { cols, vals, span })
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(output.into_iter().into_pipeline_data())
|
Ok(output
|
||||||
|
.into_iter()
|
||||||
|
.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
PipelineData::Stream(stream) => Ok(stream
|
PipelineData::Stream(stream) => Ok(stream
|
||||||
.map(move |x| {
|
.map(move |x| {
|
||||||
@ -106,7 +110,7 @@ fn select(
|
|||||||
|
|
||||||
Value::Record { cols, vals, span }
|
Value::Record { cols, vals, span }
|
||||||
})
|
})
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data(engine_state.ctrlc.clone())),
|
||||||
PipelineData::Value(v) => {
|
PipelineData::Value(v) => {
|
||||||
let mut cols = vec![];
|
let mut cols = vec![];
|
||||||
let mut vals = vec![];
|
let mut vals = vec![];
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
use nu_engine::eval_expression;
|
use nu_engine::eval_expression;
|
||||||
use nu_protocol::ast::{Call, Expr, Expression};
|
use nu_protocol::ast::{Call, Expr, Expression};
|
||||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||||
use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value};
|
use nu_protocol::{
|
||||||
|
IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, ShellError, Signature,
|
||||||
|
SyntaxShape, Value,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Where;
|
pub struct Where;
|
||||||
@ -28,6 +31,7 @@ impl Command for Where {
|
|||||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||||
let cond = call.positional[0].clone();
|
let cond = call.positional[0].clone();
|
||||||
|
|
||||||
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let engine_state = engine_state.clone();
|
let engine_state = engine_state.clone();
|
||||||
|
|
||||||
// FIXME: very expensive
|
// FIXME: very expensive
|
||||||
@ -53,7 +57,7 @@ impl Command for Where {
|
|||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data(ctrlc)),
|
||||||
PipelineData::Value(Value::List { vals, .. }) => Ok(vals
|
PipelineData::Value(Value::List { vals, .. }) => Ok(vals
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(move |value| {
|
.filter(move |value| {
|
||||||
@ -66,7 +70,7 @@ impl Command for Where {
|
|||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data(ctrlc)),
|
||||||
PipelineData::Value(x) => {
|
PipelineData::Value(x) => {
|
||||||
stack.add_var(var_id, x.clone());
|
stack.add_var(var_id, x.clone());
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use nu_engine::CallExt;
|
use nu_engine::CallExt;
|
||||||
use nu_protocol::ast::Call;
|
use nu_protocol::ast::Call;
|
||||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||||
use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape, Value};
|
use nu_protocol::{
|
||||||
|
IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, Signature, SyntaxShape, Value,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Wrap;
|
pub struct Wrap;
|
||||||
@ -37,14 +39,14 @@ impl Command for Wrap {
|
|||||||
vals: vec![x],
|
vals: vec![x],
|
||||||
span,
|
span,
|
||||||
})
|
})
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data(engine_state.ctrlc.clone())),
|
||||||
PipelineData::Stream(stream) => Ok(stream
|
PipelineData::Stream(stream) => Ok(stream
|
||||||
.map(move |x| Value::Record {
|
.map(move |x| Value::Record {
|
||||||
cols: vec![name.clone()],
|
cols: vec![name.clone()],
|
||||||
vals: vec![x],
|
vals: vec![x],
|
||||||
span,
|
span,
|
||||||
})
|
})
|
||||||
.into_pipeline_data()),
|
.into_pipeline_data(engine_state.ctrlc.clone())),
|
||||||
PipelineData::Value(input) => Ok(Value::Record {
|
PipelineData::Value(input) => Ok(Value::Record {
|
||||||
cols: vec![name],
|
cols: vec![name],
|
||||||
vals: vec![input],
|
vals: vec![input],
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
use nu_protocol::ast::Call;
|
use nu_protocol::ast::Call;
|
||||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||||
use nu_protocol::{Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, Value};
|
use nu_protocol::{
|
||||||
|
Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, ShellError, Signature,
|
||||||
|
Span, Value,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FromJson;
|
pub struct FromJson;
|
||||||
@ -68,7 +71,7 @@ impl Command for FromJson {
|
|||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
_engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
_stack: &mut Stack,
|
_stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
@ -90,7 +93,7 @@ impl Command for FromJson {
|
|||||||
Err(error) => Value::Error { error },
|
Err(error) => Value::Error { error },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data())
|
.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||||
} else {
|
} else {
|
||||||
Ok(convert_string_to_value(string_input, span)?.into_pipeline_data())
|
Ok(convert_string_to_value(string_input, span)?.into_pipeline_data())
|
||||||
}
|
}
|
||||||
|
@ -20,13 +20,16 @@ impl Command for SubCommand {
|
|||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
_engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
_stack: &mut Stack,
|
_stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||||
let head = call.head;
|
let head = call.head;
|
||||||
input.map(move |value| abs_helper(value, head))
|
input.map(
|
||||||
|
move |value| abs_helper(value, head),
|
||||||
|
engine_state.ctrlc.clone(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -24,12 +24,12 @@ impl Command for Size {
|
|||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
_engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
_stack: &mut Stack,
|
_stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
size(call, input)
|
size(engine_state, call, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -100,9 +100,14 @@ impl Command for Size {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size(call: &Call, input: PipelineData) -> Result<PipelineData, ShellError> {
|
fn size(
|
||||||
|
engine_state: &EngineState,
|
||||||
|
call: &Call,
|
||||||
|
input: PipelineData,
|
||||||
|
) -> Result<PipelineData, ShellError> {
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
input.map(move |v| match v.as_string() {
|
input.map(
|
||||||
|
move |v| match v.as_string() {
|
||||||
Ok(s) => count(&s, span),
|
Ok(s) => count(&s, span),
|
||||||
Err(_) => Value::Error {
|
Err(_) => Value::Error {
|
||||||
error: ShellError::PipelineMismatch {
|
error: ShellError::PipelineMismatch {
|
||||||
@ -111,7 +116,9 @@ fn size(call: &Call, input: PipelineData) -> Result<PipelineData, ShellError> {
|
|||||||
origin: span,
|
origin: span,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
},
|
||||||
|
engine_state.ctrlc.clone(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn count(contents: &str, span: Span) -> Value {
|
fn count(contents: &str, span: Span) -> Value {
|
||||||
|
@ -39,22 +39,26 @@ impl Command for SubCommand {
|
|||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
_engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
_stack: &mut Stack,
|
_stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||||
split_chars(call, input)
|
split_chars(engine_state, call, input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_chars(
|
fn split_chars(
|
||||||
|
engine_state: &EngineState,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
|
|
||||||
input.flat_map(move |x| split_chars_helper(&x, span))
|
input.flat_map(
|
||||||
|
move |x| split_chars_helper(&x, span),
|
||||||
|
engine_state.ctrlc.clone(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_chars_helper(v: &Value, name: Span) -> Vec<Value> {
|
fn split_chars_helper(v: &Value, name: Span) -> Vec<Value> {
|
||||||
|
@ -54,7 +54,10 @@ fn split_column(
|
|||||||
let rest: Vec<Spanned<String>> = call.rest(engine_state, stack, 1)?;
|
let rest: Vec<Spanned<String>> = call.rest(engine_state, stack, 1)?;
|
||||||
let collapse_empty = call.has_flag("collapse-empty");
|
let collapse_empty = call.has_flag("collapse-empty");
|
||||||
|
|
||||||
input.flat_map(move |x| split_column_helper(&x, &separator, &rest, collapse_empty, name_span))
|
input.flat_map(
|
||||||
|
move |x| split_column_helper(&x, &separator, &rest, collapse_empty, name_span),
|
||||||
|
engine_state.ctrlc.clone(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_column_helper(
|
fn split_column_helper(
|
||||||
|
@ -45,7 +45,10 @@ fn split_row(
|
|||||||
let name_span = call.head;
|
let name_span = call.head;
|
||||||
let separator: Spanned<String> = call.req(engine_state, stack, 0)?;
|
let separator: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||||
|
|
||||||
input.flat_map(move |x| split_row_helper(&x, &separator, name_span))
|
input.flat_map(
|
||||||
|
move |x| split_row_helper(&x, &separator, name_span),
|
||||||
|
engine_state.ctrlc.clone(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_row_helper(v: &Value, separator: &Spanned<String>, name: Span) -> Vec<Value> {
|
fn split_row_helper(v: &Value, separator: &Spanned<String>, name: Span) -> Vec<Value> {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::Call,
|
ast::Call,
|
||||||
engine::{Command, EngineState, Stack},
|
engine::{Command, EngineState, Stack},
|
||||||
Example, IntoPipelineData, PipelineData, ShellError, Signature, Value,
|
Example, IntoInterruptiblePipelineData, PipelineData, ShellError, Signature, Value,
|
||||||
};
|
};
|
||||||
use sysinfo::{ProcessExt, System, SystemExt};
|
use sysinfo::{ProcessExt, System, SystemExt};
|
||||||
|
|
||||||
@ -30,12 +30,12 @@ impl Command for Ps {
|
|||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
_engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
_stack: &mut Stack,
|
_stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||||
run_ps(call)
|
run_ps(engine_state, call)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
@ -47,7 +47,7 @@ impl Command for Ps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_ps(call: &Call) -> Result<PipelineData, ShellError> {
|
fn run_ps(engine_state: &EngineState, call: &Call) -> Result<PipelineData, ShellError> {
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
let long = call.has_flag("long");
|
let long = call.has_flag("long");
|
||||||
let mut sys = System::new_all();
|
let mut sys = System::new_all();
|
||||||
@ -126,5 +126,7 @@ fn run_ps(call: &Call) -> Result<PipelineData, ShellError> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(output.into_iter().into_pipeline_data())
|
Ok(output
|
||||||
|
.into_iter()
|
||||||
|
.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ use std::sync::mpsc;
|
|||||||
|
|
||||||
use nu_protocol::engine::{EngineState, Stack};
|
use nu_protocol::engine::{EngineState, Stack};
|
||||||
use nu_protocol::{ast::Call, engine::Command, ShellError, Signature, SyntaxShape, Value};
|
use nu_protocol::{ast::Call, engine::Command, ShellError, Signature, SyntaxShape, Value};
|
||||||
use nu_protocol::{IntoPipelineData, PipelineData, Span, Spanned};
|
use nu_protocol::{IntoInterruptiblePipelineData, PipelineData, Span, Spanned};
|
||||||
|
|
||||||
use nu_engine::CallExt;
|
use nu_engine::CallExt;
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ impl Command for External {
|
|||||||
last_expression,
|
last_expression,
|
||||||
env_vars,
|
env_vars,
|
||||||
};
|
};
|
||||||
command.run_with_input(input)
|
command.run_with_input(engine_state, input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,9 +61,15 @@ pub struct ExternalCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ExternalCommand {
|
impl ExternalCommand {
|
||||||
pub fn run_with_input(&self, input: PipelineData) -> Result<PipelineData, ShellError> {
|
pub fn run_with_input(
|
||||||
|
&self,
|
||||||
|
engine_state: &EngineState,
|
||||||
|
input: PipelineData,
|
||||||
|
) -> Result<PipelineData, ShellError> {
|
||||||
let mut process = self.create_command();
|
let mut process = self.create_command();
|
||||||
|
|
||||||
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
|
|
||||||
// TODO. We don't have a way to know the current directory
|
// TODO. We don't have a way to know the current directory
|
||||||
// This should be information from the EvaluationContex or EngineState
|
// This should be information from the EvaluationContex or EngineState
|
||||||
let path = env::current_dir().unwrap();
|
let path = env::current_dir().unwrap();
|
||||||
@ -155,7 +161,7 @@ impl ExternalCommand {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// The ValueStream is consumed by the next expression in the pipeline
|
// The ValueStream is consumed by the next expression in the pipeline
|
||||||
ChannelReceiver::new(rx).into_pipeline_data()
|
ChannelReceiver::new(rx).into_pipeline_data(ctrlc)
|
||||||
} else {
|
} else {
|
||||||
PipelineData::new()
|
PipelineData::new()
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
use super::Command;
|
use super::Command;
|
||||||
use crate::{ast::Block, BlockId, DeclId, Example, Signature, Span, Type, VarId};
|
use crate::{ast::Block, BlockId, DeclId, Example, Signature, Span, Type, VarId};
|
||||||
use core::panic;
|
use core::panic;
|
||||||
use std::collections::HashMap;
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
sync::{atomic::AtomicBool, Arc},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct EngineState {
|
pub struct EngineState {
|
||||||
@ -11,6 +14,7 @@ pub struct EngineState {
|
|||||||
decls: im::Vector<Box<dyn Command + 'static>>,
|
decls: im::Vector<Box<dyn Command + 'static>>,
|
||||||
blocks: im::Vector<Block>,
|
blocks: im::Vector<Block>,
|
||||||
pub scope: im::Vector<ScopeFrame>,
|
pub scope: im::Vector<ScopeFrame>,
|
||||||
|
pub ctrlc: Option<Arc<AtomicBool>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tells whether a decl etc. is visible or not
|
// Tells whether a decl etc. is visible or not
|
||||||
@ -102,6 +106,7 @@ impl EngineState {
|
|||||||
decls: im::vector![],
|
decls: im::vector![],
|
||||||
blocks: im::vector![],
|
blocks: im::vector![],
|
||||||
scope: im::vector![ScopeFrame::new()],
|
scope: im::vector![ScopeFrame::new()],
|
||||||
|
ctrlc: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use std::sync::{atomic::AtomicBool, Arc};
|
||||||
|
|
||||||
use crate::{ast::PathMember, ShellError, Span, Value, ValueStream};
|
use crate::{ast::PathMember, ShellError, Span, Value, ValueStream};
|
||||||
|
|
||||||
pub enum PipelineData {
|
pub enum PipelineData {
|
||||||
@ -40,18 +42,22 @@ impl PipelineData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Simplified mapper to help with simple values also. For full iterator support use `.into_iter()` instead
|
/// Simplified mapper to help with simple values also. For full iterator support use `.into_iter()` instead
|
||||||
pub fn map<F>(self, mut f: F) -> Result<PipelineData, ShellError>
|
pub fn map<F>(
|
||||||
|
self,
|
||||||
|
mut f: F,
|
||||||
|
ctrlc: Option<Arc<AtomicBool>>,
|
||||||
|
) -> Result<PipelineData, ShellError>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: FnMut(Value) -> Value + 'static + Send,
|
F: FnMut(Value) -> Value + 'static + Send,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
PipelineData::Value(Value::List { vals, .. }) => {
|
PipelineData::Value(Value::List { vals, .. }) => {
|
||||||
Ok(vals.into_iter().map(f).into_pipeline_data())
|
Ok(vals.into_iter().map(f).into_pipeline_data(ctrlc))
|
||||||
}
|
}
|
||||||
PipelineData::Stream(stream) => Ok(stream.map(f).into_pipeline_data()),
|
PipelineData::Stream(stream) => Ok(stream.map(f).into_pipeline_data(ctrlc)),
|
||||||
PipelineData::Value(Value::Range { val, .. }) => {
|
PipelineData::Value(Value::Range { val, .. }) => {
|
||||||
Ok(val.into_range_iter()?.map(f).into_pipeline_data())
|
Ok(val.into_range_iter()?.map(f).into_pipeline_data(ctrlc))
|
||||||
}
|
}
|
||||||
PipelineData::Value(v) => {
|
PipelineData::Value(v) => {
|
||||||
let output = f(v);
|
let output = f(v);
|
||||||
@ -64,7 +70,11 @@ impl PipelineData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Simplified flatmapper. For full iterator support use `.into_iter()` instead
|
/// Simplified flatmapper. For full iterator support use `.into_iter()` instead
|
||||||
pub fn flat_map<U, F>(self, mut f: F) -> Result<PipelineData, ShellError>
|
pub fn flat_map<U, F>(
|
||||||
|
self,
|
||||||
|
mut f: F,
|
||||||
|
ctrlc: Option<Arc<AtomicBool>>,
|
||||||
|
) -> Result<PipelineData, ShellError>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
U: IntoIterator<Item = Value>,
|
U: IntoIterator<Item = Value>,
|
||||||
@ -73,14 +83,14 @@ impl PipelineData {
|
|||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
PipelineData::Value(Value::List { vals, .. }) => {
|
PipelineData::Value(Value::List { vals, .. }) => {
|
||||||
Ok(vals.into_iter().map(f).flatten().into_pipeline_data())
|
Ok(vals.into_iter().map(f).flatten().into_pipeline_data(ctrlc))
|
||||||
}
|
}
|
||||||
PipelineData::Stream(stream) => Ok(stream.map(f).flatten().into_pipeline_data()),
|
PipelineData::Stream(stream) => Ok(stream.map(f).flatten().into_pipeline_data(ctrlc)),
|
||||||
PipelineData::Value(Value::Range { val, .. }) => match val.into_range_iter() {
|
PipelineData::Value(Value::Range { val, .. }) => match val.into_range_iter() {
|
||||||
Ok(iter) => Ok(iter.map(f).flatten().into_pipeline_data()),
|
Ok(iter) => Ok(iter.map(f).flatten().into_pipeline_data(ctrlc)),
|
||||||
Err(error) => Err(error),
|
Err(error) => Err(error),
|
||||||
},
|
},
|
||||||
PipelineData::Value(v) => Ok(f(v).into_iter().into_pipeline_data()),
|
PipelineData::Value(v) => Ok(f(v).into_iter().into_pipeline_data(ctrlc)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,9 +110,12 @@ impl IntoIterator for PipelineData {
|
|||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
match self {
|
match self {
|
||||||
PipelineData::Value(Value::List { vals, .. }) => PipelineIterator(
|
PipelineData::Value(Value::List { vals, .. }) => {
|
||||||
PipelineData::Stream(ValueStream(Box::new(vals.into_iter()))),
|
PipelineIterator(PipelineData::Stream(ValueStream {
|
||||||
),
|
stream: Box::new(vals.into_iter()),
|
||||||
|
ctrlc: None,
|
||||||
|
}))
|
||||||
|
}
|
||||||
x => PipelineIterator(x),
|
x => PipelineIterator(x),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,11 +146,18 @@ impl IntoPipelineData for Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> IntoPipelineData for T
|
pub trait IntoInterruptiblePipelineData {
|
||||||
|
fn into_pipeline_data(self, ctrlc: Option<Arc<AtomicBool>>) -> PipelineData;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> IntoInterruptiblePipelineData for T
|
||||||
where
|
where
|
||||||
T: Iterator<Item = Value> + Send + 'static,
|
T: Iterator<Item = Value> + Send + 'static,
|
||||||
{
|
{
|
||||||
fn into_pipeline_data(self) -> PipelineData {
|
fn into_pipeline_data(self, ctrlc: Option<Arc<AtomicBool>>) -> PipelineData {
|
||||||
PipelineData::Stream(ValueStream(Box::new(self)))
|
PipelineData::Stream(ValueStream {
|
||||||
|
stream: Box::new(self),
|
||||||
|
ctrlc,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,16 @@
|
|||||||
use crate::*;
|
use crate::*;
|
||||||
use std::fmt::Debug;
|
use std::{
|
||||||
|
fmt::Debug,
|
||||||
|
sync::{
|
||||||
|
atomic::{AtomicBool, Ordering},
|
||||||
|
Arc,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
pub struct ValueStream(pub Box<dyn Iterator<Item = Value> + Send + 'static>);
|
pub struct ValueStream {
|
||||||
|
pub stream: Box<dyn Iterator<Item = Value> + Send + 'static>,
|
||||||
|
pub ctrlc: Option<Arc<AtomicBool>>,
|
||||||
|
}
|
||||||
|
|
||||||
impl ValueStream {
|
impl ValueStream {
|
||||||
pub fn into_string(self) -> String {
|
pub fn into_string(self) -> String {
|
||||||
@ -19,8 +28,14 @@ impl ValueStream {
|
|||||||
.join("\n")
|
.join("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_stream(input: impl Iterator<Item = Value> + Send + 'static) -> ValueStream {
|
pub fn from_stream(
|
||||||
ValueStream(Box::new(input))
|
input: impl Iterator<Item = Value> + Send + 'static,
|
||||||
|
ctrlc: Option<Arc<AtomicBool>>,
|
||||||
|
) -> ValueStream {
|
||||||
|
ValueStream {
|
||||||
|
stream: Box::new(input),
|
||||||
|
ctrlc,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,8 +49,14 @@ impl Iterator for ValueStream {
|
|||||||
type Item = Value;
|
type Item = Value;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
{
|
if let Some(ctrlc) = &self.ctrlc {
|
||||||
self.0.next()
|
if ctrlc.load(Ordering::SeqCst) {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
self.stream.next()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.stream.next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
25
src/main.rs
25
src/main.rs
@ -1,4 +1,10 @@
|
|||||||
use std::io::Write;
|
use std::{
|
||||||
|
io::Write,
|
||||||
|
sync::{
|
||||||
|
atomic::{AtomicBool, Ordering},
|
||||||
|
Arc,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
use dialoguer::{
|
use dialoguer::{
|
||||||
console::{Style, Term},
|
console::{Style, Term},
|
||||||
@ -84,6 +90,20 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
let mut engine_state = create_default_context();
|
let mut engine_state = create_default_context();
|
||||||
|
|
||||||
|
// TODO: make this conditional in the future
|
||||||
|
// Ctrl-c protection section
|
||||||
|
let ctrlc = Arc::new(AtomicBool::new(false));
|
||||||
|
let handler_ctrlc = ctrlc.clone();
|
||||||
|
let engine_state_ctrlc = ctrlc.clone();
|
||||||
|
|
||||||
|
ctrlc::set_handler(move || {
|
||||||
|
handler_ctrlc.store(true, Ordering::SeqCst);
|
||||||
|
})
|
||||||
|
.expect("Error setting Ctrl-C handler");
|
||||||
|
|
||||||
|
engine_state.ctrlc = Some(engine_state_ctrlc);
|
||||||
|
// End ctrl-c protection section
|
||||||
|
|
||||||
if let Some(path) = std::env::args().nth(1) {
|
if let Some(path) = std::env::args().nth(1) {
|
||||||
let file = std::fs::read(&path).into_diagnostic()?;
|
let file = std::fs::read(&path).into_diagnostic()?;
|
||||||
|
|
||||||
@ -153,6 +173,9 @@ fn main() -> Result<()> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
//Reset the ctrl-c handler
|
||||||
|
ctrlc.store(false, Ordering::SeqCst);
|
||||||
|
|
||||||
let line_editor = Reedline::create()
|
let line_editor = Reedline::create()
|
||||||
.into_diagnostic()?
|
.into_diagnostic()?
|
||||||
.with_completion_action_handler(Box::new(FuzzyCompletion {
|
.with_completion_action_handler(Box::new(FuzzyCompletion {
|
||||||
|
Loading…
Reference in New Issue
Block a user