Fix config view column alignment
Size the config key column from the available setting keys so long keys like paste_burst_detection remain fully visible without pushing the value and scope columns out of alignment. Add a regression test covering long config keys and scope column alignment.
This commit is contained in:
@@ -555,6 +555,9 @@ pub struct ConfigView {
|
||||
last_row_hitboxes: RefCell<Vec<(u16, usize)>>,
|
||||
}
|
||||
|
||||
const CONFIG_MIN_KEY_COLUMN_WIDTH: usize = 19;
|
||||
const CONFIG_VALUE_COLUMN_WIDTH: usize = 44;
|
||||
|
||||
impl ConfigView {
|
||||
pub fn new_for_app(app: &App) -> Self {
|
||||
let settings = Settings::load().unwrap_or_else(|_| Settings::default());
|
||||
@@ -769,6 +772,15 @@ impl ConfigView {
|
||||
items
|
||||
}
|
||||
|
||||
fn key_column_width(&self) -> usize {
|
||||
self.rows
|
||||
.iter()
|
||||
.map(|row| row.key.chars().count())
|
||||
.max()
|
||||
.unwrap_or(CONFIG_MIN_KEY_COLUMN_WIDTH)
|
||||
.max(CONFIG_MIN_KEY_COLUMN_WIDTH)
|
||||
}
|
||||
|
||||
fn selected_row_index(&self) -> Option<usize> {
|
||||
let selected = self.selected;
|
||||
self.matching_row_indices()
|
||||
@@ -1257,6 +1269,7 @@ impl ModalView for ConfigView {
|
||||
self.filter.clone()
|
||||
};
|
||||
|
||||
let key_column_width = self.key_column_width();
|
||||
let mut lines: Vec<Line> = vec![
|
||||
Line::from(vec![Span::styled(
|
||||
self.tr(MessageId::ConfigTitle),
|
||||
@@ -1271,8 +1284,17 @@ impl ModalView for ConfigView {
|
||||
),
|
||||
]),
|
||||
Line::from(""),
|
||||
Line::from(" Key Value Scope"),
|
||||
Line::from(" ----------------------------------------------------------------"),
|
||||
Line::from(format!(
|
||||
" {:<key_width$} {:<value_width$} Scope",
|
||||
"Key",
|
||||
"Value",
|
||||
key_width = key_column_width,
|
||||
value_width = CONFIG_VALUE_COLUMN_WIDTH
|
||||
)),
|
||||
Line::from(format!(
|
||||
" {}",
|
||||
"-".repeat(key_column_width + CONFIG_VALUE_COLUMN_WIDTH + 8)
|
||||
)),
|
||||
];
|
||||
let mut row_hitboxes = Vec::new();
|
||||
|
||||
@@ -1299,12 +1321,14 @@ impl ModalView for ConfigView {
|
||||
} else {
|
||||
Style::default().fg(palette::TEXT_PRIMARY)
|
||||
};
|
||||
let value = truncate_view_text(&row.value, 44);
|
||||
let value = truncate_view_text(&row.value, CONFIG_VALUE_COLUMN_WIDTH);
|
||||
let mut line = Line::from(format!(
|
||||
" {:<19} {:<44} {}",
|
||||
" {:<key_width$} {:<value_width$} {}",
|
||||
row.key,
|
||||
value,
|
||||
row.scope.label()
|
||||
row.scope.label(),
|
||||
key_width = key_column_width,
|
||||
value_width = CONFIG_VALUE_COLUMN_WIDTH
|
||||
));
|
||||
line.style = style;
|
||||
lines.push(line);
|
||||
@@ -2081,6 +2105,37 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_view_keeps_scope_column_aligned_for_long_keys() {
|
||||
let app = create_test_app();
|
||||
let mut view = ConfigView::new_for_app(&app);
|
||||
type_filter(&mut view, "composer");
|
||||
let area = Rect::new(0, 0, 100, 24);
|
||||
let mut buf = Buffer::empty(area);
|
||||
|
||||
view.render(area, &mut buf);
|
||||
|
||||
let dump = buffer_text(&buf, area);
|
||||
assert!(
|
||||
dump.contains("paste_burst_detection"),
|
||||
"long config keys should stay readable:\n{dump}"
|
||||
);
|
||||
let scope_columns = dump
|
||||
.lines()
|
||||
.filter_map(|line| line.find("SAVED").or_else(|| line.find("SESSION")))
|
||||
.collect::<Vec<_>>();
|
||||
assert!(
|
||||
scope_columns.len() >= 3,
|
||||
"expected composer config rows with scopes:\n{dump}"
|
||||
);
|
||||
assert!(
|
||||
scope_columns
|
||||
.iter()
|
||||
.all(|column| *column == scope_columns[0]),
|
||||
"scope column should stay aligned even for long keys:\n{dump}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_view_filter_no_match_does_not_edit_hidden_row() {
|
||||
let app = create_test_app();
|
||||
|
||||
Reference in New Issue
Block a user