Skip to main content

nu_command/shells/
exit.rs

1use nu_engine::{
2    command_prelude::*,
3    exit::{cleanup, cleanup_exit},
4};
5
6#[derive(Clone)]
7pub struct Exit;
8
9impl Command for Exit {
10    fn name(&self) -> &str {
11        "exit"
12    }
13
14    fn signature(&self) -> Signature {
15        Signature::build("exit")
16            .input_output_types(vec![(Type::Nothing, Type::Nothing)])
17            .optional(
18                "exit_code",
19                SyntaxShape::Int,
20                "Exit code to return immediately with.",
21            )
22            .switch("abort", "Exit by abort.", None)
23            .category(Category::Shells)
24    }
25
26    fn description(&self) -> &str {
27        "Exit Nu."
28    }
29
30    fn search_terms(&self) -> Vec<&str> {
31        vec!["quit", "close", "exit_code", "error_code", "logout"]
32    }
33
34    fn run(
35        &self,
36        engine_state: &EngineState,
37        stack: &mut Stack,
38        call: &Call,
39        _input: PipelineData,
40    ) -> Result<PipelineData, ShellError> {
41        let exit_code: Option<i64> = call.opt(engine_state, stack, 0)?;
42
43        let abort = call.has_flag(engine_state, stack, "abort")?;
44        let exit_code = exit_code.map_or(0, |it| it as i32);
45
46        if abort {
47            cleanup_exit((), engine_state, exit_code);
48            Ok(Value::nothing(call.head).into_pipeline_data())
49        } else if cleanup((), engine_state).is_some() {
50            Ok(Value::nothing(call.head).into_pipeline_data())
51        } else {
52            Err(ShellError::Exit { code: exit_code })
53        }
54    }
55
56    fn examples(&self) -> Vec<Example<'_>> {
57        vec![Example {
58            description: "Exit the current shell",
59            example: "exit",
60            result: None,
61        }]
62    }
63}