@@ -106,6 +106,7 @@ struct terminal_S {
106106 int tl_dirty_row_end ; /* row below last one to update */
107107
108108 pos_T tl_cursor ;
109+ int tl_cursor_visible ;
109110};
110111
111112/*
@@ -176,6 +177,7 @@ ex_terminal(exarg_T *eap)
176177 if (term == NULL )
177178 return ;
178179 term -> tl_dirty_row_end = MAX_ROW ;
180+ term -> tl_cursor_visible = TRUE;
179181
180182 /* Open a new window or tab. */
181183 vim_memset (& split_ea , 0 , sizeof (split_ea ));
@@ -316,15 +318,18 @@ term_write_job_output(term_T *term, char_u *msg, size_t len)
316318}
317319
318320 static void
319- update_cursor ()
321+ update_cursor (term_T * term , int redraw )
320322{
321323 /* TODO: this should not always be needed */
322324 setcursor ();
323- out_flush ();
325+ if (redraw && term -> tl_buffer == curbuf && term -> tl_cursor_visible )
326+ {
327+ out_flush ();
324328#ifdef FEAT_GUI
325- if (gui .in_use )
326- gui_update_cursor (FALSE, FALSE);
329+ if (gui .in_use )
330+ gui_update_cursor (FALSE, FALSE);
327331#endif
332+ }
328333}
329334
330335/*
@@ -342,7 +347,7 @@ write_to_term(buf_T *buffer, char_u *msg, channel_T *channel)
342347
343348 /* TODO: only update once in a while. */
344349 update_screen (0 );
345- update_cursor ();
350+ update_cursor (term , TRUE );
346351}
347352
348353/*
@@ -473,7 +478,7 @@ terminal_loop(void)
473478 {
474479 /* TODO: skip screen update when handling a sequence of keys. */
475480 update_screen (0 );
476- update_cursor ();
481+ update_cursor (curbuf -> b_term , FALSE );
477482 ++ no_mapping ;
478483 ++ allow_keys ;
479484 got_int = FALSE;
@@ -559,12 +564,13 @@ term_job_ended(job_T *job)
559564 did_one = TRUE;
560565 }
561566 if (did_one )
562- {
563567 redraw_statuslines ();
564- update_cursor ();
568+ if (curbuf -> b_term != NULL )
569+ {
570+ if (curbuf -> b_term -> tl_job == job )
571+ maketitle ();
572+ update_cursor (curbuf -> b_term , TRUE);
565573 }
566- if (curbuf -> b_term != NULL && curbuf -> b_term -> tl_job == job )
567- maketitle ();
568574}
569575
570576/*
@@ -583,6 +589,18 @@ position_cursor(win_T *wp, VTermPos *pos)
583589 wp -> w_wcol = MIN (pos -> col , MAX (0 , wp -> w_width - 1 ));
584590}
585591
592+ static void
593+ may_toggle_cursor (term_T * term )
594+ {
595+ if (curbuf == term -> tl_buffer )
596+ {
597+ if (term -> tl_cursor_visible )
598+ cursor_on ();
599+ else
600+ cursor_off ();
601+ }
602+ }
603+
586604 static int
587605handle_damage (VTermRect rect , void * user )
588606{
@@ -608,7 +626,7 @@ handle_moverect(VTermRect dest UNUSED, VTermRect src UNUSED, void *user)
608626handle_movecursor (
609627 VTermPos pos ,
610628 VTermPos oldpos UNUSED ,
611- int visible UNUSED ,
629+ int visible ,
612630 void * user )
613631{
614632 term_T * term = (term_T * )user ;
@@ -625,8 +643,12 @@ handle_movecursor(
625643 }
626644 }
627645
646+ term -> tl_cursor_visible = visible ;
628647 if (is_current )
629- update_cursor ();
648+ {
649+ may_toggle_cursor (term );
650+ update_cursor (term , TRUE);
651+ }
630652
631653 return 1 ;
632654}
@@ -648,11 +670,19 @@ handle_settermprop(
648670 term -> tl_status_text = NULL ;
649671 if (term == curbuf -> b_term )
650672 maketitle ();
651- return 1 ;
673+ break ;
674+
675+ case VTERM_PROP_CURSORVISIBLE :
676+ term -> tl_cursor_visible = value -> boolean ;
677+ may_toggle_cursor (term );
678+ out_flush ();
679+ break ;
680+
652681 default :
653682 break ;
654683 }
655- return 0 ;
684+ /* Always return 1, otherwise vterm doesn't store the value internally. */
685+ return 1 ;
656686}
657687
658688/*
0 commit comments