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