Skip to content

Commit

Permalink
perf(custom): evaluate command lazily (starship#2173)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidkna authored Jan 20, 2021
1 parent bb160d9 commit 8302a3c
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 43 deletions.
24 changes: 12 additions & 12 deletions docs/config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2559,18 +2559,18 @@ If you have an interesting example not covered there, feel free to share it ther
### Options

| Option | Default | Description |
| ------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `command` | | The command whose output should be printed. The command will be passed on stdin to the shell. |
| `when` | | A shell command used as a condition to show the module. The module will be shown if the command returns a `0` status code. |
| `shell` | | [See below](#custom-command-shell) |
| `description` | `"<custom module>"` | The description of the module that is shown when running `starship explain`. |
| `files` | `[]` | The files that will be searched in the working directory for a match. |
| `directories` | `[]` | The directories that will be searched in the working directory for a match. |
| `extensions` | `[]` | The extensions that will be searched in the working directory for a match. |
| `symbol` | `""` | The symbol used before displaying the command output. |
| `style` | `"bold green"` | The style for the module. |
| `format` | `"[$symbol$output]($style) "` | The format for the module. |
| `disabled` | `false` | Disables this `custom` module. |
| ------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `command` | | The command whose output should be printed. The command will be passed on stdin to the shell. |
| `when` | | A shell command used as a condition to show the module. The module will be shown if the command returns a `0` status code. |
| `shell` | | [See below](#custom-command-shell) |
| `description` | `"<custom module>"` | The description of the module that is shown when running `starship explain`. |
| `files` | `[]` | The files that will be searched in the working directory for a match. |
| `directories` | `[]` | The directories that will be searched in the working directory for a match. |
| `extensions` | `[]` | The extensions that will be searched in the working directory for a match. |
| `symbol` | `""` | The symbol used before displaying the command output. |
| `style` | `"bold green"` | The style for the module. |
| `format` | `"[$symbol($output )]($style)"` | The format for the module. |
| `disabled` | `false` | Disables this `custom` module. |

### Variables

Expand Down
2 changes: 1 addition & 1 deletion src/configs/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub struct CustomConfig<'a> {
impl<'a> RootModuleConfig<'a> for CustomConfig<'a> {
fn new() -> Self {
CustomConfig {
format: "[$symbol$output]($style) ",
format: "[$symbol($output )]($style)",
symbol: "",
command: "",
when: None,
Expand Down
62 changes: 32 additions & 30 deletions src/modules/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,36 +46,38 @@ pub fn module<'a>(name: &str, context: &'a Context) -> Option<Module<'a>> {

let mut module = Module::new(name, config.description, Some(toml_config));

let output = exec_command(config.command, &config.shell.0)?;

let trimmed = output.trim();
if !trimmed.is_empty() {
let parsed = StringFormatter::new(config.format).and_then(|formatter| {
formatter
.map_meta(|var, _| match var {
"symbol" => Some(config.symbol),
_ => None,
})
.map_style(|variable| match variable {
"style" => Some(Ok(config.style)),
_ => None,
})
.map(|variable| match variable {
// This may result in multiple calls to `get_module_version` when a user have
// multiple `$version` variables defined in `format`.
"output" => Some(Ok(trimmed)),
_ => None,
})
.parse(None)
});

match parsed {
Ok(segments) => module.set_segments(segments),
Err(error) => {
log::warn!("Error in module `custom.{}`:\n{}", name, error);
}
};
}
let parsed = StringFormatter::new(config.format).and_then(|formatter| {
formatter
.map_meta(|var, _| match var {
"symbol" => Some(config.symbol),
_ => None,
})
.map_style(|variable| match variable {
"style" => Some(Ok(config.style)),
_ => None,
})
.map(|variable| match variable {
"output" => {
let output = exec_command(config.command, &config.shell.0)?;
let trimmed = output.trim();

if trimmed.is_empty() {
None
} else {
Some(Ok(trimmed.to_string()))
}
}
_ => None,
})
.parse(None)
});

match parsed {
Ok(segments) => module.set_segments(segments),
Err(error) => {
log::warn!("Error in module `custom.{}`:\n{}", name, error);
}
};
let elapsed = start.elapsed();
log::trace!("Took {:?} to compute custom module {:?}", elapsed, name);
module.duration = elapsed;
Expand Down

0 comments on commit 8302a3c

Please sign in to comment.