forked from extern/nushell
Implement ctrl+c for the du command (#1901)
* Implement ctrl+c for the du command * Ignore the "too many arguments" Clippy warning
This commit is contained in:
parent
fa812849b8
commit
49b0592e3c
@ -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<OutputStream, She
|
||||
let registry = registry.clone();
|
||||
let tag = args.call_info.name_tag.clone();
|
||||
let ctrl_c = args.ctrl_c.clone();
|
||||
let ctrl_c_copy = ctrl_c.clone();
|
||||
|
||||
let stream = async_stream! {
|
||||
let (args, mut input): (DuArgs, _) = args.process(®istry).await?;
|
||||
@ -136,13 +138,14 @@ fn du(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, She
|
||||
all,
|
||||
};
|
||||
|
||||
let mut inp = futures::stream::iter(paths).interruptible(ctrl_c);
|
||||
let mut inp = futures::stream::iter(paths).interruptible(ctrl_c.clone());
|
||||
|
||||
while let Some(path) = inp.next().await {
|
||||
match path {
|
||||
Ok(p) => {
|
||||
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<OutputStream, She
|
||||
}
|
||||
};
|
||||
|
||||
Ok(stream.to_output_stream())
|
||||
Ok(stream.interruptible(ctrl_c_copy).to_output_stream())
|
||||
}
|
||||
|
||||
pub struct DirBuilder {
|
||||
@ -227,7 +230,12 @@ impl FileInfo {
|
||||
}
|
||||
|
||||
impl DirInfo {
|
||||
pub fn new(path: impl Into<PathBuf>, params: &DirBuilder, depth: Option<u64>) -> Self {
|
||||
pub fn new(
|
||||
path: impl Into<PathBuf>,
|
||||
params: &DirBuilder,
|
||||
depth: Option<u64>,
|
||||
ctrl_c: Arc<AtomicBool>,
|
||||
) -> 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<PathBuf>,
|
||||
mut depth: Option<u64>,
|
||||
params: &DirBuilder,
|
||||
ctrl_c: Arc<AtomicBool>,
|
||||
) -> 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);
|
||||
|
@ -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<AtomicBool>,
|
||||
) -> Result<Value, ShellError> {
|
||||
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()
|
||||
};
|
||||
|
@ -112,6 +112,7 @@ impl Shell for FilesystemShell {
|
||||
name_tag: Tag,
|
||||
ctrl_c: Arc<AtomicBool>,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
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<OutputStream, ShellError> {
|
||||
|
Loading…
Reference in New Issue
Block a user