diff --git a/crates/nu-command/src/core_commands/loop_.rs b/crates/nu-command/src/core_commands/loop_.rs index 1b4befd871..29560f28cd 100644 --- a/crates/nu-command/src/core_commands/loop_.rs +++ b/crates/nu-command/src/core_commands/loop_.rs @@ -1,5 +1,3 @@ -use std::sync::atomic::Ordering; - use nu_engine::{eval_block, CallExt}; use nu_protocol::ast::Call; use nu_protocol::engine::{Block, Command, EngineState, Stack}; @@ -44,10 +42,8 @@ impl Command for Loop { let block: Block = call.req(engine_state, stack, 0)?; loop { - if let Some(ctrlc) = &engine_state.ctrlc { - if ctrlc.load(Ordering::SeqCst) { - break; - } + if nu_utils::ctrl_c::was_pressed(&engine_state.ctrlc) { + break; } let block = engine_state.get_block(block.block_id); diff --git a/crates/nu-command/src/core_commands/while_.rs b/crates/nu-command/src/core_commands/while_.rs index 57b4da9b4c..da871e8527 100644 --- a/crates/nu-command/src/core_commands/while_.rs +++ b/crates/nu-command/src/core_commands/while_.rs @@ -1,5 +1,3 @@ -use std::sync::atomic::Ordering; - use nu_engine::{eval_block, eval_expression, CallExt}; use nu_protocol::ast::Call; use nu_protocol::engine::{Block, Command, EngineState, Stack}; @@ -48,10 +46,8 @@ impl Command for While { let block: Block = call.req(engine_state, stack, 1)?; loop { - if let Some(ctrlc) = &engine_state.ctrlc { - if ctrlc.load(Ordering::SeqCst) { - break; - } + if nu_utils::ctrl_c::was_pressed(&engine_state.ctrlc) { + break; } let result = eval_expression(engine_state, stack, cond)?; diff --git a/crates/nu-command/src/database/values/sqlite.rs b/crates/nu-command/src/database/values/sqlite.rs index d0cd0b65df..714c4c95cb 100644 --- a/crates/nu-command/src/database/values/sqlite.rs +++ b/crates/nu-command/src/database/values/sqlite.rs @@ -10,10 +10,7 @@ use std::{ fs::File, io::Read, path::{Path, PathBuf}, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, - }, + sync::{atomic::AtomicBool, Arc}, }; const SQLITE_MAGIC_BYTES: &[u8] = "SQLite format 3\0".as_bytes(); @@ -399,14 +396,12 @@ fn prepared_statement_to_nu_list( let mut row_values = vec![]; for row_result in row_results { - if let Some(ctrlc) = &ctrlc { - if ctrlc.load(Ordering::SeqCst) { - // return whatever we have so far, let the caller decide whether to use it - return Ok(Value::List { - vals: row_values, - span: call_span, - }); - } + if nu_utils::ctrl_c::was_pressed(&ctrlc) { + // return whatever we have so far, let the caller decide whether to use it + return Ok(Value::List { + vals: row_values, + span: call_span, + }); } if let Ok(row_value) = row_result { diff --git a/crates/nu-command/src/filesystem/watch.rs b/crates/nu-command/src/filesystem/watch.rs index cc8d1d5628..809ae2c6d0 100644 --- a/crates/nu-command/src/filesystem/watch.rs +++ b/crates/nu-command/src/filesystem/watch.rs @@ -1,5 +1,4 @@ use std::path::PathBuf; -use std::sync::atomic::Ordering; use std::sync::mpsc::{channel, RecvTimeoutError}; use std::time::Duration; @@ -252,10 +251,8 @@ impl Command for Watch { } Err(RecvTimeoutError::Timeout) => {} } - if let Some(ctrlc) = ctrlc_ref { - if ctrlc.load(Ordering::SeqCst) { - break; - } + if nu_utils::ctrl_c::was_pressed(ctrlc_ref) { + break; } } diff --git a/crates/nu-command/src/filters/reduce.rs b/crates/nu-command/src/filters/reduce.rs index 5f50308dc9..ef48957ff8 100644 --- a/crates/nu-command/src/filters/reduce.rs +++ b/crates/nu-command/src/filters/reduce.rs @@ -1,5 +1,3 @@ -use std::sync::atomic::Ordering; - use nu_engine::{eval_block, CallExt}; use nu_protocol::ast::Call; @@ -217,10 +215,8 @@ impl Command for Reduce { )? .into_value(span); - if let Some(ctrlc) = &ctrlc { - if ctrlc.load(Ordering::SeqCst) { - break; - } + if nu_utils::ctrl_c::was_pressed(&ctrlc) { + break; } } diff --git a/crates/nu-command/src/filters/uniq.rs b/crates/nu-command/src/filters/uniq.rs index aed95f24dd..2ffd399ab1 100644 --- a/crates/nu-command/src/filters/uniq.rs +++ b/crates/nu-command/src/filters/uniq.rs @@ -1,4 +1,3 @@ -use crate::input_handler::ctrl_c_was_pressed; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::{ @@ -231,7 +230,7 @@ pub fn uniq( let mut uniq_values = input .into_iter() .map_while(|item| { - if ctrl_c_was_pressed(&ctrlc) { + if nu_utils::ctrl_c::was_pressed(&ctrlc) { return None; } Some(item_mapper(ItemMapperState { diff --git a/crates/nu-command/src/input_handler.rs b/crates/nu-command/src/input_handler.rs index c9694bcfa9..342c00bf60 100644 --- a/crates/nu-command/src/input_handler.rs +++ b/crates/nu-command/src/input_handler.rs @@ -1,6 +1,6 @@ use nu_protocol::ast::CellPath; use nu_protocol::{PipelineData, ShellError, Span, Value}; -use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::atomic::AtomicBool; use std::sync::Arc; pub trait CmdArgument { @@ -71,12 +71,3 @@ where } } } - -// Helper method to avoid boilerplate every time we check ctrl+c -pub fn ctrl_c_was_pressed(ctrlc: &Option>) -> bool { - if let Some(ctrlc) = ctrlc { - ctrlc.load(Ordering::SeqCst) - } else { - false - } -} diff --git a/crates/nu-command/src/platform/dir_info.rs b/crates/nu-command/src/platform/dir_info.rs index 8f8f761115..13d566b305 100644 --- a/crates/nu-command/src/platform/dir_info.rs +++ b/crates/nu-command/src/platform/dir_info.rs @@ -2,7 +2,7 @@ use filesize::file_real_size_fast; use nu_glob::Pattern; use nu_protocol::{ShellError, Span, Value}; use std::path::PathBuf; -use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::atomic::AtomicBool; use std::sync::Arc; #[derive(Debug, Clone)] @@ -106,13 +106,8 @@ impl DirInfo { match std::fs::read_dir(&s.path) { Ok(d) => { for f in d { - match ctrl_c { - Some(ref cc) => { - if cc.load(Ordering::SeqCst) { - break; - } - } - None => continue, + if nu_utils::ctrl_c::was_pressed(&ctrl_c) { + break; } match f { diff --git a/crates/nu-command/src/platform/sleep.rs b/crates/nu-command/src/platform/sleep.rs index da24a67ae4..3be4ec76df 100644 --- a/crates/nu-command/src/platform/sleep.rs +++ b/crates/nu-command/src/platform/sleep.rs @@ -6,7 +6,6 @@ use nu_protocol::{ Type, Value, }; use std::{ - sync::atomic::Ordering, thread, time::{Duration, Instant}, }; @@ -62,10 +61,8 @@ impl Command for Sleep { break; } - if let Some(ctrlc) = ctrlc_ref { - if ctrlc.load(Ordering::SeqCst) { - break; - } + if nu_utils::ctrl_c::was_pressed(ctrlc_ref) { + break; } } diff --git a/crates/nu-command/src/system/run_external.rs b/crates/nu-command/src/system/run_external.rs index 06795d5c95..0afaf42eab 100644 --- a/crates/nu-command/src/system/run_external.rs +++ b/crates/nu-command/src/system/run_external.rs @@ -13,7 +13,7 @@ use std::collections::HashMap; use std::io::{BufRead, BufReader, Read, Write}; use std::path::{Path, PathBuf}; use std::process::{Command as CommandSys, Stdio}; -use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::atomic::AtomicBool; use std::sync::mpsc::{self, SyncSender}; use std::sync::Arc; @@ -745,10 +745,8 @@ fn read_and_redirect_message( let length = bytes.len(); buf_read.consume(length); - if let Some(ctrlc) = &ctrlc { - if ctrlc.load(Ordering::SeqCst) { - break; - } + if nu_utils::ctrl_c::was_pressed(&ctrlc) { + break; } match sender.send(bytes) { diff --git a/crates/nu-command/src/viewers/table.rs b/crates/nu-command/src/viewers/table.rs index b532b0e204..4ec621d912 100644 --- a/crates/nu-command/src/viewers/table.rs +++ b/crates/nu-command/src/viewers/table.rs @@ -12,12 +12,7 @@ use nu_table::{string_width, Alignment, Table as NuTable, TableConfig, TableThem use nu_utils::get_ls_colors; use std::sync::Arc; use std::time::Instant; -use std::{ - cmp::max, - collections::HashMap, - path::PathBuf, - sync::atomic::{AtomicBool, Ordering}, -}; +use std::{cmp::max, collections::HashMap, path::PathBuf, sync::atomic::AtomicBool}; use terminal_size::{Height, Width}; use url::Url; @@ -304,13 +299,8 @@ fn handle_table_command( let result = strip_output_color(result, config); - let ctrl_c_was_triggered = || match &ctrlc { - Some(ctrlc) => ctrlc.load(Ordering::SeqCst), - None => false, - }; - let result = result.unwrap_or_else(|| { - if ctrl_c_was_triggered() { + if nu_utils::ctrl_c::was_pressed(&ctrlc) { "".into() } else { // assume this failed because the table was too wide @@ -397,11 +387,8 @@ fn build_general_table2( ) -> Result, ShellError> { let mut data = Vec::with_capacity(vals.len()); for (column, value) in cols.into_iter().zip(vals.into_iter()) { - // handle CTRLC event - if let Some(ctrlc) = &ctrlc { - if ctrlc.load(Ordering::SeqCst) { - return Ok(None); - } + if nu_utils::ctrl_c::was_pressed(&ctrlc) { + return Ok(None); } let row = vec![ @@ -460,11 +447,8 @@ fn build_expanded_table( let mut data = Vec::with_capacity(cols.len()); for (key, value) in cols.into_iter().zip(vals) { - // handle CTRLC event - if let Some(ctrlc) = &ctrlc { - if ctrlc.load(Ordering::SeqCst) { - return Ok(None); - } + if nu_utils::ctrl_c::was_pressed(&ctrlc) { + return Ok(None); } let is_limited = matches!(expand_limit, Some(0)); @@ -810,10 +794,8 @@ fn convert_to_table( }; for (row_num, item) in input.enumerate() { - if let Some(ctrlc) = &ctrlc { - if ctrlc.load(Ordering::SeqCst) { - return Ok(None); - } + if nu_utils::ctrl_c::was_pressed(&ctrlc) { + return Ok(None); } if let Value::Error { error } = item { @@ -925,10 +907,8 @@ fn convert_to_table2<'a>( } for (row, item) in input.clone().into_iter().enumerate() { - if let Some(ctrlc) = &ctrlc { - if ctrlc.load(Ordering::SeqCst) { - return Ok(None); - } + if nu_utils::ctrl_c::was_pressed(&ctrlc) { + return Ok(None); } if let Value::Error { error } = item { @@ -960,10 +940,8 @@ fn convert_to_table2<'a>( if !with_header { for (row, item) in input.into_iter().enumerate() { - if let Some(ctrlc) = &ctrlc { - if ctrlc.load(Ordering::SeqCst) { - return Ok(None); - } + if nu_utils::ctrl_c::was_pressed(&ctrlc) { + return Ok(None); } if let Value::Error { error } = item { @@ -1019,10 +997,8 @@ fn convert_to_table2<'a>( data[0].push(NuTable::create_cell(&header, header_style(color_hm))); for (row, item) in input.clone().into_iter().enumerate() { - if let Some(ctrlc) = &ctrlc { - if ctrlc.load(Ordering::SeqCst) { - return Ok(None); - } + if nu_utils::ctrl_c::was_pressed(&ctrlc) { + return Ok(None); } if let Value::Error { error } = item { @@ -1059,10 +1035,8 @@ fn convert_to_table2<'a>( column_width = string_width(&header); for (row, item) in input.clone().into_iter().enumerate() { - if let Some(ctrlc) = &ctrlc { - if ctrlc.load(Ordering::SeqCst) { - return Ok(None); - } + if nu_utils::ctrl_c::was_pressed(&ctrlc) { + return Ok(None); } let value = create_table2_entry_basic(item, &header, head, config, color_hm); @@ -1086,10 +1060,8 @@ fn convert_to_table2<'a>( column_width = string_width(&header); for (row, item) in input.clone().into_iter().enumerate() { - if let Some(ctrlc) = &ctrlc { - if ctrlc.load(Ordering::SeqCst) { - return Ok(None); - } + if nu_utils::ctrl_c::was_pressed(&ctrlc) { + return Ok(None); } let value = create_table2_entry_basic(item, &header, head, config, color_hm); @@ -1593,10 +1565,8 @@ impl Iterator for PagingTableCreator { break; } - if let Some(ctrlc) = &self.ctrlc { - if ctrlc.load(Ordering::SeqCst) { - break; - } + if nu_utils::ctrl_c::was_pressed(&self.ctrlc) { + break; } } diff --git a/crates/nu-engine/src/eval.rs b/crates/nu-engine/src/eval.rs index 34d60cf874..8bea5f4143 100644 --- a/crates/nu-engine/src/eval.rs +++ b/crates/nu-engine/src/eval.rs @@ -31,10 +31,8 @@ pub fn eval_call( call: &Call, input: PipelineData, ) -> Result { - if let Some(ctrlc) = &engine_state.ctrlc { - if ctrlc.load(core::sync::atomic::Ordering::SeqCst) { - return Ok(Value::Nothing { span: call.head }.into_pipeline_data()); - } + if nu_utils::ctrl_c::was_pressed(&engine_state.ctrlc) { + return Ok(Value::Nothing { span: call.head }.into_pipeline_data()); } let decl = engine_state.get_decl(call.decl_id); diff --git a/crates/nu-protocol/src/value/range.rs b/crates/nu-protocol/src/value/range.rs index decea873eb..1f8f5a7492 100644 --- a/crates/nu-protocol/src/value/range.rs +++ b/crates/nu-protocol/src/value/range.rs @@ -203,10 +203,8 @@ impl Iterator for RangeIterator { return None; } - if let Some(ctrlc) = &self.ctrlc { - if ctrlc.load(core::sync::atomic::Ordering::SeqCst) { - return None; - } + if nu_utils::ctrl_c::was_pressed(&self.ctrlc) { + return None; } let ordering = if matches!(self.end, Value::Nothing { .. }) { diff --git a/crates/nu-protocol/src/value/stream.rs b/crates/nu-protocol/src/value/stream.rs index af0a6dd760..a13e0d95a6 100644 --- a/crates/nu-protocol/src/value/stream.rs +++ b/crates/nu-protocol/src/value/stream.rs @@ -1,10 +1,7 @@ use crate::*; use std::{ fmt::Debug, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, - }, + sync::{atomic::AtomicBool, Arc}, }; pub struct RawStream { @@ -77,10 +74,8 @@ impl Iterator for RawStream { type Item = Result; fn next(&mut self) -> Option { - if let Some(ctrlc) = &self.ctrlc { - if ctrlc.load(Ordering::SeqCst) { - return None; - } + if nu_utils::ctrl_c::was_pressed(&self.ctrlc) { + return None; } // If we know we're already binary, just output that @@ -223,12 +218,8 @@ impl Iterator for ListStream { type Item = Value; fn next(&mut self) -> Option { - if let Some(ctrlc) = &self.ctrlc { - if ctrlc.load(Ordering::SeqCst) { - None - } else { - self.stream.next() - } + if nu_utils::ctrl_c::was_pressed(&self.ctrlc) { + None } else { self.stream.next() } diff --git a/crates/nu-utils/src/ctrl_c.rs b/crates/nu-utils/src/ctrl_c.rs new file mode 100644 index 0000000000..72719139ad --- /dev/null +++ b/crates/nu-utils/src/ctrl_c.rs @@ -0,0 +1,13 @@ +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, +}; + +/// Returns true if Nu has received a SIGINT signal / ctrl+c event +pub fn was_pressed(ctrlc: &Option>) -> bool { + if let Some(ctrlc) = ctrlc { + ctrlc.load(Ordering::SeqCst) + } else { + false + } +} diff --git a/crates/nu-utils/src/lib.rs b/crates/nu-utils/src/lib.rs index e3215de21a..e51852d17a 100644 --- a/crates/nu-utils/src/lib.rs +++ b/crates/nu-utils/src/lib.rs @@ -1,7 +1,9 @@ +pub mod ctrl_c; mod deansi; pub mod locale; pub mod utils; +pub use ctrl_c::was_pressed; pub use locale::get_system_locale; pub use utils::{ enable_vt_processing, get_default_config, get_default_env, get_ls_colors,