Add and use new Signals struct (#13314)

# Description
This PR introduces a new `Signals` struct to replace our adhoc passing
around of `ctrlc: Option<Arc<AtomicBool>>`. Doing so has a few benefits:
- We can better enforce when/where resetting or triggering an interrupt
is allowed.
- Consolidates `nu_utils::ctrl_c::was_pressed` and other ad-hoc
re-implementations into a single place: `Signals::check`.
- This allows us to add other types of signals later if we want. E.g.,
exiting or suspension.
- Similarly, we can more easily change the underlying implementation if
we need to in the future.
- Places that used to have a `ctrlc` of `None` now use
`Signals::empty()`, so we can double check these usages for correctness
in the future.
This commit is contained in:
Ian Manske
2024-07-07 22:29:01 +00:00
committed by GitHub
parent c6b6b1b7a8
commit 399a7c8836
246 changed files with 1332 additions and 1234 deletions

View File

@ -42,10 +42,7 @@ impl Command for SubCommand {
input: PipelineData,
) -> Result<PipelineData, ShellError> {
let head = call.head;
input.map(
move |value| abs_helper(value, head),
engine_state.ctrlc.clone(),
)
input.map(move |value| abs_helper(value, head), engine_state.signals())
}
fn examples(&self) -> Vec<Example> {

View File

@ -41,10 +41,7 @@ impl Command for SubCommand {
if matches!(input, PipelineData::Empty) {
return Err(ShellError::PipelineEmpty { dst_span: head });
}
input.map(
move |value| operate(value, head),
engine_state.ctrlc.clone(),
)
input.map(move |value| operate(value, head), engine_state.signals())
}
fn examples(&self) -> Vec<Example> {

View File

@ -41,10 +41,7 @@ impl Command for SubCommand {
if matches!(input, PipelineData::Empty) {
return Err(ShellError::PipelineEmpty { dst_span: head });
}
input.map(
move |value| operate(value, head),
engine_state.ctrlc.clone(),
)
input.map(move |value| operate(value, head), engine_state.signals())
}
fn examples(&self) -> Vec<Example> {

View File

@ -59,7 +59,7 @@ impl Command for SubCommand {
let base = base.item;
input.map(
move |value| operate(value, head, base),
engine_state.ctrlc.clone(),
engine_state.signals(),
)
}

View File

@ -50,7 +50,7 @@ impl Command for SubCommand {
}
input.map(
move |value| operate(value, head, precision_param),
engine_state.ctrlc.clone(),
engine_state.signals(),
)
}

View File

@ -41,10 +41,7 @@ impl Command for SubCommand {
if matches!(input, PipelineData::Empty) {
return Err(ShellError::PipelineEmpty { dst_span: head });
}
input.map(
move |value| operate(value, head),
engine_state.ctrlc.clone(),
)
input.map(move |value| operate(value, head), engine_state.signals())
}
fn examples(&self) -> Vec<Example> {

View File

@ -1,6 +1,6 @@
use core::slice;
use indexmap::IndexMap;
use nu_protocol::{ast::Call, IntoPipelineData, PipelineData, ShellError, Span, Value};
use nu_protocol::{ast::Call, IntoPipelineData, PipelineData, ShellError, Signals, Span, Value};
pub fn run_with_function(
call: &Call,
@ -92,7 +92,7 @@ pub fn calculate(
}
PipelineData::Value(Value::Range { val, .. }, ..) => {
let new_vals: Result<Vec<Value>, ShellError> = val
.into_range_iter(span, None)
.into_range_iter(span, Signals::empty())
.map(|val| mf(&[val], span, name))
.collect();