patch 9.1.1885: Wrong restored cursor pos when re-entering buffer after changes

Commit: 
https://github.com/vim/vim/commit/b2e6b328dafe1cdfff10f1e811355e514da8071d
Author: zeertzjq <[email protected]>
Date:   Tue Oct 28 20:27:19 2025 +0000

    patch 9.1.1885: Wrong restored cursor pos when re-entering buffer after 
changes
    
    Problem:  Wrong restored cursor position when re-entering a buffer
              previously viewed in a window after making changes to the same
              buffer in another window.
    Solution: Adjust per-window "last cursor" positions on buffer changes.
              (zeertzjq)
    
    closes: #18655
    
    Signed-off-by: zeertzjq <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/mark.c b/src/mark.c
index 33cd55fea..c872e2f0f 100644
--- a/src/mark.c
+++ b/src/mark.c
@@ -1031,6 +1031,25 @@ ex_changes(exarg_T *eap UNUSED)
            *lp += amount_after; \
     }
 
+// Like one_adjust_nodel(), but if the position is within the deleted range,
+// move it to the start of the line before the range.
+#define one_adjust_cursor(pp) \
+    { \
+       pos_T *posp = pp; \
+       if (posp->lnum >= line1 && posp->lnum <= line2) \
+       { \
+           if (amount == MAXLNUM) /* line with cursor is deleted */ \
+           { \
+               posp->lnum = MAX(line1 - 1, 1); \
+               posp->col = 0; \
+           } \
+           else /* keep cursor on the same line */ \
+               posp->lnum += amount; \
+       } \
+       else if (amount_after && posp->lnum > line2) \
+           posp->lnum += amount_after; \
+    }
+
 /*
  * Adjust marks between "line1" and "line2" (inclusive) to move "amount" lines.
  * Must be called before changed_*(), appended_lines() or deleted_lines().
@@ -1075,6 +1094,7 @@ mark_adjust_internal(
     linenr_T   *lp;
     win_T      *win;
     tabpage_T  *tab;
+    wininfo_T  *wip;
     static pos_T initpos = {1, 0, 0};
 
     if (line2 < line1 && amount_after == 0L)       // nothing to do
@@ -1192,21 +1212,7 @@ mark_adjust_internal(
                    win->w_topfill = 0;
 #endif
                }
-               if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2)
-               {
-                   if (amount == MAXLNUM) // line with cursor is deleted
-                   {
-                       if (line1 <= 1)
-                           win->w_cursor.lnum = 1;
-                       else
-                           win->w_cursor.lnum = line1 - 1;
-                       win->w_cursor.col = 0;
-                   }
-                   else                // keep cursor on the same line
-                       win->w_cursor.lnum += amount;
-               }
-               else if (amount_after && win->w_cursor.lnum > line2)
-                   win->w_cursor.lnum += amount_after;
+               one_adjust_cursor(&(win->w_cursor));
            }
 
 #ifdef FEAT_FOLDING
@@ -1221,6 +1227,10 @@ mark_adjust_internal(
     // adjust diffs
     diff_mark_adjust(line1, line2, amount, amount_after);
 #endif
+
+    // adjust per-window "last cursor" positions
+    FOR_ALL_BUF_WININFO(curbuf, wip)
+       one_adjust_cursor(&(wip->wi_fpos));
 }
 
 // This code is used often, needs to be fast.
diff --git a/src/testdir/test_buffer.vim b/src/testdir/test_buffer.vim
index 90b7a9aa4..1ffa7ae87 100644
--- a/src/testdir/test_buffer.vim
+++ b/src/testdir/test_buffer.vim
@@ -623,17 +623,48 @@ func Test_switch_to_previously_viewed_buffer()
   vsplit
 
   call cursor(100, 3)
+  call assert_equal('100', getline('.'))
   edit Xotherbuf
   buffer Xviewbuf
   call assert_equal([0, 100, 3, 0], getpos('.'))
+  call assert_equal('100', getline('.'))
 
+  edit Xotherbuf
+  wincmd p
+  normal! gg10dd
+  wincmd p
+  buffer Xviewbuf
+  call assert_equal([0, 90, 3, 0], getpos('.'))
+  call assert_equal('100', getline('.'))
+
+  edit Xotherbuf
+  wincmd p
+  normal! ggP
+  wincmd p
+  buffer Xviewbuf
+  call assert_equal([0, 100, 3, 0], getpos('.'))
+  call assert_equal('100', getline('.'))
+
+  edit Xotherbuf
+  wincmd p
+  normal! 96gg10ddgg
+  wincmd p
+  buffer Xviewbuf
+  " The original cursor line was deleted, so cursor is restored to the start
+  " of the line before the deleted range.
+  call assert_equal([0, 95, 1, 0], getpos('.'))
+  call assert_equal('95', getline('.'))
+
+  normal! u
   exe win_id2win(oldwin) .. 'close'
   setlocal bufhidden=hide
 
   call cursor(200, 3)
+  call assert_equal('200', getline('.'))
   edit Xotherbuf
   buffer Xviewbuf
   call assert_equal([0, 200, 3, 0], getpos('.'))
+  call assert_equal('200', getline('.'))
 
   bwipe! Xotherbuf
   bwipe! Xviewbuf
diff --git a/src/version.c b/src/version.c
index e225e9439..7b814f726 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1885,
 /**/
     1884,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1vDqKU-008NJH-6Q%40256bit.org.

Raspunde prin e-mail lui