Add line numbers in the editor

This commit is contained in:
2026-06-09 18:05:42 +03:00
parent 7e378ada8b
commit e83cab94b0

View File

@@ -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