diff options
author | Gokul Soumya | 2021-12-23 06:26:52 +0000 |
---|---|---|
committer | Gokul Soumya | 2021-12-23 06:26:52 +0000 |
commit | c0bbadcaaf42698d102fa03f6f9267021f3efec0 (patch) | |
tree | 4ce51151dea4ff0fe58d53ea6a5a94b58332bfc6 /helix-term | |
parent | d4fb1d06333315a3c6e9dc7f0ad8055d91551e3a (diff) |
Manually draw all block cursors
Diffstat (limited to 'helix-term')
-rw-r--r-- | helix-term/src/ui/editor.rs | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 7d57e581..6b015171 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -17,6 +17,7 @@ use helix_core::{ }; use helix_view::{ document::{Mode, SCRATCH_BUFFER_NAME}, + editor::CursorShapeConfig, graphics::{CursorKind, Modifier, Rect, Style}, info::Info, input::KeyEvent, @@ -79,7 +80,7 @@ impl EditorView { let highlights: Box<dyn Iterator<Item = HighlightEvent>> = if is_focused { Box::new(syntax::merge( highlights, - Self::doc_selection_highlights(doc, view, theme), + Self::doc_selection_highlights(doc, view, theme, &config.cursor_shape), )) } else { Box::new(highlights) @@ -213,11 +214,16 @@ impl EditorView { doc: &Document, view: &View, theme: &Theme, + cursor_shape_config: &CursorShapeConfig, ) -> Vec<(usize, std::ops::Range<usize>)> { let text = doc.text().slice(..); let selection = doc.selection(view.id); let primary_idx = selection.primary_index(); + let mode = doc.mode(); + let cursorkind = cursor_shape_config.from_mode(mode); + let cursor_is_block = cursorkind == CursorKind::Block; + let selection_scope = theme .find_scope_index("ui.selection") .expect("could not find `ui.selection` scope in the theme!"); @@ -225,13 +231,16 @@ impl EditorView { .find_scope_index("ui.cursor") .unwrap_or(selection_scope); - let cursor_scope = match doc.mode() { + let cursor_scope = match mode { Mode::Insert => theme.find_scope_index("ui.cursor.insert"), Mode::Select => theme.find_scope_index("ui.cursor.select"), Mode::Normal => Some(base_cursor_scope), } .unwrap_or(base_cursor_scope); + let primary_cursor_scope = theme + .find_scope_index("ui.cursor.primary") + .unwrap_or(cursor_scope); let primary_selection_scope = theme .find_scope_index("ui.selection.primary") .unwrap_or(selection_scope); @@ -239,16 +248,20 @@ impl EditorView { let mut spans: Vec<(usize, std::ops::Range<usize>)> = Vec::new(); for (i, range) in selection.iter().enumerate() { let selection_is_primary = i == primary_idx; - let selection_scope = if selection_is_primary { - primary_selection_scope + let (cursor_scope, selection_scope) = if selection_is_primary { + (primary_cursor_scope, primary_selection_scope) } else { - selection_scope + (cursor_scope, selection_scope) }; // Special-case: cursor at end of the rope. if range.head == range.anchor && range.head == text.len_chars() { - if !selection_is_primary { - // Terminal cursor acts as the primary cursor + if !selection_is_primary || cursor_is_block { + // Bar and underline cursors are drawn by the terminal + // BUG: If the editor area loses focus while having a bar or + // underline cursor (eg. when a regex prompt has focus) then + // the primary cursor will be invisible. This doesn't happen + // with block cursors since we manually draw *all* cursors. spans.push((cursor_scope, range.head..range.head + 1)); } continue; @@ -259,13 +272,13 @@ impl EditorView { // Standard case. let cursor_start = prev_grapheme_boundary(text, range.head); spans.push((selection_scope, range.anchor..cursor_start)); - if !selection_is_primary { + if !selection_is_primary || cursor_is_block { spans.push((cursor_scope, cursor_start..range.head)); } } else { // Reverse case. let cursor_end = next_grapheme_boundary(text, range.head); - if !selection_is_primary { + if !selection_is_primary || cursor_is_block { spans.push((cursor_scope, range.head..cursor_end)); } spans.push((selection_scope, cursor_end..range.anchor)); @@ -1140,11 +1153,11 @@ impl Component for EditorView { } fn cursor(&self, _area: Rect, editor: &Editor) -> (Option<Position>, CursorKind) { - // match view.doc.mode() { - // Mode::Insert => write!(stdout, "\x1B[6 q"), - // mode => write!(stdout, "\x1B[2 q"), - // }; - editor.cursor() + match editor.cursor() { + // All block cursors are drawn manually + (pos, CursorKind::Block) => (pos, CursorKind::Hidden), + cursor => cursor, + } } } |