diff --git a/nori-rs/tui/src/nori/session_config_history.rs b/nori-rs/tui/src/nori/session_config_history.rs index 20da90d8..6c832bdb 100644 --- a/nori-rs/tui/src/nori/session_config_history.rs +++ b/nori-rs/tui/src/nori/session_config_history.rs @@ -5,6 +5,7 @@ use std::collections::BTreeMap; use nori_acp as acp; use ratatui::style::Stylize; use ratatui::text::Line; +use ratatui::text::Span; use crate::history_cell::PlainHistoryCell; @@ -59,7 +60,7 @@ pub(crate) fn new_agent_options_initial_history_cell( if index > 0 { line.push(", ".into()); } - line.push(format!("{}={}", value.name, value.value).cyan().bold()); + line.extend(option_assignment_spans(&value.name, &value.value)); } line.push(" (/config to change)".dim()); @@ -89,7 +90,7 @@ pub(crate) fn new_agent_options_history_cell( if index > 0 { line.push(", ".into()); } - line.push(format!("{}={}", change.name, change.value).cyan().bold()); + line.extend(option_assignment_spans(&change.name, &change.value)); } PlainHistoryCell::new(vec![Line::from(line)]) @@ -105,11 +106,21 @@ pub(crate) fn new_agent_option_set_history_cell( } else { agent_display_name }; - PlainHistoryCell::new(vec![Line::from(vec![ + let mut line = vec![ "• ".dim(), format!("{agent_display_name} option set: ").into(), - format!("{option_name}={value_name}").cyan().bold(), - ])]) + ]; + line.extend(option_assignment_spans(option_name, value_name)); + + PlainHistoryCell::new(vec![Line::from(line)]) +} + +fn option_assignment_spans(name: &str, value: &str) -> Vec> { + vec![ + name.to_string().into(), + "=".into(), + value.to_string().cyan().bold(), + ] } fn display_value(option: &acp::SessionConfigOption) -> Option { @@ -136,3 +147,78 @@ fn display_value(option: &acp::SessionConfigOption) -> Option], + expected_name: &str, + expected_value: &str, + ) { + let name = spans + .iter() + .find(|span| span.content.as_ref() == expected_name) + .expect("option name should be its own span"); + let separator = spans + .iter() + .find(|span| span.content.as_ref() == "=") + .expect("separator should be its own span"); + let value = spans + .iter() + .find(|span| span.content.as_ref() == expected_value) + .expect("option value should be its own span"); + + assert_eq!(name.style, Style::default()); + assert_eq!(separator.style, Style::default()); + assert_eq!(value.style.fg, Some(Color::Cyan)); + assert!(value.style.add_modifier.contains(Modifier::BOLD)); + } + + fn spans_to_style_snapshot(spans: &[ratatui::text::Span<'static>]) -> String { + spans + .iter() + .map(|span| format!("{:?} {:?}", span.content, span.style)) + .collect::>() + .join("\n") + } +} diff --git a/nori-rs/tui/src/nori/snapshots/nori_tui__nori__session_config_history__tests__history_cells_highlight_values_not_names.snap b/nori-rs/tui/src/nori/snapshots/nori_tui__nori__session_config_history__tests__history_cells_highlight_values_not_names.snap new file mode 100644 index 00000000..8b94e678 --- /dev/null +++ b/nori-rs/tui/src/nori/snapshots/nori_tui__nori__session_config_history__tests__history_cells_highlight_values_not_names.snap @@ -0,0 +1,9 @@ +--- +source: tui/src/nori/session_config_history.rs +expression: "spans_to_style_snapshot(&lines[0].spans)" +--- +"• " Style::new().dim() +"Claude Code option set: " Style::new() +"Model" Style::new() +"=" Style::new() +"Opus 4.6" Style::new().cyan().bold()