diff --git a/docs/config/README.md b/docs/config/README.md index b910229a..c4007aa1 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -3407,7 +3407,7 @@ To enable it, set `disabled` to `false` in your configuration file. | `recognize_signal_code` | `true` | Enable signal mapping from exit code | | `map_symbol` | `false` | Enable symbols mapping from exit code | | `pipestatus` | `false` | Enable pipestatus reporting | -| `pipestatus_separator` | | | The symbol used to separate pipestatus segments | +| `pipestatus_separator` | | | The symbol used to separate pipestatus segments (supports formatting) | | `pipestatus_format` | `'\[$pipestatus\] => [$symbol$common_meaning$signal_name$maybe_int]($style)'` | The format of the module when the command is a pipeline | | `pipestatus_segment_format` | | When specified, replaces `format` when formatting pipestatus segments | | `disabled` | `true` | Disables the `status` module. | diff --git a/src/modules/status.rs b/src/modules/status.rs index c202eea7..e14afd6a 100644 --- a/src/modules/status.rs +++ b/src/modules/status.rs @@ -55,22 +55,30 @@ pub fn module<'a>(context: &'a Context) -> Option> { } let segment_format = config.pipestatus_segment_format.unwrap_or(config.format); + let segment_format_with_separator = [segment_format, config.pipestatus_separator].join(""); // Create pipestatus string let pipestatus = match pipestatus_status { PipeStatusStatus::Pipe(pipestatus) => pipestatus .iter() - .map( - |ec| match format_exit_code(ec.as_str(), segment_format, None, &config, context) { - Ok(segments) => segments - .into_iter() - .map(|s| s.to_string()) - .collect::(), - Err(_) => "".to_string(), - }, - ) - .collect::>() - .join(config.pipestatus_separator), + .enumerate() + .filter_map(|(i, ec)| { + format_exit_code( + ec.as_str(), + if i == pipestatus.len() - 1 { + segment_format + } else { + &segment_format_with_separator + }, + None, + &config, + context, + ) + .ok() + .map(|segments| segments.into_iter().map(|s| s.to_string())) + }) + .flatten() + .collect::(), _ => "".to_string(), }; @@ -225,7 +233,7 @@ fn status_signal_name(signal: SignalNumber) -> Option<&'static str> { #[cfg(test)] mod tests { - use nu_ansi_term::Color; + use nu_ansi_term::{Color, Style}; use crate::test::ModuleRenderer; @@ -708,4 +716,37 @@ mod tests { .collect(); assert_eq!(expected, actual); } + + #[test] + fn pipestatus_separator_format() { + let pipe_exit_code = &[0, 1, 2]; + let main_exit_code = 2; + + let expected_style = Style::new().on(Color::Red).fg(Color::White).bold(); + let expected = Some(format!( + "{}{}{}{}{}{}{}", + expected_style.paint("["), + expected_style.paint("0"), + expected_style.paint("|"), + expected_style.paint("1"), + expected_style.paint("|"), + expected_style.paint("2"), + expected_style.paint("] => <2>"), + )); + let actual = ModuleRenderer::new("status") + .config(toml::toml! { + [status] + format = "\\($status\\)" + style = "fg:white bg:red bold" + pipestatus = true + pipestatus_separator = "[|]($style)" + pipestatus_format = "[\\[]($style)$pipestatus[\\] => <$status>]($style)" + pipestatus_segment_format = "[$status]($style)" + disabled = false + }) + .status(main_exit_code) + .pipestatus(pipe_exit_code) + .collect(); + assert_eq!(expected, actual); + } }