From 0d9e95c2dbc422ffa3db10132db3154357c461be Mon Sep 17 00:00:00 2001
From: Ron Yorston <rmy@pobox.com>
Date: Tue, 26 Apr 2016 16:40:18 +0100
Subject: winansi: speed up clearing of screen

Various tasks on the shell command line (e.g. backspace, DEL,
reverse search) were found to be slow when the console screen
buffer was very large.  This was because the entire buffer was
being cleared in erase_till_end_of_screen().

Rewrite erase_till_end_of_screen() to only clear to the end of the
visible screen and to be tidier.  (Based on a suggestion by GitHub
user avih.)

Also, modify move_cursor to use coordinates relative to the current
display (as ANSI escapes expect) rather than relative to the screen
buffer.
---
 win32/winansi.c | 25 ++++++++++---------------
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/win32/winansi.c b/win32/winansi.c
index 0a637670c..5d4adbec8 100644
--- a/win32/winansi.c
+++ b/win32/winansi.c
@@ -109,27 +109,20 @@ static void erase_in_line(void)
 static void erase_till_end_of_screen(void)
 {
 	CONSOLE_SCREEN_BUFFER_INFO sbi;
-	COORD pos;
-	DWORD dummy;
+	DWORD dummy, len;
 
 	if (!console)
 		return;
 
 	GetConsoleScreenBufferInfo(console, &sbi);
-	FillConsoleOutputCharacterA(console, ' ',
-		sbi.dwSize.X - sbi.dwCursorPosition.X, sbi.dwCursorPosition,
+	len = sbi.dwSize.X - sbi.dwCursorPosition.X +
+			sbi.dwSize.X * (sbi.srWindow.Bottom - sbi.dwCursorPosition.Y);
+
+	FillConsoleOutputCharacterA(console, ' ', len, sbi.dwCursorPosition,
 		&dummy);
-	FillConsoleOutputAttribute(console, plain_attr,
-		sbi.dwSize.X - sbi.dwCursorPosition.X, sbi.dwCursorPosition,
+	FillConsoleOutputAttribute(console, plain_attr, len, sbi.dwCursorPosition,
 		&dummy);
 
-	pos.X = 0;
-	for (pos.Y = sbi.dwCursorPosition.Y+1; pos.Y < sbi.dwSize.Y; pos.Y++) {
-		FillConsoleOutputCharacterA(console, ' ', sbi.dwSize.X,
-					    pos, &dummy);
-		FillConsoleOutputAttribute(console, plain_attr, sbi.dwSize.X,
-					    pos, &dummy);
-	}
 }
 
 static void move_cursor_row(int n)
@@ -159,12 +152,14 @@ static void move_cursor_column(int n)
 static void move_cursor(int x, int y)
 {
 	COORD pos;
+	CONSOLE_SCREEN_BUFFER_INFO sbi;
 
 	if (!console)
 		return;
 
-	pos.X = x;
-	pos.Y = y;
+	GetConsoleScreenBufferInfo(console, &sbi);
+	pos.X = sbi.srWindow.Left + x;
+	pos.Y = sbi.srWindow.Top + y;
 	SetConsoleCursorPosition(console, pos);
 }
 
-- 
cgit v1.2.3-55-g6feb