feat: Implement the prompt module for jobs (#85)

This commit is contained in:
John Letey 2019-08-12 18:42:33 +01:00 committed by Matan Kushner
parent 3f6fe50adb
commit 82cf484ced
9 changed files with 161 additions and 8 deletions

View File

@ -18,7 +18,7 @@
<h1></h1> <h1></h1>
Starship is the minimal, blazing fast, and extremely customizable prompt for any shell!<br> Starship is the minimal, blazing fast, and extremely customizable prompt for any shell!<br>
The prompt shows information need while you're working, while staying sleek and out of the way. The prompt shows information you need while you're working, while staying sleek and out of the way.
<p align="center"> <p align="center">
<img alt="Starship with Hyper and One Dark" src="https://raw.githubusercontent.com/starship/starship/master/media/demo.gif"> <img alt="Starship with Hyper and One Dark" src="https://raw.githubusercontent.com/starship/starship/master/media/demo.gif">
@ -46,7 +46,7 @@ The prompt shows information need while you're working, while staying sleek and
- `»` — renamed files - `»` — renamed files
- `✘` — deleted files - `✘` — deleted files
- Execution time of the last command if it exceeds the set threshold. - Execution time of the last command if it exceeds the set threshold.
- [PLANNED #80](https://github.com/starship/starship/issues/80) Indicator for jobs in the background (`✦`). - Indicator for jobs in the background (`✦`).
## 🚀 Installation ## 🚀 Installation

View File

@ -250,6 +250,29 @@ The module will be shown if any of the following conditions are met:
symbol = "🏎💨 " symbol = "🏎💨 "
``` ```
## Jobs
The `jobs` module shows the current number of jobs running.
The module will be shown only if there are background jobs running.
The module will show the number of jobs running if there is more than 1 job, or
more than the `threshold` config value, if it exists.
### Options
| Variable | Default | Description |
| ----------- | ------- | -------------------------------- |
| `threshold` | `1` | Show number of jobs if execeded. |
| `disabled` | `false` | Disables the `jobs` module. |
### Example
```toml
# ~/.config/starship.toml
[jobs]
threshold = 4
```
## Line Break ## Line Break
The `line_break` module separates the prompt into two lines. The `line_break` module separates the prompt into two lines.

View File

@ -58,7 +58,7 @@ https://github.com/starship/starship/issues/124
const BASH_INIT: &str = r##" const BASH_INIT: &str = r##"
starship_precmd() { starship_precmd() {
PS1="$(starship prompt --status=$?)"; PS1="$(starship prompt --status=$? --jobs=$(jobs -p | wc -l))";
}; };
PROMPT_COMMAND=starship_precmd; PROMPT_COMMAND=starship_precmd;
"##; "##;
@ -83,10 +83,10 @@ starship_precmd() {
if [[ $STARSHIP_START_TIME ]]; then if [[ $STARSHIP_START_TIME ]]; then
STARSHIP_END_TIME="$(date +%s)"; STARSHIP_END_TIME="$(date +%s)";
STARSHIP_DURATION=$((STARSHIP_END_TIME - STARSHIP_START_TIME)); STARSHIP_DURATION=$((STARSHIP_END_TIME - STARSHIP_START_TIME));
PROMPT="$(starship prompt --status=$STATUS --cmd-duration=$STARSHIP_DURATION)"; PROMPT="$(starship prompt --status=$STATUS --cmd-duration=$STARSHIP_DURATION --jobs=$(jobs | wc -l))";
unset STARSHIP_START_TIME; unset STARSHIP_START_TIME;
else else
PROMPT="$(starship prompt --status=$STATUS)"; PROMPT="$(starship prompt --status=$STATUS --jobs=$(jobs | wc -l))";
fi fi
}; };
starship_preexec(){ starship_preexec(){
@ -108,6 +108,6 @@ function fish_prompt;
set -l exit_code $status; set -l exit_code $status;
set -l CMD_DURATION "$CMD_DURATION$cmd_duration"; set -l CMD_DURATION "$CMD_DURATION$cmd_duration";
set -l starship_duration (math --scale=0 "$CMD_DURATION / 1000"); set -l starship_duration (math --scale=0 "$CMD_DURATION / 1000");
starship prompt --status=$exit_code --cmd-duration=$starship_duration; starship prompt --status=$exit_code --cmd-duration=$starship_duration --jobs=(count (jobs -p));
end; end;
"##; "##;

View File

@ -43,6 +43,13 @@ fn main() {
.help("The execution duration of the last command, in seconds") .help("The execution duration of the last command, in seconds")
.takes_value(true); .takes_value(true);
let jobs_arg = Arg::with_name("jobs")
.short("j")
.long("jobs")
.value_name("JOBS")
.help("The number of currently running jobs")
.takes_value(true);
let matches = App::new("starship") let matches = App::new("starship")
.about("The cross-shell prompt for astronauts. ☄🌌️") .about("The cross-shell prompt for astronauts. ☄🌌️")
// pull the version number from Cargo.toml // pull the version number from Cargo.toml
@ -61,7 +68,8 @@ fn main() {
.about("Prints the full starship prompt") .about("Prints the full starship prompt")
.arg(&status_code_arg) .arg(&status_code_arg)
.arg(&path_arg) .arg(&path_arg)
.arg(&cmd_duration_arg), .arg(&cmd_duration_arg)
.arg(&jobs_arg),
) )
.subcommand( .subcommand(
SubCommand::with_name("module") SubCommand::with_name("module")
@ -73,7 +81,8 @@ fn main() {
) )
.arg(&status_code_arg) .arg(&status_code_arg)
.arg(&path_arg) .arg(&path_arg)
.arg(&cmd_duration_arg), .arg(&cmd_duration_arg)
.arg(&jobs_arg),
) )
.get_matches(); .get_matches();

32
src/modules/jobs.rs Normal file
View File

@ -0,0 +1,32 @@
use ansi_term::Color;
use super::{Context, Module};
/// Creates a segment to show if there are any active jobs running
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let mut module = context.new_module("jobs")?;
let threshold = module.config_value_i64("threshold").unwrap_or(1);
const JOB_CHAR: &str = "";
let module_color = Color::Blue.bold();
module.set_style(module_color);
let arguments = &context.arguments;
let num_of_jobs = arguments
.value_of("jobs")
.unwrap_or("0")
.parse::<i64>()
.ok()?;
if num_of_jobs == 0 {
return None;
}
module.new_segment("symbol", JOB_CHAR);
if num_of_jobs > threshold {
module.new_segment("number", &num_of_jobs.to_string());
}
module.get_prefix().set_value("");
Some(module)
}

View File

@ -5,6 +5,7 @@ mod directory;
mod git_branch; mod git_branch;
mod git_status; mod git_status;
mod golang; mod golang;
mod jobs;
mod line_break; mod line_break;
mod nodejs; mod nodejs;
mod package; mod package;
@ -30,6 +31,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option<Module<'a>> {
"username" => username::module(context), "username" => username::module(context),
"battery" => battery::module(context), "battery" => battery::module(context),
"cmd_duration" => cmd_duration::module(context), "cmd_duration" => cmd_duration::module(context),
"jobs" => jobs::module(context),
_ => panic!("Unknown module: {}", module), _ => panic!("Unknown module: {}", module),
} }

