mirror of
https://github.com/Llewellynvdm/starship.git
synced 2024-12-26 19:40:20 +00:00
feat: Add ability for command duration in milliseconds (#380)
This commit is contained in:
parent
c9878cab69
commit
c5e971aef8
@ -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
|
||||||
@ -228,8 +228,8 @@ 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. |
|
||||||
|
|
||||||
@ -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
|
||||||
|
@ -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"
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user