mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
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)
This commit is contained in:
122
src/os_win32.c
122
src/os_win32.c
@@ -171,6 +171,9 @@ static int g_fForceExit = FALSE; /* set when forcefully exiting */
|
||||
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;
|
||||
fill.Attributes = g_attrDefault;
|
||||
|
||||
ScrollConsoleScreenBuffer(g_hConOut, &source, NULL, dest, &fill);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_console_color_rgb();
|
||||
|
||||
gotoxy(1, source.Top + 1);
|
||||
vtp_printf("\033[%dT", cLines);
|
||||
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). */
|
||||
// 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;
|
||||
int i;
|
||||
|
||||
coord.X = 0;
|
||||
coord.Y = source.Bottom;
|
||||
clear_chars(coord, Columns * (dest.Y - source.Bottom));
|
||||
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;
|
||||
fill.Attributes = g_attrDefault;
|
||||
|
||||
ScrollConsoleScreenBuffer(g_hConOut, &source, NULL, dest, &fill);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_console_color_rgb();
|
||||
|
||||
gotoxy(1, source.Top + 1);
|
||||
vtp_printf("\033[%dS", cLines);
|
||||
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). */
|
||||
// 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;
|
||||
int i;
|
||||
|
||||
coord.X = 0;
|
||||
coord.Y = nb;
|
||||
clear_chars(coord, Columns * (source.Top - nb));
|
||||
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,
|
||||
|
Reference in New Issue
Block a user