use crate::config::{Config, FormatterBackend, RSourceOverrideInfo, ReprexMode};
use crate::editor::prompt::get_r_version;
pub fn format_banner(
config: &Config,
r_initialized: bool,
override_info: Option<&RSourceOverrideInfo>,
formatter_backend: Option<FormatterBackend>,
) -> String {
let mut lines = Vec::new();
lines.push(format!("# arf console v{}", env!("CARGO_PKG_VERSION")));
lines.push(format!("# Edit mode: {}", config.editor.mode));
match config.startup.reprex {
ReprexMode::Off => {}
ReprexMode::On => lines.push(format!(
"# Reprex: on | Comment: {:?}",
config.reprex.comment
)),
ReprexMode::Format => {
let formatter_label = match (config.reprex.formatter, formatter_backend) {
(crate::config::ReprexFormatter::Auto, Some(backend)) => {
format!("auto ({})", backend.command())
}
(crate::config::ReprexFormatter::Auto, None) => "auto (unavailable)".to_string(),
(selector, Some(backend)) => format!("{selector} ({})", backend.command()),
(selector, None) => format!("{selector} (unavailable)"),
};
lines.push(format!(
"# Reprex: format | Comment: {:?} | Formatter: {}",
config.reprex.comment, formatter_label
));
}
}
if r_initialized {
let r_version = get_r_version();
if r_version.is_empty() {
lines.push("# R is ready.".to_string());
} else {
lines.push(format!("# R {} is ready.", r_version));
}
if let Some(info) = override_info {
lines.push(format_override_line(info));
}
} else {
lines.push("# R is not initialized. Commands will not be evaluated.".to_string());
}
lines.push("# Type :cmds for meta commands list, Ctrl+D to exit.".to_string());
lines.push(String::new());
lines.join("\n")
}
pub(crate) fn format_override_line(info: &RSourceOverrideInfo) -> String {
format!("# R source override: {}", info.display())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_banner_default_r_initialized() {
let config = Config::default();
let banner = format_banner(&config, true, None, Some(FormatterBackend::Air));
insta::assert_snapshot!("banner_default_r_initialized", banner);
}
#[test]
fn test_banner_default_r_not_initialized() {
let config = Config::default();
let banner = format_banner(&config, false, None, Some(FormatterBackend::Air));
insta::assert_snapshot!("banner_default_r_not_initialized", banner);
}
#[test]
fn test_banner_reprex_mode() {
let mut config = Config::default();
config.startup.reprex = ReprexMode::On;
let banner = format_banner(&config, true, None, Some(FormatterBackend::Air));
insta::assert_snapshot!("banner_reprex_mode", banner);
}
#[test]
fn test_banner_reprex_custom_comment() {
let mut config = Config::default();
config.startup.reprex = ReprexMode::On;
config.reprex.comment = "## ".to_string();
let banner = format_banner(&config, true, None, Some(FormatterBackend::Air));
insta::assert_snapshot!("banner_reprex_custom_comment", banner);
}
#[test]
fn test_banner_reprex_format_mode() {
let mut config = Config::default();
config.startup.reprex = ReprexMode::Format;
let banner = format_banner(&config, true, None, Some(FormatterBackend::Air));
insta::assert_snapshot!("banner_reprex_format_mode", banner);
}
#[test]
fn test_banner_vi_mode() {
let mut config = Config::default();
config.editor.mode = crate::config::EditorMode::Vi;
let banner = format_banner(&config, true, None, Some(FormatterBackend::Air));
insta::assert_snapshot!("banner_vi_mode", banner);
}
#[test]
fn test_banner_all_lines_start_with_comment() {
let config = Config::default();
let banner = format_banner(&config, true, None, Some(FormatterBackend::Air));
for line in banner.lines() {
if !line.is_empty() {
assert!(
line.starts_with("# "),
"Banner line should start with '# ': {:?}",
line
);
}
}
}
#[test]
fn test_banner_includes_r_source_override_line() {
let config = Config::default();
let info = RSourceOverrideInfo {
provider: "toml-key".to_string(),
file: Some("rproject.toml".into()),
key: Some("project.r_version".to_string()),
requested_version: "4.4".to_string(),
resolved_version: "4.4.2".to_string(),
};
let banner = format_banner(&config, true, Some(&info), Some(FormatterBackend::Air));
assert!(
banner.contains(
"# R source override: toml-key rproject.toml:project.r_version = \"4.4\""
)
);
}
#[test]
fn test_hidden_banner_override_line_is_one_stderr_line() {
let info = RSourceOverrideInfo {
provider: "version-file".to_string(),
file: Some(".r-version".into()),
key: None,
requested_version: "4.4".to_string(),
resolved_version: "4.4.2".to_string(),
};
let line = format_override_line(&info);
assert_eq!(
line,
"# R source override: version-file .r-version = \"4.4\""
);
assert!(!line.contains('\n'));
}
}