@@ -112,6 +112,10 @@ impl EditorView {
115+ if editor.config().cursorline {
116+ Self::highlight_cursorline(doc, view, surface, theme);
115 let highlights = Self::doc_syntax_highlights(doc, view.offset, inner.height, theme);
119 let highlights = Self::doc_syntax_highlights(doc, view.offset, inner.height, theme);
116 let highlights = syntax::merge(highlights, Self::doc_diagnostics_highlights(doc, theme));
120 let highlights = syntax::merge(highlights, Self::doc_diagnostics_highlights(doc, theme));
117 let highlights: Box<dyn Iterator<Item = HighlightEvent>> = if is_focused {
121 let highlights: Box<dyn Iterator<Item = HighlightEvent>> = if is_focused {
@@ -686,6 +690,43 @@ impl EditorView {
693+ /// Apply the highlighting on the lines where a cursor is active
694+ pub fn highlight_cursorline(doc: &Document, view: &View, surface: &mut Surface, theme: &Theme) {
695+ let text = doc.text().slice(..);
696+ let last_line = view.last_line(doc);
698+ let primary_line = doc.selection(view.id).primary().cursor_line(text);
700+ // The secondary_lines do contain the primary_line, it doesn't matter
701+ // as the else-if clause in the loop later won't test for the
702+ // secondary_lines if primary_line == line.
703+ // It's used inside a loop so the collect isn't needless:
704+ // https://github.com/rust-lang/rust-clippy/issues/6164
705+ #[allow(clippy::needless_collect)]
706+ let secondary_lines: Vec<_> = doc
709+ .map(|range| range.cursor_line(text))
712+ let primary_style = theme.get("ui.cursorline.primary");
713+ let secondary_style = theme.get("ui.cursorline.secondary");
715+ for line in view.offset.row..(last_line + 1) {
716+ let area = Rect::new(
718+ view.area.y + (line - view.offset.row) as u16,
722+ if primary_line == line {
723+ surface.set_style(area, primary_style);
724+ } else if secondary_lines.binary_search(&line).is_ok() {
725+ surface.set_style(area, secondary_style);
689 pub fn render_statusline(
730 pub fn render_statusline(
691 doc: &Document,
732 doc: &Document,