mirror of
https://github.com/nushell/nushell.git
synced 2025-05-29 22:29:06 +02:00
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_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
use nu_source::Tagged;
|
use nu_source::Tagged;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
const NAME: &str = "du";
|
const NAME: &str = "du";
|
||||||
const GLOB_PARAMS: MatchOptions = MatchOptions {
|
const GLOB_PARAMS: MatchOptions = MatchOptions {
|
||||||
@ -92,6 +93,7 @@ fn du(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, She
|
|||||||
let registry = registry.clone();
|
let registry = registry.clone();
|
||||||
let tag = args.call_info.name_tag.clone();
|
let tag = args.call_info.name_tag.clone();
|
||||||
let ctrl_c = args.ctrl_c.clone();
|
let ctrl_c = args.ctrl_c.clone();
|
||||||
|
let ctrl_c_copy = ctrl_c.clone();
|
||||||
|
|
||||||
let stream = async_stream! {
|
let stream = async_stream! {
|
||||||
let (args, mut input): (DuArgs, _) = args.process(®istry).await?;
|
let (args, mut input): (DuArgs, _) = args.process(®istry).await?;
|
||||||
@ -136,13 +138,14 @@ fn du(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, She
|
|||||||
all,
|
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 {
|
while let Some(path) = inp.next().await {
|
||||||
match path {
|
match path {
|
||||||
Ok(p) => {
|
Ok(p) => {
|
||||||
if p.is_dir() {
|
if p.is_dir() {
|
||||||
yield Ok(ReturnSuccess::Value(
|
yield Ok(ReturnSuccess::Value(
|
||||||
DirInfo::new(p, ¶ms, max_depth).into(),
|
DirInfo::new(p, ¶ms, max_depth, ctrl_c.clone()).into(),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
for v in FileInfo::new(p, deref, tag.clone()).into_iter() {
|
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 {
|
pub struct DirBuilder {
|
||||||
@ -227,7 +230,12 @@ impl FileInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DirInfo {
|
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 path = path.into();
|
||||||
|
|
||||||
let mut s = Self {
|
let mut s = Self {
|
||||||
@ -243,9 +251,15 @@ impl DirInfo {
|
|||||||
match std::fs::read_dir(&s.path) {
|
match std::fs::read_dir(&s.path) {
|
||||||
Ok(d) => {
|
Ok(d) => {
|
||||||
for f in d {
|
for f in d {
|
||||||
|
if ctrl_c.load(Ordering::SeqCst) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
match f {
|
match f {
|
||||||
Ok(i) => match i.file_type() {
|
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),
|
Ok(_t) => s = s.add_file(i.path(), ¶ms),
|
||||||
Err(e) => s = s.add_error(e.into()),
|
Err(e) => s = s.add_error(e.into()),
|
||||||
},
|
},
|
||||||
@ -263,6 +277,7 @@ impl DirInfo {
|
|||||||
path: impl Into<PathBuf>,
|
path: impl Into<PathBuf>,
|
||||||
mut depth: Option<u64>,
|
mut depth: Option<u64>,
|
||||||
params: &DirBuilder,
|
params: &DirBuilder,
|
||||||
|
ctrl_c: Arc<AtomicBool>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
if let Some(current) = depth {
|
if let Some(current) = depth {
|
||||||
if let Some(new) = current.checked_sub(1) {
|
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.size += d.size;
|
||||||
self.blocks += d.blocks;
|
self.blocks += d.blocks;
|
||||||
self.dirs.push(d);
|
self.dirs.push(d);
|
||||||
|
@ -32,6 +32,7 @@ fn get_file_type(md: &std::fs::Metadata) -> &str {
|
|||||||
file_type
|
file_type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub(crate) fn dir_entry_dict(
|
pub(crate) fn dir_entry_dict(
|
||||||
filename: &std::path::Path,
|
filename: &std::path::Path,
|
||||||
metadata: Option<&std::fs::Metadata>,
|
metadata: Option<&std::fs::Metadata>,
|
||||||
@ -40,6 +41,7 @@ pub(crate) fn dir_entry_dict(
|
|||||||
short_name: bool,
|
short_name: bool,
|
||||||
with_symlink_targets: bool,
|
with_symlink_targets: bool,
|
||||||
du: bool,
|
du: bool,
|
||||||
|
ctrl_c: Arc<AtomicBool>,
|
||||||
) -> Result<Value, ShellError> {
|
) -> Result<Value, ShellError> {
|
||||||
let tag = tag.into();
|
let tag = tag.into();
|
||||||
let mut dict = TaggedDictBuilder::new(&tag);
|
let mut dict = TaggedDictBuilder::new(&tag);
|
||||||
@ -140,7 +142,7 @@ pub(crate) fn dir_entry_dict(
|
|||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
DirInfo::new(filename, ¶ms, None).get_size()
|
DirInfo::new(filename, ¶ms, None, ctrl_c).get_size()
|
||||||
} else {
|
} else {
|
||||||
md.len()
|
md.len()
|
||||||
};
|
};
|
||||||
|
@ -112,6 +112,7 @@ impl Shell for FilesystemShell {
|
|||||||
name_tag: Tag,
|
name_tag: Tag,
|
||||||
ctrl_c: Arc<AtomicBool>,
|
ctrl_c: Arc<AtomicBool>,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
|
let ctrl_c_copy = ctrl_c.clone();
|
||||||
let (path, p_tag) = match path {
|
let (path, p_tag) = match path {
|
||||||
Some(p) => {
|
Some(p) => {
|
||||||
let p_tag = p.tag;
|
let p_tag = p.tag;
|
||||||
@ -171,6 +172,7 @@ impl Shell for FilesystemShell {
|
|||||||
short_names,
|
short_names,
|
||||||
with_symlink_targets,
|
with_symlink_targets,
|
||||||
du,
|
du,
|
||||||
|
ctrl_c.clone()
|
||||||
)
|
)
|
||||||
.map(|entry| ReturnSuccess::Value(entry.into()))?;
|
.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> {
|
fn cd(&self, args: CdArgs, name: Tag) -> Result<OutputStream, ShellError> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user