Add line numbers in the editor
This commit is contained in:
46
src/tui.rs
46
src/tui.rs
@@ -968,6 +968,11 @@ fn render_editor(frame: &mut Frame, area: Rect, editor: &Editor, focused: bool)
|
||||
};
|
||||
let block = Block::default().borders(Borders::ALL).title(title);
|
||||
|
||||
// Line numbers occupy a fixed-width left gutter. Width grows with the
|
||||
// largest line number so the body never shifts as lines are added.
|
||||
let gutter_width = line_number_width(editor.buffer.len());
|
||||
let gutter_style = Style::default().fg(Color::DarkGray);
|
||||
|
||||
if focused {
|
||||
// Highlight the character under the cursor with explicit bg + fg
|
||||
// colours (not `REVERSED`) so the cursor cell is filled even when
|
||||
@@ -981,24 +986,55 @@ fn render_editor(frame: &mut Frame, area: Rect, editor: &Editor, focused: bool)
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(r, line)| {
|
||||
if r == cr {
|
||||
let body = if r == cr {
|
||||
editor_cursor_line(line, cc, cursor_style)
|
||||
} else {
|
||||
Line::from(line.clone())
|
||||
}
|
||||
};
|
||||
prepend_line_number(body, r + 1, gutter_width, gutter_style)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let p = Paragraph::new(lines).block(block).wrap(Wrap { trim: false });
|
||||
frame.render_widget(p, area);
|
||||
} else {
|
||||
let p = Paragraph::new(editor.text())
|
||||
.block(block)
|
||||
.wrap(Wrap { trim: false });
|
||||
let lines: Vec<Line> = editor
|
||||
.buffer
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(r, line)| {
|
||||
prepend_line_number(
|
||||
Line::from(line.clone()),
|
||||
r + 1,
|
||||
gutter_width,
|
||||
gutter_style,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
let p = Paragraph::new(lines).block(block).wrap(Wrap { trim: false });
|
||||
frame.render_widget(p, area);
|
||||
}
|
||||
}
|
||||
|
||||
fn line_number_width(line_count: usize) -> usize {
|
||||
let max = line_count.max(1);
|
||||
let mut digits = 1;
|
||||
let mut n = max;
|
||||
while n >= 10 {
|
||||
n /= 10;
|
||||
digits += 1;
|
||||
}
|
||||
digits
|
||||
}
|
||||
|
||||
fn prepend_line_number(line: Line<'static>, number: usize, width: usize, style: Style) -> Line<'static> {
|
||||
let gutter = format!("{:>width$} │ ", number, width = width);
|
||||
let mut spans = Vec::with_capacity(line.spans.len() + 1);
|
||||
spans.push(Span::styled(gutter, style));
|
||||
spans.extend(line.spans);
|
||||
Line::from(spans)
|
||||
}
|
||||
|
||||
/// 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 (or on a whitespace cell), the highlight
|
||||
|
||||
Reference in New Issue
Block a user