Fix for loop ctrlc not terminating (#5003)

This commit is contained in:
JT 2022-03-28 19:13:43 +13:00 committed by GitHub
parent a87f53072a
commit 2e3b74f1b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 37 additions and 19 deletions

View File

@ -125,7 +125,7 @@ https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-
.filter(|x| !x.is_nothing()) .filter(|x| !x.is_nothing())
.into_pipeline_data(ctrlc)), .into_pipeline_data(ctrlc)),
Value::Range { val, .. } => Ok(val Value::Range { val, .. } => Ok(val
.into_range_iter()? .into_range_iter(ctrlc.clone())?
.enumerate() .enumerate()
.map(move |(idx, x)| { .map(move |(idx, x)| {
stack.with_env(&orig_env_vars, &orig_env_hidden); stack.with_env(&orig_env_vars, &orig_env_hidden);

View File

@ -71,7 +71,7 @@ impl Command for ParEach {
match input { match input {
PipelineData::Value(Value::Range { val, .. }, ..) => Ok(val PipelineData::Value(Value::Range { val, .. }, ..) => Ok(val
.into_range_iter()? .into_range_iter(ctrlc.clone())?
.enumerate() .enumerate()
.par_bridge() .par_bridge()
.map(move |(idx, x)| { .map(move |(idx, x)| {

View File

@ -81,7 +81,7 @@ pub fn calculate(
} }
PipelineData::Value(Value::Range { val, .. }, ..) => { PipelineData::Value(Value::Range { val, .. }, ..) => {
let new_vals: Result<Vec<Value>, ShellError> = val let new_vals: Result<Vec<Value>, ShellError> = val
.into_range_iter()? .into_range_iter(None)?
.map(|val| mf(&[val], &name)) .map(|val| mf(&[val], &name))
.collect(); .collect();

View File

@ -283,9 +283,10 @@ impl PipelineData {
} }
} }
PipelineData::Value(Value::Range { val, .. }, ..) => { PipelineData::Value(Value::Range { val, .. }, ..) => Ok(val
Ok(val.into_range_iter()?.map(f).into_pipeline_data(ctrlc)) .into_range_iter(ctrlc.clone())?
} .map(f)
.into_pipeline_data(ctrlc)),
PipelineData::Value(v, ..) => match f(v) { PipelineData::Value(v, ..) => match f(v) {
Value::Error { error } => Err(error), Value::Error { error } => Err(error),
v => Ok(v.into_pipeline_data()), v => Ok(v.into_pipeline_data()),
@ -337,10 +338,12 @@ impl PipelineData {
.into_pipeline_data(ctrlc)) .into_pipeline_data(ctrlc))
} }
} }
PipelineData::Value(Value::Range { val, .. }, ..) => match val.into_range_iter() { PipelineData::Value(Value::Range { val, .. }, ..) => {
Ok(iter) => Ok(iter.flat_map(f).into_pipeline_data(ctrlc)), match val.into_range_iter(ctrlc.clone()) {
Err(error) => Err(error), Ok(iter) => Ok(iter.flat_map(f).into_pipeline_data(ctrlc)),
}, Err(error) => Err(error),
}
}
PipelineData::Value(v, ..) => Ok(f(v).into_iter().into_pipeline_data(ctrlc)), PipelineData::Value(v, ..) => Ok(f(v).into_iter().into_pipeline_data(ctrlc)),
} }
} }
@ -392,9 +395,10 @@ impl PipelineData {
} }
} }
} }
PipelineData::Value(Value::Range { val, .. }, ..) => { PipelineData::Value(Value::Range { val, .. }, ..) => Ok(val
Ok(val.into_range_iter()?.filter(f).into_pipeline_data(ctrlc)) .into_range_iter(ctrlc.clone())?
} .filter(f)
.into_pipeline_data(ctrlc)),
PipelineData::Value(v, ..) => { PipelineData::Value(v, ..) => {
if f(&v) { if f(&v) {
Ok(v.into_pipeline_data()) Ok(v.into_pipeline_data())
@ -425,7 +429,7 @@ impl IntoIterator for PipelineData {
)) ))
} }
PipelineData::Value(Value::Range { val, .. }, metadata) => { PipelineData::Value(Value::Range { val, .. }, metadata) => {
match val.into_range_iter() { match val.into_range_iter(None) {
Ok(iter) => PipelineIterator(PipelineData::ListStream( Ok(iter) => PipelineIterator(PipelineData::ListStream(
ListStream { ListStream {
stream: Box::new(iter), stream: Box::new(iter),

View File

@ -605,7 +605,7 @@ impl Value {
} }
} }
Value::Range { val, .. } => { Value::Range { val, .. } => {
if let Some(item) = val.clone().into_range_iter()?.nth(*count) { if let Some(item) = val.clone().into_range_iter(None)?.nth(*count) {
current = item.clone(); current = item.clone();
} else { } else {
return Err(ShellError::AccessBeyondEndOfStream(*origin_span)); return Err(ShellError::AccessBeyondEndOfStream(*origin_span));

View File

@ -1,5 +1,8 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::cmp::Ordering; use std::{
cmp::Ordering,
sync::{atomic::AtomicBool, Arc},
};
/// A Range is an iterator over integers. /// A Range is an iterator over integers.
use crate::{ use crate::{
@ -122,10 +125,13 @@ impl Range {
} }
} }
pub fn into_range_iter(self) -> Result<RangeIterator, ShellError> { pub fn into_range_iter(
self,
ctrlc: Option<Arc<AtomicBool>>,
) -> Result<RangeIterator, ShellError> {
let span = self.from.span()?; let span = self.from.span()?;
Ok(RangeIterator::new(self, span)) Ok(RangeIterator::new(self, ctrlc, span))
} }
} }
@ -155,10 +161,11 @@ pub struct RangeIterator {
moves_up: bool, moves_up: bool,
incr: Value, incr: Value,
done: bool, done: bool,
ctrlc: Option<Arc<AtomicBool>>,
} }
impl RangeIterator { impl RangeIterator {
pub fn new(range: Range, span: Span) -> RangeIterator { pub fn new(range: Range, ctrlc: Option<Arc<AtomicBool>>, span: Span) -> RangeIterator {
let moves_up = range.moves_up(); let moves_up = range.moves_up();
let is_end_inclusive = range.is_end_inclusive(); let is_end_inclusive = range.is_end_inclusive();
@ -183,6 +190,7 @@ impl RangeIterator {
is_end_inclusive, is_end_inclusive,
done: false, done: false,
incr: range.incr, incr: range.incr,
ctrlc,
} }
} }
} }
@ -194,6 +202,12 @@ impl Iterator for RangeIterator {
return None; return None;
} }
if let Some(ctrlc) = &self.ctrlc {
if ctrlc.load(core::sync::atomic::Ordering::SeqCst) {
return None;
}
}
let ordering = if matches!(self.end, Value::Nothing { .. }) { let ordering = if matches!(self.end, Value::Nothing { .. }) {
Some(Ordering::Less) Some(Ordering::Less)
} else { } else {