aboutsummaryrefslogtreecommitdiff
path: root/helix-term
diff options
context:
space:
mode:
authorBlaž Hrastnik2021-11-22 08:02:46 +0000
committerBlaž Hrastnik2021-11-29 02:00:28 +0000
commit27c1a84f053d1282ed09d64ec737a46f55685d85 (patch)
tree95c25e00ffe0472859d525fb365a7773df422e75 /helix-term
parentba45db84d4b49913836a949472366a30a620e67b (diff)
Reuse a text buffer for each gutter line
Diffstat (limited to 'helix-term')
-rw-r--r--helix-term/src/ui/editor.rs46
1 files changed, 30 insertions, 16 deletions
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index 2cc212ea..82fb8fbf 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -421,6 +421,8 @@ impl EditorView {
.map(|range| range.cursor_line(text))
.collect();
+ use std::fmt::Write;
+
fn diagnostic<'doc>(
doc: &'doc Document,
_view: &View,
@@ -435,18 +437,16 @@ impl EditorView {
let hint = theme.get("hint");
let diagnostics = doc.diagnostics();
- Box::new(move |line: usize, _selected: bool| {
+ Box::new(move |line: usize, _selected: bool, out: &mut String| {
use helix_core::diagnostic::Severity;
if let Some(diagnostic) = diagnostics.iter().find(|d| d.line == line) {
- return Some((
- "●".to_string(),
- match diagnostic.severity {
- Some(Severity::Error) => error,
- Some(Severity::Warning) | None => warning,
- Some(Severity::Info) => info,
- Some(Severity::Hint) => hint,
- },
- ));
+ write!(out, "●").unwrap();
+ return Some(match diagnostic.severity {
+ Some(Severity::Error) => error,
+ Some(Severity::Warning) | None => warning,
+ Some(Severity::Info) => info,
+ Some(Severity::Hint) => hint,
+ });
}
None
})
@@ -475,9 +475,10 @@ impl EditorView {
let config = config.line_number;
- Box::new(move |line: usize, selected: bool| {
+ Box::new(move |line: usize, selected: bool, out: &mut String| {
if line == last_line && !draw_last {
- Some((format!("{:>1$}", '~', width), linenr))
+ write!(out, "{:>1$}", '~', width).unwrap();
+ Some(linenr)
} else {
let line = match config {
LineNumber::Absolute => line + 1,
@@ -494,25 +495,38 @@ impl EditorView {
} else {
linenr
};
- Some((format!("{:>1$}", line, width), style))
+ write!(out, "{:>1$}", line, width).unwrap();
+ Some(style)
}
})
}
- type GutterFn<'doc> = Box<dyn Fn(usize, bool) -> Option<(String, Style)> + 'doc>;
+ type GutterFn<'doc> = Box<dyn Fn(usize, bool, &mut String) -> Option<Style> + 'doc>;
type Gutter =
for<'doc> fn(&'doc Document, &View, &Theme, &Config, bool, usize) -> GutterFn<'doc>;
let gutters: &[(Gutter, usize)] = &[(diagnostic, 1), (line_number, 5)];
let mut offset = 0;
+
+ // avoid lots of small allocations by reusing a text buffer for each line
+ let mut text = String::with_capacity(8);
+
for (constructor, width) in gutters {
let gutter = constructor(doc, view, theme, config, is_focused, *width);
+ text.reserve(*width); // ensure there's enough space for the gutter
for (i, line) in (view.offset.row..(last_line + 1)).enumerate() {
let selected = cursors.contains(&line);
- if let Some((text, style)) = gutter(line, selected) {
- surface.set_stringn(viewport.x + offset, viewport.y + i as u16, text, 5, style);
+ if let Some(style) = gutter(line, selected, &mut text) {
+ surface.set_stringn(
+ viewport.x + offset,
+ viewport.y + i as u16,
+ &text,
+ *width,
+ style,
+ );
}
+ text.clear();
}
offset += *width as u16;
}