mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 17:45:03 +02:00
Add and use new Signals
struct (#13314)
# Description This PR introduces a new `Signals` struct to replace our adhoc passing around of `ctrlc: Option<Arc<AtomicBool>>`. Doing so has a few benefits: - We can better enforce when/where resetting or triggering an interrupt is allowed. - Consolidates `nu_utils::ctrl_c::was_pressed` and other ad-hoc re-implementations into a single place: `Signals::check`. - This allows us to add other types of signals later if we want. E.g., exiting or suspension. - Similarly, we can more easily change the underlying implementation if we need to in the future. - Places that used to have a `ctrlc` of `None` now use `Signals::empty()`, so we can double check these usages for correctness in the future.
This commit is contained in:
@ -182,5 +182,5 @@ fn run_ps(
|
||||
|
||||
Ok(output
|
||||
.into_iter()
|
||||
.into_pipeline_data(span, engine_state.ctrlc.clone()))
|
||||
.into_pipeline_data(span, engine_state.signals().clone()))
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ fn registry_query(
|
||||
*registry_key_span,
|
||||
))
|
||||
}
|
||||
Ok(reg_values.into_pipeline_data(call_span, engine_state.ctrlc.clone()))
|
||||
Ok(reg_values.into_pipeline_data(call_span, engine_state.signals().clone()))
|
||||
} else {
|
||||
match registry_value {
|
||||
Some(value) => {
|
||||
|
@ -2,7 +2,7 @@ use nu_cmd_base::hook::eval_hook;
|
||||
use nu_engine::{command_prelude::*, env_to_strings, get_eval_expression};
|
||||
use nu_path::{dots::expand_ndots, expand_tilde};
|
||||
use nu_protocol::{
|
||||
ast::Expression, did_you_mean, process::ChildProcess, ByteStream, NuGlob, OutDest,
|
||||
ast::Expression, did_you_mean, process::ChildProcess, ByteStream, NuGlob, OutDest, Signals,
|
||||
};
|
||||
use nu_system::ForegroundChild;
|
||||
use nu_utils::IgnoreCaseExt;
|
||||
@ -13,7 +13,7 @@ use std::{
|
||||
io::Write,
|
||||
path::{Path, PathBuf},
|
||||
process::Stdio,
|
||||
sync::{atomic::AtomicBool, Arc},
|
||||
sync::Arc,
|
||||
thread,
|
||||
};
|
||||
|
||||
@ -221,7 +221,6 @@ pub fn eval_arguments_from_call(
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
) -> Result<Vec<Spanned<OsString>>, ShellError> {
|
||||
let ctrlc = &engine_state.ctrlc;
|
||||
let cwd = engine_state.cwd(Some(stack))?;
|
||||
let mut args: Vec<Spanned<OsString>> = vec![];
|
||||
for (expr, spread) in call.rest_iter(1) {
|
||||
@ -229,7 +228,7 @@ pub fn eval_arguments_from_call(
|
||||
match arg {
|
||||
// Expand globs passed to run-external
|
||||
Value::Glob { val, no_expand, .. } if !no_expand => args.extend(
|
||||
expand_glob(&val, &cwd, expr.span, ctrlc)?
|
||||
expand_glob(&val, &cwd, expr.span, engine_state.signals())?
|
||||
.into_iter()
|
||||
.map(|s| s.into_spanned(expr.span)),
|
||||
),
|
||||
@ -289,7 +288,7 @@ fn expand_glob(
|
||||
arg: &str,
|
||||
cwd: &Path,
|
||||
span: Span,
|
||||
interrupt: &Option<Arc<AtomicBool>>,
|
||||
signals: &Signals,
|
||||
) -> Result<Vec<OsString>, ShellError> {
|
||||
const GLOB_CHARS: &[char] = &['*', '?', '['];
|
||||
|
||||
@ -307,9 +306,7 @@ fn expand_glob(
|
||||
let mut result: Vec<OsString> = vec![];
|
||||
|
||||
for m in matches {
|
||||
if nu_utils::ctrl_c::was_pressed(interrupt) {
|
||||
return Err(ShellError::InterruptedByUser { span: Some(span) });
|
||||
}
|
||||
signals.check(span)?;
|
||||
if let Ok(arg) = m {
|
||||
let arg = resolve_globbed_path_to_cwd_relative(arg, prefix.as_ref(), cwd);
|
||||
result.push(arg.into());
|
||||
@ -611,30 +608,30 @@ mod test {
|
||||
|
||||
let cwd = dirs.test();
|
||||
|
||||
let actual = expand_glob("*.txt", cwd, Span::unknown(), &None).unwrap();
|
||||
let actual = expand_glob("*.txt", cwd, Span::unknown(), &Signals::empty()).unwrap();
|
||||
let expected = &["a.txt", "b.txt"];
|
||||
assert_eq!(actual, expected);
|
||||
|
||||
let actual = expand_glob("./*.txt", cwd, Span::unknown(), &None).unwrap();
|
||||
let actual = expand_glob("./*.txt", cwd, Span::unknown(), &Signals::empty()).unwrap();
|
||||
assert_eq!(actual, expected);
|
||||
|
||||
let actual = expand_glob("'*.txt'", cwd, Span::unknown(), &None).unwrap();
|
||||
let actual = expand_glob("'*.txt'", cwd, Span::unknown(), &Signals::empty()).unwrap();
|
||||
let expected = &["'*.txt'"];
|
||||
assert_eq!(actual, expected);
|
||||
|
||||
let actual = expand_glob(".", cwd, Span::unknown(), &None).unwrap();
|
||||
let actual = expand_glob(".", cwd, Span::unknown(), &Signals::empty()).unwrap();
|
||||
let expected = &["."];
|
||||
assert_eq!(actual, expected);
|
||||
|
||||
let actual = expand_glob("./a.txt", cwd, Span::unknown(), &None).unwrap();
|
||||
let actual = expand_glob("./a.txt", cwd, Span::unknown(), &Signals::empty()).unwrap();
|
||||
let expected = &["./a.txt"];
|
||||
assert_eq!(actual, expected);
|
||||
|
||||
let actual = expand_glob("[*.txt", cwd, Span::unknown(), &None).unwrap();
|
||||
let actual = expand_glob("[*.txt", cwd, Span::unknown(), &Signals::empty()).unwrap();
|
||||
let expected = &["[*.txt"];
|
||||
assert_eq!(actual, expected);
|
||||
|
||||
let actual = expand_glob("~/foo.txt", cwd, Span::unknown(), &None).unwrap();
|
||||
let actual = expand_glob("~/foo.txt", cwd, Span::unknown(), &Signals::empty()).unwrap();
|
||||
let home = dirs_next::home_dir().expect("failed to get home dir");
|
||||
let expected: Vec<OsString> = vec![home.join("foo.txt").into()];
|
||||
assert_eq!(actual, expected);
|
||||
@ -666,7 +663,7 @@ mod test {
|
||||
ByteStream::read(
|
||||
b"foo".as_slice(),
|
||||
Span::unknown(),
|
||||
None,
|
||||
Signals::empty(),
|
||||
ByteStreamType::Unknown,
|
||||
),
|
||||
None,
|
||||
|
@ -188,7 +188,6 @@ fn which(
|
||||
applications: call.rest(engine_state, stack, 0)?,
|
||||
all: call.has_flag(engine_state, stack, "all")?,
|
||||
};
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
||||
if which_args.applications.is_empty() {
|
||||
return Err(ShellError::MissingParameter {
|
||||
@ -214,7 +213,9 @@ fn which(
|
||||
output.extend(values);
|
||||
}
|
||||
|
||||
Ok(output.into_iter().into_pipeline_data(head, ctrlc))
|
||||
Ok(output
|
||||
.into_iter()
|
||||
.into_pipeline_data(head, engine_state.signals().clone()))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
Reference in New Issue
Block a user