diff src/os_win32.c @ 15852:acd4fc05422b v8.1.0933

patch 8.1.0933: When using VTP scroll region isn't used properly commit https://github.com/vim/vim/commit/6982f42f33b2868e4b9884514cfe8e357b727498 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Feb 16 16:48:01 2019 +0100 patch 8.1.0933: When using VTP scroll region isn't used properly Problem: When using VTP scroll region isn't used properly. Solution: Make better use of the scroll region. (Nobuhiro Takasaki, closes #3974)
author Bram Moolenaar <Bram@vim.org>
date Sat, 16 Feb 2019 17:00:05 +0100
parents cea7a0fde805
children 2ab6321fd355
line wrap: on
line diff
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -171,6 +171,9 @@ static int g_fForceExit = FALSE;    /* s
 static void scroll(unsigned cLines);
 static void set_scroll_region(unsigned left, unsigned top,
 			      unsigned right, unsigned bottom);
+static void set_scroll_region_tb(unsigned top, unsigned bottom);
+static void set_scroll_region_lr(unsigned left, unsigned right);
+static void insert_lines(unsigned cLines);
 static void delete_lines(unsigned cLines);
 static void gotoxy(unsigned x, unsigned y);
 static void standout(void);
@@ -5392,7 +5395,7 @@ create_pipe_pair(HANDLE handles[2])
 
     if (handles[0] == INVALID_HANDLE_VALUE)
     {
-        CloseHandle(handles[1]);
+	CloseHandle(handles[1]);
 	return FALSE;
     }
 
@@ -5976,9 +5979,30 @@ set_scroll_region(
     g_srScrollRegion.Top =    top;
     g_srScrollRegion.Right =  right;
     g_srScrollRegion.Bottom = bottom;
-
-    if (USE_VTP)
-	vtp_printf("\033[%d;%dr", top + 1, bottom + 1);
+}
+
+    static void
+set_scroll_region_tb(
+    unsigned top,
+    unsigned bottom)
+{
+    if (top >= bottom || bottom > (unsigned)Rows - 1)
+	return;
+
+    g_srScrollRegion.Top = top;
+    g_srScrollRegion.Bottom = bottom;
+}
+
+    static void
+set_scroll_region_lr(
+    unsigned left,
+    unsigned right)
+{
+    if (left >= right || right > (unsigned)Columns - 1)
+	return;
+
+    g_srScrollRegion.Left = left;
+    g_srScrollRegion.Right = right;
 }
 
 
@@ -5988,47 +6012,49 @@ set_scroll_region(
     static void
 insert_lines(unsigned cLines)
 {
-    SMALL_RECT	    source;
+    SMALL_RECT	    source, clip;
     COORD	    dest;
     CHAR_INFO	    fill;
 
-    dest.X = 0;
+    dest.X = g_srScrollRegion.Left;
     dest.Y = g_coord.Y + cLines;
 
-    source.Left   = 0;
+    source.Left   = g_srScrollRegion.Left;
     source.Top	  = g_coord.Y;
     source.Right  = g_srScrollRegion.Right;
     source.Bottom = g_srScrollRegion.Bottom - cLines;
 
-    if (!USE_VTP)
+    clip.Left   = g_srScrollRegion.Left;
+    clip.Top    = g_coord.Y;
+    clip.Right  = g_srScrollRegion.Right;
+    clip.Bottom = g_srScrollRegion.Bottom;
+
     {
 	fill.Char.AsciiChar = ' ';
-	fill.Attributes = g_attrCurrent;
-
-	ScrollConsoleScreenBuffer(g_hConOut, &source, NULL, dest, &fill);
-    }
-    else
-    {
+	fill.Attributes = g_attrDefault;
+
 	set_console_color_rgb();
 
-	gotoxy(1, source.Top + 1);
-	vtp_printf("\033[%dT", cLines);
-    }
-
-    /* Here we have to deal with a win32 console flake: If the scroll
-     * region looks like abc and we scroll c to a and fill with d we get
-     * cbd... if we scroll block c one line at a time to a, we get cdd...
-     * vim expects cdd consistently... So we have to deal with that
-     * here... (this also occurs scrolling the same way in the other
-     * direction).  */
+	ScrollConsoleScreenBuffer(g_hConOut, &source, &clip, dest, &fill);
+    }
+    // Here we have to deal with a win32 console flake: If the scroll
+    // region looks like abc and we scroll c to a and fill with d we get
+    // cbd... if we scroll block c one line at a time to a, we get cdd...
+    // vim expects cdd consistently... So we have to deal with that
+    // here... (this also occurs scrolling the same way in the other
+    // direction).
 
     if (source.Bottom < dest.Y)
     {
 	COORD coord;
-
-	coord.X = 0;
-	coord.Y = source.Bottom;
-	clear_chars(coord, Columns * (dest.Y - source.Bottom));
+	int   i;
+
+	coord.X = source.Left;
+	for (i = clip.Top; i < dest.Y; ++i)
+	{
+	    coord.Y = i;
+	    clear_chars(coord, source.Right - source.Left + 1);
+	}
     }
 }
 
