@@ -17,6 +17,7 @@ use helix_core::{
1717};
1818use helix_view::{
1919 document::{Mode, SCRATCH_BUFFER_NAME},
20+ editor::CursorShapeConfig,
2021 graphics::{CursorKind, Modifier, Rect, Style},
2122 info::Info,
2223 input::KeyEvent,
@@ -79,7 +80,7 @@ impl EditorView {
7980 let highlights: Box<dyn Iterator<Item = HighlightEvent>> = if is_focused {
8081 Box::new(syntax::merge(
8182 highlights,
82− Self::doc_selection_highlights(doc, view, theme),
83+ Self::doc_selection_highlights(doc, view, theme, &config.cursor_shape),
8384 ))
8485 } else {
8586 Box::new(highlights)
@@ -213,11 +214,16 @@ impl EditorView {
213214 doc: &Document,
214215 view: &View,
215216 theme: &Theme,
217+ cursor_shape_config: &CursorShapeConfig,
216218 ) -> Vec<(usize, std::ops::Range<usize>)> {
217219 let text = doc.text().slice(..);
218220 let selection = doc.selection(view.id);
219221 let primary_idx = selection.primary_index();
220222
223+ let mode = doc.mode();
224+ let cursorkind = cursor_shape_config.from_mode(mode);
225+ let cursor_is_block = cursorkind == CursorKind::Block;
226+
221227 let selection_scope = theme
222228 .find_scope_index("ui.selection")
223229 .expect("could not find `ui.selection` scope in the theme!");
@@ -225,13 +231,16 @@ impl EditorView {
225231 .find_scope_index("ui.cursor")
226232 .unwrap_or(selection_scope);
227233
228− let cursor_scope = match doc.mode() {
234+ let cursor_scope = match mode {
229235 Mode::Insert => theme.find_scope_index("ui.cursor.insert"),
230236 Mode::Select => theme.find_scope_index("ui.cursor.select"),
231237 Mode::Normal => Some(base_cursor_scope),
232238 }
233239 .unwrap_or(base_cursor_scope);
234240
241+ let primary_cursor_scope = theme
242+ .find_scope_index("ui.cursor.primary")
243+ .unwrap_or(cursor_scope);
235244 let primary_selection_scope = theme
236245 .find_scope_index("ui.selection.primary")
237246 .unwrap_or(selection_scope);
@@ -239,16 +248,20 @@ impl EditorView {
239248 let mut spans: Vec<(usize, std::ops::Range<usize>)> = Vec::new();
240249 for (i, range) in selection.iter().enumerate() {
241250 let selection_is_primary = i == primary_idx;
242− let selection_scope = if selection_is_primary {
243− primary_selection_scope
251+ let (cursor_scope, selection_scope) = if selection_is_primary {
252+ (primary_cursor_scope, primary_selection_scope)
244253 } else {
245− selection_scope
254+ (cursor_scope, selection_scope)
246255 };
247256
248257 // Special-case: cursor at end of the rope.
249258 if range.head == range.anchor && range.head == text.len_chars() {
250− if !selection_is_primary {
251− // Terminal cursor acts as the primary cursor
259+ if !selection_is_primary || cursor_is_block {
260+ // Bar and underline cursors are drawn by the terminal
261+ // BUG: If the editor area loses focus while having a bar or
262+ // underline cursor (eg. when a regex prompt has focus) then
263+ // the primary cursor will be invisible. This doesn't happen
264+ // with block cursors since we manually draw *all* cursors.
252265 spans.push((cursor_scope, range.head..range.head + 1));
253266 }
254267 continue;
@@ -259,13 +272,13 @@ impl EditorView {
259272 // Standard case.
260273 let cursor_start = prev_grapheme_boundary(text, range.head);
261274 spans.push((selection_scope, range.anchor..cursor_start));
262− if !selection_is_primary {
275+ if !selection_is_primary || cursor_is_block {
263276 spans.push((cursor_scope, cursor_start..range.head));
264277 }
265278 } else {
266279 // Reverse case.
267280 let cursor_end = next_grapheme_boundary(text, range.head);
268− if !selection_is_primary {
281+ if !selection_is_primary || cursor_is_block {
269282 spans.push((cursor_scope, range.head..cursor_end));
270283 }
271284 spans.push((selection_scope, cursor_end..range.anchor));
@@ -1140,11 +1153,11 @@ impl Component for EditorView {
11401153 }
11411154
11421155 fn cursor(&self, _area: Rect, editor: &Editor) -> (Option<Position>, CursorKind) {
1143− // match view.doc.mode() {
1144− // Mode::Insert => write!(stdout, "\x1B[6 q"),
1145− // mode => write!(stdout, "\x1B[2 q"),
1146− // };
1147− editor.cursor()
1156+ match editor.cursor() {
1157+ // All block cursors are drawn manually
1158+ (pos, CursorKind::Block) => (pos, CursorKind::Hidden),
1159+ cursor => cursor,
1160+ }
11481161 }
11491162}
11501163