]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1772: Cursor may be adjusted in 'splitkeep'ed windows v9.0.1772
authorLuuk van Baal <luukvbaal@gmail.com>
Sun, 20 Aug 2023 18:44:59 +0000 (20:44 +0200)
committerChristian Brabandt <cb@256bit.org>
Sun, 20 Aug 2023 18:44:59 +0000 (20:44 +0200)
Problem:    Cursor is adjusted in window that did not change in size by
            'splitkeep'.
Solution:   Only check that cursor position is valid in a window that
            has changed in size.

closes: #12509

Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Luuk van Baal <luukvbaal@gmail.com>
src/structs.h
src/testdir/dumps/Test_splitkeep_cursor_1.dump [new file with mode: 0644]
src/testdir/dumps/Test_splitkeep_cursor_2.dump [new file with mode: 0644]
src/testdir/dumps/Test_splitkeep_cursor_3.dump [new file with mode: 0644]
src/testdir/test_window_cmd.vim
src/version.c
src/window.c

index eefc8f21867fb53d2171fdfbbd64106130ad092d..eb8d30b23e9385380242baad0cab9107483f5261 100644 (file)
@@ -3778,6 +3778,7 @@ struct window_S
     int                w_vsep_width;       // Number of separator columns (0 or 1).
 
     pos_save_T w_save_cursor;      // backup of cursor pos and topline
+    int                w_do_win_fix_cursor;// if TRUE cursor may be invalid
 
 #ifdef FEAT_PROP_POPUP
     int                w_popup_flags;      // POPF_ values
diff --git a/src/testdir/dumps/Test_splitkeep_cursor_1.dump b/src/testdir/dumps/Test_splitkeep_cursor_1.dump
new file mode 100644 (file)
index 0000000..3b30e82
--- /dev/null
@@ -0,0 +1,8 @@
+|9+0&#ffffff0@1| @72
+>1|0@1| @71
+|1|0|1| @71
+|[+3&&|N|o| |N|a|m|e|]| |[|+|]| @43|1|0@1|,|1| @9|4|9|%
+|5+0&&| @73
+|6| @73
+|[+1&&|N|o| |N|a|m|e|]| |[|+|]| @43|5|,|1| @12|2|%
+| +0&&@74
diff --git a/src/testdir/dumps/Test_splitkeep_cursor_2.dump b/src/testdir/dumps/Test_splitkeep_cursor_2.dump
new file mode 100644 (file)
index 0000000..bff6940
--- /dev/null
@@ -0,0 +1,8 @@
+|1+0&#ffffff0|0@1| @71
+>1|0|1| @71
+|1|0|2| @71
+|[+3&&|N|o| |N|a|m|e|]| |[|+|]| @43|1|0|1|,|1| @9|5|0|%
+|5+0&&| @73
+|6| @73
+|[+1&&|N|o| |N|a|m|e|]| |[|+|]| @43|5|,|1| @12|2|%
+| +0&&@74
diff --git a/src/testdir/dumps/Test_splitkeep_cursor_3.dump b/src/testdir/dumps/Test_splitkeep_cursor_3.dump
new file mode 100644 (file)
index 0000000..979cd00
--- /dev/null
@@ -0,0 +1,8 @@
+|1+0&#ffffff0|9|8| @71
+|1|9@1| @71
+>2|0@1| @71
+|[+3&&|N|o| |N|a|m|e|]| |[|+|]| @43|2|0@1|,|1| @9|B|o|t
+|5+0&&| @73
+|6| @73
+|[+1&&|N|o| |N|a|m|e|]| |[|+|]| @43|5|,|1| @12|2|%
+|:+0&&|s|e|t| |s|c|r|o|l@1|o|f@1|=|0| @58
index 03c51e845ab179511019a916880bc979a0ad3d9a..818fef03946849ee428a2750ce04847674fdc552 100644 (file)
@@ -1861,6 +1861,33 @@ func Test_splitkeep_misc()
   set splitkeep&
 endfunc
 
+func Test_splitkeep_cursor()
+  CheckScreendump
+  let lines =<< trim END
+    set splitkeep=screen
+    autocmd CursorMoved * wincmd p | wincmd p
+    call setline(1, range(1, 200))
+    func CursorEqualize()
+      call cursor(100, 1)
+      wincmd =
+    endfunc
+    wincmd s
+    call CursorEqualize()
+  END
+  call writefile(lines, 'XTestSplitkeepCallback', 'D')
+  let buf = RunVimInTerminal('-S XTestSplitkeepCallback', #{rows: 8})
+
+  call VerifyScreenDump(buf, 'Test_splitkeep_cursor_1', {})
+
+  call term_sendkeys(buf, "j")
+  call VerifyScreenDump(buf, 'Test_splitkeep_cursor_2', {})
+
+  call term_sendkeys(buf, ":set scrolloff=0\<CR>G")
+  call VerifyScreenDump(buf, 'Test_splitkeep_cursor_3', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
 func Test_splitkeep_callback()
   CheckScreendump
   let lines =<< trim END
index cda23f7925f694b90fd3baac6da442e768138af9..13d27f4afd7ebc918d6e559bde45389a3f068c06 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1772,
 /**/
     1771,
 /**/
index 833ee561408493daa254f557345e4908f77c4d75..152365e7d93e2a1eb2b87d247f292e4e138c4e38 100644 (file)
@@ -6789,6 +6789,10 @@ win_fix_scroll(int resize)
        // Skip when window height has not changed.
        if (wp->w_height != wp->w_prev_height)
        {
+           // Cursor position in this window may now be invalid.  It is kept
+           // potentially invalid until the window is made the current window.
+           wp->w_do_win_fix_cursor = TRUE;
+
            // If window has moved update botline to keep the same screenlines.
            if (*p_spk == 's' && wp->w_winrow != wp->w_prev_winrow
                      && wp->w_botline - 1 <= wp->w_buffer->b_ml.ml_line_count)
@@ -6813,6 +6817,7 @@ win_fix_scroll(int resize)
            }
            else if (wp == curwin)
                wp->w_valid &= ~VALID_CROW;
+
            invalidate_botline_win(wp);
            validate_botline_win(wp);
        }
@@ -6830,7 +6835,7 @@ win_fix_scroll(int resize)
 /*
  * Make sure the cursor position is valid for 'splitkeep'.
  * If it is not, put the cursor position in the jumplist and move it.
- * If we are not in normal mode ("normal" is zero), make it valid by scrolling
+ * If we are not in normal mode ("normal" is FALSE), make it valid by scrolling
  * instead.
  */
     static void
@@ -6838,9 +6843,12 @@ win_fix_cursor(int normal)
 {
     win_T      *wp = curwin;
 
-    if (skip_win_fix_cursor || wp->w_buffer->b_ml.ml_line_count < wp->w_height)
+    if (skip_win_fix_cursor
+           || !wp->w_do_win_fix_cursor
+           || wp->w_buffer->b_ml.ml_line_count < wp->w_height)
        return;
 
+    wp->w_do_win_fix_cursor = FALSE;
     // Determine valid cursor range.
     long so = MIN(wp->w_height / 2, get_scrolloff_value());
     linenr_T lnum = wp->w_cursor.lnum;
@@ -6873,7 +6881,7 @@ win_fix_cursor(int normal)
        {
            wp->w_fraction = (nlnum == bot) ? FRACTION_MULT : 0;
            scroll_to_fraction(wp, wp->w_prev_height);
-           validate_botline_win(curwin);
+           validate_botline();
        }
     }
 }