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
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.
::: warning Do not hook the DEBUG trap in Bash
@ -227,11 +227,11 @@ running `eval $(starship init $0)`, and then proceed as normal.
### Options
| Variable | Default | Description |
| ---------- | --------------- | ----------------------------------- |
| `min_time` | `2` | Shortest duration to show time for. |
| `style` | `"bold yellow"` | The style for the module. |
| `disabled` | `false` | Disables the `cmd_duration` module. |
| Variable | Default | Description |
| ---------- | --------------- | ----------------------------------------------------- |
| `min_time` | `2000` | Shortest duration to show time for (in milliseconds). |
| `style` | `"bold yellow"` | The style for the module. |
| `disabled` | `false` | Disables the `cmd_duration` module. |
### Example
@ -239,7 +239,7 @@ running `eval $(starship init $0)`, and then proceed as normal.
# ~/.config/starship.toml
[cmd_duration]
min_time = 4
min_time = 4000
```
## Directory

View File

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

View File

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

View File

@ -19,7 +19,7 @@ starship_precmd() {
NUM_JOBS=$#jobstates
# Compute cmd_duration, if we have a time to consume
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))
PROMPT="$(::STARSHIP:: prompt --status=$STATUS --cmd-duration=$STARSHIP_DURATION --jobs="$NUM_JOBS")"
unset STARSHIP_START_TIME
@ -28,7 +28,7 @@ starship_precmd() {
fi
}
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,
@ -53,6 +53,6 @@ function zle-keymap-select
zle reset-prompt
}
STARSHIP_START_TIME="$(date +%s)"
STARSHIP_START_TIME="$(date +%s%0N)"
zle -N zle-keymap-select
export STARSHIP_SHELL="zsh"

View File

@ -14,9 +14,10 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
.value_of("cmd_duration")
.unwrap_or("invalid_time")
.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
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 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
.config_value_style("style")
.unwrap_or_else(|| Color::Yellow.bold()),
};
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("");
Some(module)
}
// 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
let (mut milliseconds, raw_seconds) = (raw_milliseconds % 1000, raw_milliseconds / 1000);
let (seconds, raw_minutes) = (raw_seconds % 60, raw_seconds / 60);
let (minutes, raw_hours) = (raw_minutes % 60, raw_minutes / 60);
let (hours, days) = (raw_hours % 24, raw_hours / 24);
let components = [days, hours, minutes, seconds];
let suffixes = ["d", "h", "m", "s"];
// Do not display milliseconds if command duration is less than config_min
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
.iter()
@ -74,20 +86,24 @@ fn render_time_component((component, suffix): (&u64, &&str)) -> String {
mod tests {
use super::*;
#[test]
fn test_100ms() {
assert_eq!(render_time(100 as u64, 2000), "100ms")
}
#[test]
fn test_10s() {
assert_eq!(render_time(10 as u64), "10s")
assert_eq!(render_time(10 * 1000 as u64, 2000), "10s")
}
#[test]
fn test_90s() {
assert_eq!(render_time(90 as u64), "1m30s")
assert_eq!(render_time(90 * 1_000 as u64, 2000), "1m30s")
}
#[test]
fn test_10110s() {
assert_eq!(render_time(10110 as u64), "2h48m30s")
assert_eq!(render_time(10110 * 1_000 as u64, 2000), "2h48m30s")
}
#[test]
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]
fn config_blank_duration_1s() -> io::Result<()> {
let output = common::render_module("cmd_duration")
.arg("--cmd-duration=1")
.arg("--cmd-duration=1000000000")
.output()?;
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);
Ok(())
}
@ -18,7 +18,7 @@ fn config_blank_duration_1s() -> io::Result<()> {
#[test]
fn config_blank_duration_5s() -> io::Result<()> {
let output = common::render_module("cmd_duration")
.arg("--cmd-duration=5")
.arg("--cmd-duration=5000000000")
.output()?;
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")
.use_config(toml::toml! {
[cmd_duration]
min_time = 5
min_time = 5000
})
.arg("--cmd-duration=3")
.arg("--cmd-duration=3000000000")
.output()?;
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);
Ok(())
}
@ -48,9 +48,9 @@ fn config_5s_duration_10s() -> io::Result<()> {
let output = common::render_module("cmd_duration")
.use_config(toml::toml! {
[cmd_duration]
min_time = 5
min_time = 5000
})
.arg("--cmd-duration=10")
.arg("--cmd-duration=10000000000")
.output()?;
let actual = String::from_utf8(output.stdout).unwrap();