patch 9.1.0280: several issues with 'smoothscroll' support

Problem:  Logic to make sure cursor is in visible part of the screen after
          scrolling the text with 'smoothscroll' is scattered, asymmetric
          and contains bugs.
Solution: Adjust and create helper function for 'smoothscroll' cursor logic.
          (Luuk van Baal)

closes: #14410

Signed-off-by: Luuk van Baal <luukvbaal@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/testdir/dumps/Test_smooth_long_6.dump b/src/testdir/dumps/Test_smooth_long_6.dump
index ba48c28..507aa46 100644
--- a/src/testdir/dumps/Test_smooth_long_6.dump
+++ b/src/testdir/dumps/Test_smooth_long_6.dump
@@ -3,4 +3,4 @@
 |t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o
 |f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e
 |x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w
-| @21|3|,|9|0| @9|6@1|%| 
+|:|s|e|t| |s|c|r|o|l@1|o| @9|3|,|9|0| @9|6@1|%| 
diff --git a/src/testdir/dumps/Test_smooth_long_7.dump b/src/testdir/dumps/Test_smooth_long_7.dump
index 222e001..225207f 100644
--- a/src/testdir/dumps/Test_smooth_long_7.dump
+++ b/src/testdir/dumps/Test_smooth_long_7.dump
@@ -3,4 +3,4 @@
 |t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o
 |f| |t|e|x|t| |w|i>t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e
 |x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w
-| @21|3|,|1|7|0| @8|6@1|%| 
+|:|s|e|t| |s|c|r|o|l@1|o| @9|3|,|1|7|0| @8|6@1|%| 
diff --git a/src/testdir/test_diffmode.vim b/src/testdir/test_diffmode.vim
index b8d0057..9e973de 100644
--- a/src/testdir/test_diffmode.vim
+++ b/src/testdir/test_diffmode.vim
Binary files differ
diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim
index 294da0d..e09c240 100644
--- a/src/testdir/test_scroll_opt.vim
+++ b/src/testdir/test_scroll_opt.vim
@@ -1020,30 +1020,36 @@
   " Half-page scrolling does not go beyond end of buffer and moves the cursor.
   " Even with 'nostartofline', the correct amount of lines is scrolled.
   setl nostartofline
-  exe "norm! 0\<C-D>"
+  exe "norm! 15|\<C-D>"
   call assert_equal(200, winsaveview().skipcol)
-  call assert_equal(204, col('.'))
+  call assert_equal(215, col('.'))
   exe "norm! \<C-D>"
   call assert_equal(400, winsaveview().skipcol)
-  call assert_equal(404, col('.'))
+  call assert_equal(415, col('.'))
   exe "norm! \<C-D>"
   call assert_equal(520, winsaveview().skipcol)
-  call assert_equal(601, col('.'))
+  call assert_equal(535, col('.'))
   exe "norm! \<C-D>"
   call assert_equal(520, winsaveview().skipcol)
-  call assert_equal(801, col('.'))
-  exe "norm! \<C-U>"
+  call assert_equal(735, col('.'))
+  exe "norm! \<C-D>"
   call assert_equal(520, winsaveview().skipcol)
-  call assert_equal(601, col('.'))
+  call assert_equal(895, col('.'))
   exe "norm! \<C-U>"
-  call assert_equal(400, winsaveview().skipcol)
-  call assert_equal(404, col('.'))
+  call assert_equal(320, winsaveview().skipcol)
+  call assert_equal(695, col('.'))
   exe "norm! \<C-U>"
-  call assert_equal(200, winsaveview().skipcol)
-  call assert_equal(204, col('.'))
+  call assert_equal(120, winsaveview().skipcol)
+  call assert_equal(495, col('.'))
   exe "norm! \<C-U>"
   call assert_equal(0, winsaveview().skipcol)
-  call assert_equal(40, col('.'))
+  call assert_equal(375, col('.'))
+  exe "norm! \<C-U>"
+  call assert_equal(0, winsaveview().skipcol)
+  call assert_equal(175, col('.'))
+  exe "norm! \<C-U>"
+  call assert_equal(0, winsaveview().skipcol)
+  call assert_equal(15, col('.'))
 
   bwipe!
 endfunc
@@ -1071,6 +1077,14 @@
   redraw
   call assert_equal(2, line('w0'))
 
+  " Cursor does not end up above topline, adjusting topline later.
+  setlocal nu cpo+=n
+  exe "norm! G$g013\<C-Y>"
+  redraw
+  call assert_equal(2, line('.'))
+  call assert_equal(0, winsaveview().skipcol)
+
+  set cpo-=n
   bwipe!
 endfunc