changeset 28133:373f1afadfa3 v8.2.4591

patch 8.2.4591: cursor line not updated when a callback moves the cursor Commit: https://github.com/vim/vim/commit/e7a74d53754765f22ef8ce71c915bb669d5f7f3f Author: Bram Moolenaar <Bram@vim.org> Date: Sat Mar 19 11:10:15 2022 +0000 patch 8.2.4591: cursor line not updated when a callback moves the cursor Problem: Cursor line not updated when a callback moves the cursor. Solution: Check if the cursor moved. (closes https://github.com/vim/vim/issues/9970)
author Bram Moolenaar <Bram@vim.org>
date Sat, 19 Mar 2022 12:15:04 +0100
parents a4c48c2beb9f
children 0ff3b213d70f
files src/drawscreen.c src/main.c src/proto/drawscreen.pro src/testdir/dumps/Test_cursorline_callback_1.dump src/testdir/test_cursorline.vim src/version.c
diffstat 6 files changed, 66 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/drawscreen.c
+++ b/src/drawscreen.c
@@ -1463,11 +1463,14 @@ win_update(win_T *wp)
 #ifdef FEAT_SYN_HL
     // remember what happened to the previous line, to know if
     // check_visual_highlight() can be used
-#define DID_NONE 1	// didn't update a line
-#define DID_LINE 2	// updated a normal line
-#define DID_FOLD 3	// updated a folded line
+# define DID_NONE 1	// didn't update a line
+# define DID_LINE 2	// updated a normal line
+# define DID_FOLD 3	// updated a folded line
     int		did_update = DID_NONE;
     linenr_T	syntax_last_parsed = 0;		// last parsed text line
+    // remember the current w_last_cursorline, it changes when drawing the new
+    // cursor line
+    linenr_T	last_cursorline = wp->w_last_cursorline;
 #endif
     linenr_T	mod_top = 0;
     linenr_T	mod_bot = 0;
@@ -2244,7 +2247,7 @@ win_update(win_T *wp)
 				))))
 #ifdef FEAT_SYN_HL
 		|| (wp->w_p_cul && (lnum == wp->w_cursor.lnum
-					     || lnum == wp->w_last_cursorline))
+						   || lnum == last_cursorline))
 #endif
 				)
 	{
@@ -3027,6 +3030,23 @@ redraw_asap(int type)
 }
 #endif
 
+#if defined(FEAT_SYN_HL) || defined(PROTO)
+/*
+ * Check if the cursor moved and 'cursorline' is set.  Mark for a VALID redraw
+ * if needed.
+ */
+    void
+check_redraw_cursorline(void)
+{
+    // When 'cursorlineopt' is "screenline" need to redraw always.
+    if (curwin->w_p_cul
+	    && (curwin->w_last_cursorline != curwin->w_cursor.lnum
+		|| (curwin->w_p_culopt_flags & CULOPT_SCRLINE))
+	    && !char_avail())
+	redraw_later(VALID);
+}
+#endif
+
 /*
  * Invoked after an asynchronous callback is called.
  * If an echo command was used the cursor needs to be put back where
@@ -3071,6 +3091,10 @@ redraw_after_callback(int call_update_sc
     }
     else if (State & (NORMAL | INSERT | TERMINAL))
     {
+#ifdef FEAT_SYN_HL
+	// might need to update for 'cursorline'
+	check_redraw_cursorline();
+#endif
 	// keep the command line if possible
 	update_screen(VALID_NO_UPDATE);
 	setcursor();
--- a/src/main.c
+++ b/src/main.c
@@ -1386,12 +1386,7 @@ main_loop(
 
 #ifdef FEAT_SYN_HL
 	    // Might need to update for 'cursorline'.
-	    // When 'cursorlineopt' is "screenline" need to redraw always.
-	    if (curwin->w_p_cul
-		    && (curwin->w_last_cursorline != curwin->w_cursor.lnum
-			|| (curwin->w_p_culopt_flags & CULOPT_SCRLINE))
-		    && !char_avail())
-		redraw_later(VALID);
+	    check_redraw_cursorline();
 #endif
 	    if (VIsual_active)
 		update_curbuf(INVERTED); // update inverted part
--- a/src/proto/drawscreen.pro
+++ b/src/proto/drawscreen.pro
@@ -8,6 +8,7 @@ void update_curbuf(int type);
 void update_debug_sign(buf_T *buf, linenr_T lnum);
 void updateWindow(win_T *wp);
 int redraw_asap(int type);
+void check_redraw_cursorline(void);
 void redraw_after_callback(int call_update_screen, int do_message);
 void redraw_later(int type);
 void redraw_win_later(win_T *wp, int type);
new file mode 100644
--- /dev/null
+++ b/src/testdir/dumps/Test_cursorline_callback_1.dump
@@ -0,0 +1,8 @@
+|a+0&#ffffff0@4| @69
+>b+8&&@4| @69
+|c+0&&@4| @69
+|d@4| @69
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|4|,|1| @10|A|l@1| 
--- a/src/testdir/test_cursorline.vim
+++ b/src/testdir/test_cursorline.vim
@@ -247,4 +247,30 @@ END
   call delete('Xtextfile')
 endfunc
 
+func Test_cursorline_callback()
+  CheckScreendump
+  CheckFeature timers
+
+  let lines =<< trim END
+      call setline(1, ['aaaaa', 'bbbbb', 'ccccc', 'ddddd'])
+      set cursorline
+      call cursor(4, 1)
+
+      func Func(timer)
+        call cursor(2, 1)
+      endfunc
+
+      call timer_start(300, 'Func')
+  END
+  call writefile(lines, 'Xcul_timer')
+
+  let buf = RunVimInTerminal('-S Xcul_timer', #{rows: 8})
+  call TermWait(buf, 310)
+  call VerifyScreenDump(buf, 'Test_cursorline_callback_1', {})
+
+  call StopVimInTerminal(buf)
+  call delete('Xcul_timer')
+endfunc
+
+
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4591,
+/**/
     4590,
 /**/
     4589,