View File

@ -19,6 +19,7 @@ const PROMPT_ORDER: &[&str] = &[
"go", "go",
"cmd_duration", "cmd_duration",
"line_break", "line_break",
"jobs",
"battery", "battery",
"character", "character",
]; ];

85
tests/testsuite/jobs.rs Normal file
View File

@ -0,0 +1,85 @@
use ansi_term::Color;
use std::fs;
use std::io;
use std::path::Path;
use tempfile::TempDir;
use crate::common::{self, TestCommand};
#[test]
fn config_blank_job_0() -> io::Result<()> {
let output = common::render_module("jobs").arg("--jobs=0").output()?;
let actual = String::from_utf8(output.stdout).unwrap();
let expected = "";
assert_eq!(expected, actual);
Ok(())
}
#[test]
fn config_blank_job_1() -> io::Result<()> {
let output = common::render_module("jobs").arg("--jobs=1").output()?;
let actual = String::from_utf8(output.stdout).unwrap();
let expected = format!("{} ", Color::Blue.bold().paint(""));
assert_eq!(expected, actual);
Ok(())
}
#[test]
fn config_blank_job_2() -> io::Result<()> {
let output = common::render_module("jobs").arg("--jobs=2").output()?;
let actual = String::from_utf8(output.stdout).unwrap();
let expected = format!("{} ", Color::Blue.bold().paint("✦2"));
assert_eq!(expected, actual);
Ok(())
}
#[test]
fn config_2_job_2() -> io::Result<()> {
let output = common::render_module("jobs")
.use_config(toml::toml! {
[jobs]
threshold = 2
})
.arg("--jobs=2")
.output()?;
let actual = String::from_utf8(output.stdout).unwrap();
let expected = format!("{} ", Color::Blue.bold().paint(""));
assert_eq!(expected, actual);
Ok(())
}
#[test]
fn config_2_job_3() -> io::Result<()> {
let output = common::render_module("jobs")
.use_config(toml::toml! {
[jobs]
threshold = 2
})
.arg("--jobs=3")
.output()?;
let actual = String::from_utf8(output.stdout).unwrap();
let expected = format!("{} ", Color::Blue.bold().paint("✦3"));
assert_eq!(expected, actual);
Ok(())
}
#[test]
fn config_disabled() -> io::Result<()> {
let output = common::render_module("jobs")
.use_config(toml::toml! {
[jobs]
disabled = true
})
.arg("--jobs=1")
.output()?;
let actual = String::from_utf8(output.stdout).unwrap();
let expected = "";
assert_eq!(expected, actual);
Ok(())
}

View File

@ -4,6 +4,7 @@ mod common;
mod configuration; mod configuration;
mod directory; mod directory;
mod golang; mod golang;
mod jobs;
mod line_break; mod line_break;
mod nodejs; mod nodejs;
mod python; mod python;