nu_command/experimental/
job_kill.rs

1use nu_engine::command_prelude::*;
2use nu_protocol::JobId;
3
4#[derive(Clone)]
5pub struct JobKill;
6
7impl Command for JobKill {
8    fn name(&self) -> &str {
9        "job kill"
10    }
11
12    fn description(&self) -> &str {
13        "Kill a background job."
14    }
15
16    fn signature(&self) -> nu_protocol::Signature {
17        Signature::build("job kill")
18            .category(Category::Experimental)
19            .required("id", SyntaxShape::Int, "The id of the job to kill.")
20            .input_output_types(vec![(Type::Nothing, Type::Nothing)])
21            .allow_variants_without_examples(true)
22    }
23
24    fn search_terms(&self) -> Vec<&str> {
25        vec!["halt", "stop", "end", "close"]
26    }
27
28    fn run(
29        &self,
30        engine_state: &EngineState,
31        stack: &mut Stack,
32        call: &Call,
33        _input: PipelineData,
34    ) -> Result<PipelineData, ShellError> {
35        let head = call.head;
36
37        let id_arg: Spanned<usize> = call.req(engine_state, stack, 0)?;
38        let id = JobId::new(id_arg.item);
39
40        let mut jobs = engine_state.jobs.lock().expect("jobs lock is poisoned!");
41
42        if jobs.lookup(id).is_none() {
43            return Err(JobError::NotFound { span: head, id }.into());
44        }
45
46        jobs.kill_and_remove(id).map_err(|err| {
47            ShellError::Io(IoError::new_internal(
48                err,
49                "Failed to kill the requested job",
50                nu_protocol::location!(),
51            ))
52        })?;
53
54        Ok(Value::nothing(head).into_pipeline_data())
55    }
56
57    fn examples(&self) -> Vec<Example<'_>> {
58        vec![Example {
59            example: "let id = job spawn { sleep 10sec }; job kill $id",
60            description: "Kill a newly spawned job",
61            result: None,
62        }]
63    }
64}