diff --git a/crates/nu-cli/src/commands/du.rs b/crates/nu-cli/src/commands/du.rs index 3b3126a26a..767360f6b8 100644 --- a/crates/nu-cli/src/commands/du.rs +++ b/crates/nu-cli/src/commands/du.rs @@ -7,6 +7,7 @@ use nu_errors::ShellError; use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value}; use nu_source::Tagged; use std::path::PathBuf; +use std::sync::atomic::Ordering; const NAME: &str = "du"; const GLOB_PARAMS: MatchOptions = MatchOptions { @@ -92,6 +93,7 @@ fn du(args: CommandArgs, registry: &CommandRegistry) -> Result Result { if p.is_dir() { yield Ok(ReturnSuccess::Value( - DirInfo::new(p, ¶ms, max_depth).into(), + DirInfo::new(p, ¶ms, max_depth, ctrl_c.clone()).into(), )) } else { for v in FileInfo::new(p, deref, tag.clone()).into_iter() { @@ -155,7 +158,7 @@ fn du(args: CommandArgs, registry: &CommandRegistry) -> Result, params: &DirBuilder, depth: Option) -> Self { + pub fn new( + path: impl Into, + params: &DirBuilder, + depth: Option, + ctrl_c: Arc, + ) -> Self { let path = path.into(); let mut s = Self { @@ -243,9 +251,15 @@ impl DirInfo { match std::fs::read_dir(&s.path) { Ok(d) => { for f in d { + if ctrl_c.load(Ordering::SeqCst) { + break; + } + match f { Ok(i) => match i.file_type() { - Ok(t) if t.is_dir() => s = s.add_dir(i.path(), depth, ¶ms), + Ok(t) if t.is_dir() => { + s = s.add_dir(i.path(), depth, ¶ms, ctrl_c.clone()) + } Ok(_t) => s = s.add_file(i.path(), ¶ms), Err(e) => s = s.add_error(e.into()), }, @@ -263,6 +277,7 @@ impl DirInfo { path: impl Into, mut depth: Option, params: &DirBuilder, + ctrl_c: Arc, ) -> Self { if let Some(current) = depth { if let Some(new) = current.checked_sub(1) { @@ -272,7 +287,7 @@ impl DirInfo { } } - let d = DirInfo::new(path, ¶ms, depth); + let d = DirInfo::new(path, ¶ms, depth, ctrl_c); self.size += d.size; self.blocks += d.blocks; self.dirs.push(d); diff --git a/crates/nu-cli/src/data/files.rs b/crates/nu-cli/src/data/files.rs index 26cdbc597d..7d7c1b95e4 100644 --- a/crates/nu-cli/src/data/files.rs +++ b/crates/nu-cli/src/data/files.rs @@ -32,6 +32,7 @@ fn get_file_type(md: &std::fs::Metadata) -> &str { file_type } +#[allow(clippy::too_many_arguments)] pub(crate) fn dir_entry_dict( filename: &std::path::Path, metadata: Option<&std::fs::Metadata>, @@ -40,6 +41,7 @@ pub(crate) fn dir_entry_dict( short_name: bool, with_symlink_targets: bool, du: bool, + ctrl_c: Arc, ) -> Result { let tag = tag.into(); let mut dict = TaggedDictBuilder::new(&tag); @@ -140,7 +142,7 @@ pub(crate) fn dir_entry_dict( false, ); - DirInfo::new(filename, ¶ms, None).get_size() + DirInfo::new(filename, ¶ms, None, ctrl_c).get_size() } else { md.len() }; diff --git a/crates/nu-cli/src/shell/filesystem_shell.rs b/crates/nu-cli/src/shell/filesystem_shell.rs index 3aac323d3b..b37886532b 100644 --- a/crates/nu-cli/src/shell/filesystem_shell.rs +++ b/crates/nu-cli/src/shell/filesystem_shell.rs @@ -112,6 +112,7 @@ impl Shell for FilesystemShell { name_tag: Tag, ctrl_c: Arc, ) -> Result { + let ctrl_c_copy = ctrl_c.clone(); let (path, p_tag) = match path { Some(p) => { let p_tag = p.tag; @@ -171,6 +172,7 @@ impl Shell for FilesystemShell { short_names, with_symlink_targets, du, + ctrl_c.clone() ) .map(|entry| ReturnSuccess::Value(entry.into()))?; @@ -178,7 +180,7 @@ impl Shell for FilesystemShell { } }; - Ok(stream.interruptible(ctrl_c).to_output_stream()) + Ok(stream.interruptible(ctrl_c_copy).to_output_stream()) } fn cd(&self, args: CdArgs, name: Tag) -> Result {