@@ -25,7 +25,7 @@ use helix_core::{
2525use helix_view:: {
2626 annotations:: diagnostics:: DiagnosticFilter ,
2727 document:: { Mode , SCRATCH_BUFFER_NAME } ,
28- editor:: { CompleteAction , CursorShapeConfig } ,
28+ editor:: CompleteAction ,
2929 graphics:: { Color , CursorKind , Modifier , Rect , Style } ,
3030 input:: { KeyEvent , MouseButton , MouseEvent , MouseEventKind } ,
3131 keyboard:: { KeyCode , KeyModifiers } ,
@@ -146,11 +146,10 @@ impl EditorView {
146146 overlays. push ( tabstops) ;
147147 }
148148 overlays. push ( Self :: doc_selection_highlights (
149- editor. mode ( ) ,
149+ editor,
150150 doc,
151151 view,
152152 theme,
153- & config. cursor_shape ,
154153 self . terminal_focused ,
155154 ) ) ;
156155 if let Some ( overlay) = Self :: highlight_focused_view_elements ( view, doc, theme) {
@@ -461,20 +460,24 @@ impl EditorView {
461460
462461 /// Get highlight spans for selections in a document view.
463462 pub fn doc_selection_highlights (
464- mode : Mode ,
463+ editor : & Editor ,
465464 doc : & Document ,
466465 view : & View ,
467466 theme : & Theme ,
468- cursor_shape_config : & CursorShapeConfig ,
469467 is_terminal_focused : bool ,
470468 ) -> OverlayHighlights {
471469 let text = doc. text ( ) . slice ( ..) ;
472470 let selection = doc. selection ( view. id ) ;
473471 let primary_idx = selection. primary_index ( ) ;
474472
473+ let mode = editor. mode ( ) ;
474+ let cursor_shape_config = & editor. config ( ) . cursor_shape ;
475475 let cursorkind = cursor_shape_config. from_mode ( mode) ;
476476 let cursor_is_block = cursorkind == CursorKind :: Block ;
477477
478+ // Skip rendering secondary cursors when kitty protocol handles them
479+ let skip_secondary_cursors = editor. kitty_multi_cursor_support && !cursor_is_block;
480+
478481 let selection_scope = theme
479482 . find_highlight_exact ( "ui.selection" )
480483 . expect ( "could not find `ui.selection` scope in the theme!" ) ;
@@ -514,13 +517,10 @@ impl EditorView {
514517
515518 // Special-case: cursor at end of the rope.
516519 if range. head == range. anchor && range. head == text. len_chars ( ) {
517- if !selection_is_primary || ( cursor_is_block && is_terminal_focused) {
518- // Bar and underline cursors are drawn by the terminal
519- // BUG: If the editor area loses focus while having a bar or
520- // underline cursor (eg. when a regex prompt has focus) then
521- // the primary cursor will be invisible. This doesn't happen
522- // with block cursors since we manually draw *all* cursors.
523- spans. push ( ( cursor_scope, range. head ..range. head + 1 ) ) ;
520+ if selection_is_primary || !skip_secondary_cursors {
521+ if !selection_is_primary || ( cursor_is_block && is_terminal_focused) {
522+ spans. push ( ( cursor_scope, range. head ..range. head + 1 ) ) ;
523+ }
524524 }
525525 continue ;
526526 }
@@ -537,17 +537,17 @@ impl EditorView {
537537 cursor_start
538538 } ;
539539 spans. push ( ( selection_scope, range. anchor ..selection_end) ) ;
540- // add block cursors
541- // skip primary cursor if terminal is unfocused - terminal cursor is used in that case
542- if !selection_is_primary || ( cursor_is_block && is_terminal_focused ) {
540+ if ( selection_is_primary || !skip_secondary_cursors )
541+ && ( !selection_is_primary || ( cursor_is_block && is_terminal_focused ) )
542+ {
543543 spans. push ( ( cursor_scope, cursor_start..range. head ) ) ;
544544 }
545545 } else {
546546 // Reverse case.
547547 let cursor_end = next_grapheme_boundary ( text, range. head ) ;
548- // add block cursors
549- // skip primary cursor if terminal is unfocused - terminal cursor is used in that case
550- if !selection_is_primary || ( cursor_is_block && is_terminal_focused ) {
548+ if ( selection_is_primary || !skip_secondary_cursors )
549+ && ( !selection_is_primary || ( cursor_is_block && is_terminal_focused ) )
550+ {
551551 spans. push ( ( cursor_scope, range. head ..cursor_end) ) ;
552552 }
553553 // non block cursors look like they exclude the cursor
0 commit comments