feat: Add ability for command duration in milliseconds (#380)

This commit is contained in:
Tom Hotston 2019-09-24 20:03:10 +01:00 committed by Kevin Song
parent c9878cab69
commit c5e971aef8
6 changed files with 51 additions and 35 deletions

View file

@ -212,7 +212,7 @@ use_symbol_for_status = true
## Command Duration ## Command Duration
The `cmd_duration` module shows how long the last command took to execute. The `cmd_duration` module shows how long the last command took to execute.
The module will be shown only if the command took longer than two seconds, or The module will be shown only if the command took longer than 2000 milliseconds (2 seconds), or
the `min_time` config value, if it exists. the `min_time` config value, if it exists.
::: warning Do not hook the DEBUG trap in Bash ::: warning Do not hook the DEBUG trap in Bash
@ -227,11 +227,11 @@ running `eval $(starship init $0)`, and then proceed as normal.
### Options ### Options
| Variable | Default | Description | | Variable | Default | Description |
| ---------- | --------------- | ----------------------------------- | | ---------- | --------------- | ----------------------------------------------------- |
| `min_time` | `2` | Shortest duration to show time for. | | `min_time` | `2000` | Shortest duration to show time for (in milliseconds). |
| `style` | `"bold yellow"` | The style for the module. | | `style` | `"bold yellow"` | The style for the module. |
| `disabled` | `false` | Disables the `cmd_duration` module. | | `disabled` | `false` | Disables the `cmd_duration` module. |
### Example ### Example
@ -239,7 +239,7 @@ running `eval $(starship init $0)`, and then proceed as normal.
# ~/.config/starship.toml # ~/.config/starship.toml
[cmd_duration] [cmd_duration]
min_time = 4 min_time = 4000
``` ```
## Directory ## Directory

View file

@ -17,7 +17,7 @@ starship_preexec() {
# Avoid restarting the timer for commands in the same pipeline # Avoid restarting the timer for commands in the same pipeline
if [ "$PREEXEC_READY" = "true" ]; then if [ "$PREEXEC_READY" = "true" ]; then
PREEXEC_READY=false PREEXEC_READY=false
STARSHIP_START_TIME=$(date +%s) STARSHIP_START_TIME=$(date +%s%0N)
fi fi
} }
@ -31,7 +31,7 @@ starship_precmd() {
# Prepare the timer data, if needed. # Prepare the timer data, if needed.
if [[ $STARSHIP_START_TIME ]]; then if [[ $STARSHIP_START_TIME ]]; then
STARSHIP_END_TIME=$(date +%s) STARSHIP_END_TIME=$(date +%s%0N)
STARSHIP_DURATION=$((STARSHIP_END_TIME - STARSHIP_START_TIME)) STARSHIP_DURATION=$((STARSHIP_END_TIME - STARSHIP_START_TIME))
PS1="$(::STARSHIP:: prompt --status=$STATUS --jobs="$(jobs -p | wc -l)" --cmd-duration=$STARSHIP_DURATION)" PS1="$(::STARSHIP:: prompt --status=$STATUS --jobs="$(jobs -p | wc -l)" --cmd-duration=$STARSHIP_DURATION)"
unset STARSHIP_START_TIME unset STARSHIP_START_TIME
@ -65,5 +65,5 @@ else
fi fi
# Set up the start time and STARSHIP_SHELL, which controls shell-specific sequences # Set up the start time and STARSHIP_SHELL, which controls shell-specific sequences
STARSHIP_START_TIME=$(date +%s) STARSHIP_START_TIME=$(date +%s%0N)
export STARSHIP_SHELL="bash" export STARSHIP_SHELL="bash"

View file

@ -8,8 +8,8 @@ function fish_prompt
set -l exit_code $status set -l exit_code $status
# Account for changes in variable name between v2.7 and v3.0 # Account for changes in variable name between v2.7 and v3.0
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_ns {$CMD_DURATION}000000
::STARSHIP:: prompt --status=$exit_code --keymap=$keymap --cmd-duration=$starship_duration --jobs=(count (jobs -p)) ::STARSHIP:: prompt --status=$exit_code --keymap=$keymap --cmd-duration=$starship_duration_ns --jobs=(count (jobs -p))
end end
function fish_mode_prompt; end function fish_mode_prompt; end
export STARSHIP_SHELL="fish" export STARSHIP_SHELL="fish"

View file

@ -19,7 +19,7 @@ starship_precmd() {
NUM_JOBS=$#jobstates NUM_JOBS=$#jobstates
# Compute cmd_duration, if we have a time to consume # Compute cmd_duration, if we have a time to consume
if [[ ! -z "${STARSHIP_START_TIME+1}" ]]; then if [[ ! -z "${STARSHIP_START_TIME+1}" ]]; then
STARSHIP_END_TIME="$(date +%s)" STARSHIP_END_TIME="$(date +%s%0N)"
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 --jobs="$NUM_JOBS")" PROMPT="$(::STARSHIP:: prompt --status=$STATUS --cmd-duration=$STARSHIP_DURATION --jobs="$NUM_JOBS")"
unset STARSHIP_START_TIME unset STARSHIP_START_TIME
@ -28,7 +28,7 @@ starship_precmd() {
fi fi
} }
starship_preexec(){ starship_preexec(){
STARSHIP_START_TIME="$(date +%s)" STARSHIP_START_TIME="$(date +%s%0N)"
} }
# If precmd/preexec arrays are not already set, set them. If we don't do this, # If precmd/preexec arrays are not already set, set them. If we don't do this,
@ -53,6 +53,6 @@ function zle-keymap-select
zle reset-prompt zle reset-prompt
} }
STARSHIP_START_TIME="$(date +%s)" STARSHIP_START_TIME="$(date +%s%0N)"
zle -N zle-keymap-select zle -N zle-keymap-select
export STARSHIP_SHELL="zsh" export STARSHIP_SHELL="zsh"

