diff --git a/src/tui.rs b/src/tui.rs index 44f3ed8..5412096 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -1001,7 +1001,12 @@ fn render_editor(frame: &mut Frame, area: Rect, editor: &Editor, focused: bool) /// Build the cursor-bearing line as three spans: text before, the /// highlighted character at the cursor, text after. If the cursor sits -/// past the end of the line, the highlight falls on a trailing space. +/// past the end of the line (or on a whitespace cell), the highlight +/// falls on a visible block glyph — some terminals / ratatui's wrap +/// layer skip painting bg on styled space cells, which would leave the +/// cursor invisible. +const CURSOR_PLACEHOLDER: char = '▏'; + fn editor_cursor_line(line: &str, col: usize, cursor_style: Style) -> Line<'static> { let col = col.min(line.len()); let before = line[..col].to_string(); @@ -1011,15 +1016,17 @@ fn editor_cursor_line(line: &str, col: usize, cursor_style: Style) -> Line<'stat let mut chars = after.char_indices(); let (_, c) = chars.next().expect("non-empty: col < line.len()"); let next_boundary = chars.next().map(|(i, _)| i).unwrap_or(after.len()); + let glyph = if c.is_whitespace() { CURSOR_PLACEHOLDER } else { c }; Line::from(vec![ Span::raw(before), - Span::styled(c.to_string(), cursor_style), + Span::styled(glyph.to_string(), cursor_style), Span::raw(after[next_boundary..].to_string()), ]) } else { + // Cursor past end of line — show the placeholder glyph. Line::from(vec![ Span::raw(before), - Span::styled(" ".to_string(), cursor_style), + Span::styled(CURSOR_PLACEHOLDER.to_string(), cursor_style), ]) } }