diff --git a/crates/kebab-tui/src/library.rs b/crates/kebab-tui/src/library.rs index 5ce1d6c..d46165d 100644 --- a/crates/kebab-tui/src/library.rs +++ b/crates/kebab-tui/src/library.rs @@ -127,6 +127,13 @@ fn filter_overlay_height(state: &App) -> u16 { } } +/// Single source of truth for the filter overlay row labels — used +/// both by `line_with_focus` (display) and the cursor-placement +/// `display_width(...)` math below. Editing one without the other +/// would silently miscolumn the caret. +const LABEL_TAGS: &str = "tags_any (csv): "; +const LABEL_LANG: &str = "lang: "; + fn render_filter_overlay(f: &mut Frame, area: Rect, edit: &FilterEdit, theme: &crate::theme::Theme) { let block = Block::default() .title("Filter (Tab=cycle field, Enter=apply, Esc=cancel)") @@ -135,8 +142,8 @@ fn render_filter_overlay(f: &mut Frame, area: Rect, edit: &FilterEdit, theme: &c f.render_widget(block, area); let lines = vec![ - line_with_focus("tags_any (csv): ", edit.tags_buf.as_str(), edit.field == FilterField::Tags, theme), - line_with_focus("lang: ", edit.lang_buf.as_str(), edit.field == FilterField::Lang, theme), + line_with_focus(LABEL_TAGS, edit.tags_buf.as_str(), edit.field == FilterField::Tags, theme), + line_with_focus(LABEL_LANG, edit.lang_buf.as_str(), edit.field == FilterField::Lang, theme), ]; let para = Paragraph::new(lines); f.render_widget(para, inner); @@ -146,18 +153,11 @@ fn render_filter_overlay(f: &mut Frame, area: Rect, edit: &FilterEdit, theme: &c // omits set_cursor_position (Library/Inspect main view), ratatui // calls hide_cursor instead. So this single call positions the // caret on the focused field of the filter overlay. - let (label_w, focused_buf, row_offset) = match edit.field { - FilterField::Tags => ( - display_width("tags_any (csv): ") as u16, - &edit.tags_buf, - 0u16, - ), - FilterField::Lang => ( - display_width("lang: ") as u16, - &edit.lang_buf, - 1u16, - ), + let (label, focused_buf, row_offset) = match edit.field { + FilterField::Tags => (LABEL_TAGS, &edit.tags_buf, 0u16), + FilterField::Lang => (LABEL_LANG, &edit.lang_buf, 1u16), }; + let label_w = display_width(label) as u16; let raw_x = inner.x + label_w + focused_buf.cursor_col() as u16; let cursor_x = raw_x.min(inner.x + inner.width.saturating_sub(1)); f.set_cursor_position((cursor_x, inner.y + row_offset));