View file

@ -14,9 +14,10 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
.value_of("cmd_duration") .value_of("cmd_duration")
.unwrap_or("invalid_time") .unwrap_or("invalid_time")
.parse::<u64>() .parse::<u64>()
.ok()?; .ok()?
/ 1_000_000;
let signed_config_min = module.config_value_i64("min_time").unwrap_or(2); let signed_config_min = module.config_value_i64("min_time").unwrap_or(2000);
/* TODO: Once error handling is implemented, warn the user if their config /* TODO: Once error handling is implemented, warn the user if their config
min time is nonsensical */ min time is nonsensical */
@ -31,28 +32,39 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let config_min = signed_config_min as u64; let config_min = signed_config_min as u64;
let module_color = match elapsed { let module_color = match elapsed {
time if time < config_min => return None, time if time < config_min => module
.config_value_style("style")
.unwrap_or_else(|| Color::RGB(80, 80, 80).bold()),
_ => module _ => module
.config_value_style("style") .config_value_style("style")
.unwrap_or_else(|| Color::Yellow.bold()), .unwrap_or_else(|| Color::Yellow.bold()),
}; };
module.set_style(module_color); module.set_style(module_color);
module.new_segment("cmd_duration", &format!("took {}", render_time(elapsed))); module.new_segment(
"cmd_duration",
&format!("took {}", render_time(elapsed, config_min)),
);
module.get_prefix().set_value(""); module.get_prefix().set_value("");
Some(module) Some(module)
} }
// Render the time into a nice human-readable string // Render the time into a nice human-readable string
fn render_time(raw_seconds: u64) -> String { fn render_time(raw_milliseconds: u64, config_min: u64) -> String {
// Calculate a simple breakdown into days/hours/minutes/seconds // Calculate a simple breakdown into days/hours/minutes/seconds
let (mut milliseconds, raw_seconds) = (raw_milliseconds % 1000, raw_milliseconds / 1000);
let (seconds, raw_minutes) = (raw_seconds % 60, raw_seconds / 60); let (seconds, raw_minutes) = (raw_seconds % 60, raw_seconds / 60);
let (minutes, raw_hours) = (raw_minutes % 60, raw_minutes / 60); let (minutes, raw_hours) = (raw_minutes % 60, raw_minutes / 60);
let (hours, days) = (raw_hours % 24, raw_hours / 24); let (hours, days) = (raw_hours % 24, raw_hours / 24);
let components = [days, hours, minutes, seconds]; // Do not display milliseconds if command duration is less than config_min
let suffixes = ["d", "h", "m", "s"]; if raw_milliseconds > config_min {
milliseconds = 0;
}
let components = [days, hours, minutes, seconds, milliseconds];
let suffixes = ["d", "h", "m", "s", "ms"];
let rendered_components: Vec<String> = components let rendered_components: Vec<String> = components
.iter() .iter()
@ -74,20 +86,24 @@ fn render_time_component((component, suffix): (&u64, &&str)) -> String {
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn test_100ms() {
assert_eq!(render_time(100 as u64, 2000), "100ms")
}
#[test] #[test]
fn test_10s() { fn test_10s() {
assert_eq!(render_time(10 as u64), "10s") assert_eq!(render_time(10 * 1000 as u64, 2000), "10s")
} }
#[test] #[test]
fn test_90s() { fn test_90s() {
assert_eq!(render_time(90 as u64), "1m30s") assert_eq!(render_time(90 * 1_000 as u64, 2000), "1m30s")
} }
#[test] #[test]
fn test_10110s() { fn test_10110s() {
assert_eq!(render_time(10110 as u64), "2h48m30s") assert_eq!(render_time(10110 * 1_000 as u64, 2000), "2h48m30s")
} }
#[test] #[test]
fn test_1d() { fn test_1d() {
assert_eq!(render_time(86400 as u64), "1d") assert_eq!(render_time(86400 * 1_000 as u64, 2000), "1d")
} }
} }

View file

@ -6,11 +6,11 @@ use crate::common::{self, TestCommand};
#[test] #[test]
fn config_blank_duration_1s() -> io::Result<()> { fn config_blank_duration_1s() -> io::Result<()> {
let output = common::render_module("cmd_duration") let output = common::render_module("cmd_duration")
.arg("--cmd-duration=1") .arg("--cmd-duration=1000000000")
.output()?; .output()?;
let actual = String::from_utf8(output.stdout).unwrap(); let actual = String::from_utf8(output.stdout).unwrap();
let expected = ""; let expected = format!("{} ", Color::RGB(80, 80, 80).bold().paint("took 1s"));
assert_eq!(expected, actual); assert_eq!(expected, actual);
Ok(()) Ok(())
} }
@ -18,7 +18,7 @@ fn config_blank_duration_1s() -> io::Result<()> {
#[test] #[test]
fn config_blank_duration_5s() -> io::Result<()> { fn config_blank_duration_5s() -> io::Result<()> {
let output = common::render_module("cmd_duration") let output = common::render_module("cmd_duration")
.arg("--cmd-duration=5") .arg("--cmd-duration=5000000000")
.output()?; .output()?;
let actual = String::from_utf8(output.stdout).unwrap(); let actual = String::from_utf8(output.stdout).unwrap();
@ -32,13 +32,13 @@ fn config_5s_duration_3s() -> io::Result<()> {
let output = common::render_module("cmd_duration") let output = common::render_module("cmd_duration")
.use_config(toml::toml! { .use_config(toml::toml! {
[cmd_duration] [cmd_duration]
min_time = 5 min_time = 5000
}) })
.arg("--cmd-duration=3") .arg("--cmd-duration=3000000000")
.output()?; .output()?;
let actual = String::from_utf8(output.stdout).unwrap(); let actual = String::from_utf8(output.stdout).unwrap();
let expected = ""; let expected = format!("{} ", Color::RGB(80, 80, 80).bold().paint("took 3s"));
assert_eq!(expected, actual); assert_eq!(expected, actual);
Ok(()) Ok(())
} }
@ -48,9 +48,9 @@ fn config_5s_duration_10s() -> io::Result<()> {
let output = common::render_module("cmd_duration") let output = common::render_module("cmd_duration")
.use_config(toml::toml! { .use_config(toml::toml! {
[cmd_duration] [cmd_duration]
min_time = 5 min_time = 5000
}) })
.arg("--cmd-duration=10") .arg("--cmd-duration=10000000000")
.output()?; .output()?;
let actual = String::from_utf8(output.stdout).unwrap(); let actual = String::from_utf8(output.stdout).unwrap();