@@ -6039,50 +6065,48 @@ insert_lines(unsigned cLines)
     static void
 delete_lines(unsigned cLines)
 {
-    SMALL_RECT	    source;
+    SMALL_RECT	    source, clip;
     COORD	    dest;
     CHAR_INFO	    fill;
     int		    nb;
 
-    dest.X = 0;
+    dest.X = g_srScrollRegion.Left;
     dest.Y = g_coord.Y;
 
-    source.Left   = 0;
+    source.Left   = g_srScrollRegion.Left;
     source.Top	  = g_coord.Y + cLines;
     source.Right  = g_srScrollRegion.Right;
     source.Bottom = g_srScrollRegion.Bottom;
 
-    if (!USE_VTP)
+    clip.Left   = g_srScrollRegion.Left;
+    clip.Top    = g_coord.Y;
+    clip.Right  = g_srScrollRegion.Right;
+    clip.Bottom = g_srScrollRegion.Bottom;
+
     {
 	fill.Char.AsciiChar = ' ';
-	fill.Attributes = g_attrCurrent;
-
-	ScrollConsoleScreenBuffer(g_hConOut, &source, NULL, dest, &fill);
-    }
-    else
-    {
+	fill.Attributes = g_attrDefault;
+
 	set_console_color_rgb();
 
-	gotoxy(1, source.Top + 1);
-	vtp_printf("\033[%dS", cLines);
-    }
-
-    /* Here we have to deal with a win32 console flake: If the scroll
-     * region looks like abc and we scroll c to a and fill with d we get
-     * cbd... if we scroll block c one line at a time to a, we get cdd...
-     * vim expects cdd consistently... So we have to deal with that
-     * here... (this also occurs scrolling the same way in the other
-     * direction).  */
+	ScrollConsoleScreenBuffer(g_hConOut, &source, &clip, dest, &fill);
+    }
+    // Here we have to deal with a win32 console flake; See insert_lines()
+    // above.
 
     nb = dest.Y + (source.Bottom - source.Top) + 1;
 
     if (nb < source.Top)
     {
 	COORD coord;
-
-	coord.X = 0;
-	coord.Y = nb;
-	clear_chars(coord, Columns * (source.Top - nb));
+	int   i;
+
+	coord.X = source.Left;
+	for (i = nb; i < clip.Bottom; ++i)
+	{
+	    coord.Y = i;
+	    clear_chars(coord, source.Right - source.Left + 1);
+	}
     }
 }
 
@@ -6508,6 +6532,14 @@ mch_write(
 		{
 		    set_scroll_region(0, arg1 - 1, Columns - 1, arg2 - 1);
 		}
+		else if (argc == 2 && *p == 'R')
+		{
+		    set_scroll_region_tb(arg1, arg2);
+		}
+		else if (argc == 2 && *p == 'V')
+		{
+		    set_scroll_region_lr(arg1, arg2);
+		}
 		else if (argc == 1 && *p == 'A')
 		{
 		    gotoxy(g_coord.X + 1,