Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-term/src/ui/editor.rs')
-rw-r--r--helix-term/src/ui/editor.rs94
1 files changed, 48 insertions, 46 deletions
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index a071bfaa..c151a7dd 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -5,8 +5,10 @@ use crate::{
key,
keymap::{KeymapResult, Keymaps},
ui::{
- document::{render_document, LinePos, TextRenderer, TranslatedPosition},
- Completion, ProgressSpinners,
+ document::{render_document, LinePos, TextRenderer},
+ statusline,
+ text_decorations::{self, Decoration, DecorationManager, InlineDiagnostics},
+ Completion, CompletionItem, ProgressSpinners,
},
};
@@ -20,6 +22,7 @@ use helix_core::{
visual_offset_from_block, Change, Position, Range, Selection, Transaction,
};
use helix_view::{
+ annotations::diagnostics::DiagnosticFilter,
document::{Mode, SavePoint, SCRATCH_BUFFER_NAME},
editor::{CompleteAction, CursorShapeConfig},
graphics::{Color, CursorKind, Modifier, Rect, Style},
@@ -31,9 +34,6 @@ use std::{mem::take, num::NonZeroUsize, path::PathBuf, rc::Rc, sync::Arc};
use tui::{buffer::Buffer as Surface, text::Span};
-use super::document::LineDecoration;
-use super::{completion::CompletionItem, statusline};
-
pub struct EditorView {
pub keymaps: Keymaps,
on_next_key: Option<OnKeyCallback>,
@@ -94,11 +94,10 @@ impl EditorView {
let config = editor.config();
let text_annotations = view.text_annotations(doc, Some(theme));
- let mut line_decorations: Vec<Box<dyn LineDecoration>> = Vec::new();
- let mut translated_positions: Vec<TranslatedPosition> = Vec::new();
+ let mut decorations = DecorationManager::default();
if is_focused && config.cursorline {
- line_decorations.push(Self::cursorline_decorator(doc, view, theme))
+ decorations.add_decoration(Self::cursorline(doc, view, theme));
}
if is_focused && config.cursorcolumn {
@@ -113,13 +112,10 @@ impl EditorView {
if pos.doc_line != dap_line {
return;
}
- renderer.surface.set_style(
- Rect::new(inner.x, inner.y + pos.visual_line, inner.width, 1),
- style,
- );
+ renderer.set_style(Rect::new(inner.x, pos.visual_line, inner.width, 1), style);
};
- line_decorations.push(Box::new(line_decoration));
+ decorations.add_decoration(line_decoration);
}
let syntax_highlights =
@@ -176,22 +172,33 @@ impl EditorView {
view.area,
theme,
is_focused & self.terminal_focused,
- &mut line_decorations,
+ &mut decorations,
);
}
+ let primary_cursor = doc
+ .selection(view.id)
+ .primary()
+ .cursor(doc.text().slice(..));
if is_focused {
- let cursor = doc
- .selection(view.id)
- .primary()
- .cursor(doc.text().slice(..));
- // set the cursor_cache to out of view in case the position is not found
- editor.cursor_cache.set(Some(None));
- let update_cursor_cache =
- |_: &mut TextRenderer, pos| editor.cursor_cache.set(Some(Some(pos)));
- translated_positions.push((cursor, Box::new(update_cursor_cache)));
+ decorations.add_decoration(text_decorations::Cursor {
+ cache: &editor.cursor_cache,
+ primary_cursor,
+ });
}
-
+ let width = view.inner_width(doc);
+ let config = doc.config.load();
+ let enable_cursor_line = view
+ .diagnostics_handler
+ .show_cursorline_diagnostics(doc, view.id);
+ let inline_diagnostic_config = config.inline_diagnostics.prepare(width, enable_cursor_line);
+ decorations.add_decoration(InlineDiagnostics::new(
+ doc,
+ theme,
+ primary_cursor,
+ inline_diagnostic_config,
+ config.end_of_line_diagnostics,
+ ));
render_document(
surface,
inner,
@@ -201,8 +208,7 @@ impl EditorView {
syntax_highlights,
overlay_highlights,
theme,
- &mut line_decorations,
- &mut translated_positions,
+ decorations,
);
Self::render_rulers(editor, doc, view, inner, surface, theme);
@@ -218,7 +224,11 @@ impl EditorView {
}
}
- Self::render_diagnostics(doc, view, inner, surface, theme);
+ if config.inline_diagnostics.disabled()
+ && config.end_of_line_diagnostics == DiagnosticFilter::Disable
+ {
+ Self::render_diagnostics(doc, view, inner, surface, theme);
+ }
let statusline_area = view
.area
@@ -637,7 +647,7 @@ impl EditorView {
viewport: Rect,
theme: &Theme,
is_focused: bool,
- line_decorations: &mut Vec<Box<(dyn LineDecoration + 'd)>>,
+ decoration_manager: &mut DecorationManager<'d>,
) {
let text = doc.text().slice(..);
let cursors: Rc<[_]> = doc
@@ -663,7 +673,7 @@ impl EditorView {
// TODO handle softwrap in gutters
let selected = cursors.contains(&pos.doc_line);
let x = viewport.x + offset;
- let y = viewport.y + pos.visual_line;
+ let y = pos.visual_line;
let gutter_style = match (selected, pos.first_visual_line) {
(false, true) => gutter_style,
@@ -675,11 +685,9 @@ impl EditorView {
if let Some(style) =
gutter(pos.doc_line, selected, pos.first_visual_line, &mut text)
{
- renderer
- .surface
- .set_stringn(x, y, &text, width, gutter_style.patch(style));
+ renderer.set_stringn(x, y, &text, width, gutter_style.patch(style));
} else {
- renderer.surface.set_style(
+ renderer.set_style(
Rect {
x,
y,
@@ -691,7 +699,7 @@ impl EditorView {
}
text.clear();
};
- line_decorations.push(Box::new(gutter_decoration));
+ decoration_manager.add_decoration(gutter_decoration);
offset += width as u16;
}
@@ -761,11 +769,7 @@ impl EditorView {
}
/// Apply the highlighting on the lines where a cursor is active
- pub fn cursorline_decorator(
- doc: &Document,
- view: &View,
- theme: &Theme,
- ) -> Box<dyn LineDecoration> {
+ pub fn cursorline(doc: &Document, view: &View, theme: &Theme) -> impl Decoration {
let text = doc.text().slice(..);
// TODO only highlight the visual line that contains the cursor instead of the full visual line
let primary_line = doc.selection(view.id).primary().cursor_line(text);
@@ -786,16 +790,14 @@ impl EditorView {
let secondary_style = theme.get("ui.cursorline.secondary");
let viewport = view.area;
- let line_decoration = move |renderer: &mut TextRenderer, pos: LinePos| {
- let area = Rect::new(viewport.x, viewport.y + pos.visual_line, viewport.width, 1);
+ move |renderer: &mut TextRenderer, pos: LinePos| {
+ let area = Rect::new(viewport.x, pos.visual_line, viewport.width, 1);
if primary_line == pos.doc_line {
- renderer.surface.set_style(area, primary_style);
+ renderer.set_style(area, primary_style);
} else if secondary_lines.binary_search(&pos.doc_line).is_ok() {
- renderer.surface.set_style(area, secondary_style);
+ renderer.set_style(area, secondary_style);
}
- };
-
- Box::new(line_decoration)
+ }
}
/// Apply the highlighting on the columns where a cursor is active