nu_command/experimental/
job_kill.rs1use 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}