From 5531e51fe26e4c6bbd34dbaa98b12564f8a7f295 Mon Sep 17 00:00:00 2001
From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date: Tue, 14 Sep 2010 16:32:36 +1000
Subject: win32: winansi: implement \033[J

---
 win32/winansi.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/win32/winansi.c b/win32/winansi.c
index e2e7010fb..51bfad67c 100644
--- a/win32/winansi.c
+++ b/win32/winansi.c
@@ -91,6 +91,24 @@ static void erase_in_line(void)
 		NULL);
 }
 
+static void erase_till_end_of_screen(void)
+{
+	CONSOLE_SCREEN_BUFFER_INFO sbi;
+	COORD pos;
+
+	if (!console)
+		return;
+
+	GetConsoleScreenBufferInfo(console, &sbi);
+	FillConsoleOutputCharacterA(console, ' ',
+		sbi.dwSize.X - sbi.dwCursorPosition.X, sbi.dwCursorPosition,
+		NULL);
+
+	pos.X = 0;
+	for (pos.Y = sbi.dwCursorPosition.Y+1; pos.Y < sbi.dwSize.Y; pos.Y++)
+		FillConsoleOutputCharacterA(console, ' ', sbi.dwSize.X,
+					    pos, NULL);
+}
 
 static const char *set_attr(const char *str)
 {
@@ -230,6 +248,9 @@ static const char *set_attr(const char *str)
 
 		set_console_attr();
 		break;
+	case 'J':
+		erase_till_end_of_screen();
+		break;
 	case 'K':
 		erase_in_line();
 		break;
-- 
cgit v1.2.3-55-g6feb


From 79fc61359a8f9a9563627e9ad8e5938c3ffee4ca Mon Sep 17 00:00:00 2001
From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date: Tue, 14 Sep 2010 15:37:12 +1000
Subject: win32: read_key: reset console state after reading

---
 win32/termios.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/win32/termios.c b/win32/termios.c
index 6d85ff98e..1bd3cbd5b 100644
--- a/win32/termios.c
+++ b/win32/termios.c
@@ -12,25 +12,29 @@ int tcgetattr(int fd UNUSED_PARAM, struct termios *t UNUSED_PARAM)
 
 int64_t FAST_FUNC read_key(int fd, char *buf, int timeout UNUSED_PARAM)
 {
-	static int initialized = 0;
 	HANDLE cin = GetStdHandle(STD_INPUT_HANDLE);
 	INPUT_RECORD record;
-	DWORD nevent_out;
+	DWORD nevent_out, mode;
+	int ret = -1;
 
 	if (fd != 0)
 		bb_error_msg_and_die("read_key only works on stdin");
 	if (cin == INVALID_HANDLE_VALUE)
 		return -1;
-	if (!initialized) {
-		SetConsoleMode(cin, ENABLE_ECHO_INPUT);
-		initialized = 1;
-	}
+	GetConsoleMode(cin, &mode);
+	SetConsoleMode(cin, 0);
 
 	while (1) {
 		if (!ReadConsoleInput(cin, &record, 1, &nevent_out))
-			return -1;
+			goto done;
 		if (record.EventType != KEY_EVENT || !record.Event.KeyEvent.bKeyDown)
 			continue;
-		return record.Event.KeyEvent.uChar.AsciiChar;
+		if (!record.Event.KeyEvent.uChar.AsciiChar)
+			continue;
+		ret = record.Event.KeyEvent.uChar.AsciiChar;
+		break;
 	}
+ done:
+	SetConsoleMode(cin, mode);
+	return ret;
 }
-- 
cgit v1.2.3-55-g6feb


From fc11f0cef175a7bfd652691d05f3e19147462cb1 Mon Sep 17 00:00:00 2001
From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date: Tue, 14 Sep 2010 16:47:04 +1000
Subject: win32: read_key: imap some movement keys to KEYCODE_*

---
 win32/termios.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/win32/termios.c b/win32/termios.c
index 1bd3cbd5b..812f6d5d7 100644
--- a/win32/termios.c
+++ b/win32/termios.c
@@ -29,8 +29,24 @@ int64_t FAST_FUNC read_key(int fd, char *buf, int timeout UNUSED_PARAM)
 			goto done;
 		if (record.EventType != KEY_EVENT || !record.Event.KeyEvent.bKeyDown)
 			continue;
-		if (!record.Event.KeyEvent.uChar.AsciiChar)
+		if (!record.Event.KeyEvent.uChar.AsciiChar) {
+			switch (record.Event.KeyEvent.wVirtualKeyCode) {
+			case VK_UP: return KEYCODE_UP;
+			case VK_DOWN: return KEYCODE_DOWN;
+			case VK_RIGHT: return KEYCODE_RIGHT;
+			case VK_LEFT: return KEYCODE_LEFT;
+			case VK_HOME: return KEYCODE_HOME;
+			case VK_END: return KEYCODE_END;
+			case VK_CAPITAL:
+			case VK_SHIFT:
+			case VK_CONTROL:
+			case VK_MENU:
+				break;
+			default:
+				return -1;
+			}
 			continue;
+		}
 		ret = record.Event.KeyEvent.uChar.AsciiChar;
 		break;
 	}
-- 
cgit v1.2.3-55-g6feb


From d527acced45955fa83f0453e2c215b6cc1cad920 Mon Sep 17 00:00:00 2001
From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date: Tue, 14 Sep 2010 16:54:54 +1000
Subject: win32: winansi: implement \033[%uD

---
 win32/winansi.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/win32/winansi.c b/win32/winansi.c
index 51bfad67c..3e97779cb 100644
--- a/win32/winansi.c
+++ b/win32/winansi.c
@@ -110,6 +110,18 @@ static void erase_till_end_of_screen(void)
 					    pos, NULL);
 }
 
+static void move_cursor_back(int n)
+{
+	CONSOLE_SCREEN_BUFFER_INFO sbi;
+
+	if (!console)
+		return;
+
+	GetConsoleScreenBufferInfo(console, &sbi);
+	sbi.dwCursorPosition.X -= n;
+	SetConsoleCursorPosition(console, sbi.dwCursorPosition);
+}
+
 static const char *set_attr(const char *str)
 {
 	const char *func;
@@ -248,6 +260,9 @@ static const char *set_attr(const char *str)
 
 		set_console_attr();
 		break;
+	case 'D':
+		move_cursor_back(strtol(str, (char **)&str, 10));
+		break;
 	case 'J':
 		erase_till_end_of_screen();
 		break;
-- 
cgit v1.2.3-55-g6feb


From 62822fc3b2cadf823d4d74be902c76e1af0b904a Mon Sep 17 00:00:00 2001
From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date: Tue, 14 Sep 2010 17:58:57 +1000
Subject: win32: read_key: support Ctrl-{Left,Right}

---
 win32/termios.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/win32/termios.c b/win32/termios.c
index 812f6d5d7..0154bd11f 100644
--- a/win32/termios.c
+++ b/win32/termios.c
@@ -30,11 +30,18 @@ int64_t FAST_FUNC read_key(int fd, char *buf, int timeout UNUSED_PARAM)
 		if (record.EventType != KEY_EVENT || !record.Event.KeyEvent.bKeyDown)
 			continue;
 		if (!record.Event.KeyEvent.uChar.AsciiChar) {
+			DWORD state = record.Event.KeyEvent.dwControlKeyState;
 			switch (record.Event.KeyEvent.wVirtualKeyCode) {
 			case VK_UP: return KEYCODE_UP;
 			case VK_DOWN: return KEYCODE_DOWN;
-			case VK_RIGHT: return KEYCODE_RIGHT;
-			case VK_LEFT: return KEYCODE_LEFT;
+			case VK_RIGHT:
+				if (state & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
+					return KEYCODE_CTRL_RIGHT;
+				return KEYCODE_RIGHT;
+			case VK_LEFT:
+				if (state & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))
+					return KEYCODE_CTRL_LEFT;
+				return KEYCODE_LEFT;
 			case VK_HOME: return KEYCODE_HOME;
 			case VK_END: return KEYCODE_END;
 			case VK_CAPITAL:
-- 
cgit v1.2.3-55-g6feb


From a335db7cd1acbe54c0bfe5ec02457d430e866f04 Mon Sep 17 00:00:00 2001
From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date: Tue, 14 Sep 2010 17:59:09 +1000
Subject: win32: read_key: support Delete

---
 win32/termios.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/win32/termios.c b/win32/termios.c
index 0154bd11f..177a7bdbe 100644
--- a/win32/termios.c
+++ b/win32/termios.c
@@ -32,6 +32,7 @@ int64_t FAST_FUNC read_key(int fd, char *buf, int timeout UNUSED_PARAM)
 		if (!record.Event.KeyEvent.uChar.AsciiChar) {
 			DWORD state = record.Event.KeyEvent.dwControlKeyState;
 			switch (record.Event.KeyEvent.wVirtualKeyCode) {
+			case VK_DELETE: return KEYCODE_DELETE;
 			case VK_UP: return KEYCODE_UP;
 			case VK_DOWN: return KEYCODE_DOWN;
 			case VK_RIGHT:
-- 
cgit v1.2.3-55-g6feb


From 1a6d1cbfb455e71208017039d41fe7e62a69cda2 Mon Sep 17 00:00:00 2001
From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date: Tue, 14 Sep 2010 18:00:35 +1000
Subject: win32: read_key: do not return -1 on unknown key

-1 to lineedit means error... when tty is destroyed... it would
terminate ash for some reasone
---
 win32/termios.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/win32/termios.c b/win32/termios.c
index 177a7bdbe..283e88b3a 100644
--- a/win32/termios.c
+++ b/win32/termios.c
@@ -50,8 +50,6 @@ int64_t FAST_FUNC read_key(int fd, char *buf, int timeout UNUSED_PARAM)
 			case VK_CONTROL:
 			case VK_MENU:
 				break;
-			default:
-				return -1;
 			}
 			continue;
 		}
-- 
cgit v1.2.3-55-g6feb


From 3bc78ad7df40a9d2787d7dd7f79a5d3257d619e4 Mon Sep 17 00:00:00 2001
From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date: Tue, 14 Sep 2010 18:07:31 +1000
Subject: win32: winansi: implement \033[H (no param)

---
 win32/winansi.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/win32/winansi.c b/win32/winansi.c
index 3e97779cb..568f925aa 100644
--- a/win32/winansi.c
+++ b/win32/winansi.c
@@ -122,6 +122,18 @@ static void move_cursor_back(int n)
 	SetConsoleCursorPosition(console, sbi.dwCursorPosition);
 }
 
+static void move_cursor(int x, int y)
+{
+	COORD pos;
+
+	if (!console)
+		return;
+
+	pos.X = x;
+	pos.Y = y;
+	SetConsoleCursorPosition(console, pos);
+}
+
 static const char *set_attr(const char *str)
 {
 	const char *func;
@@ -263,6 +275,10 @@ static const char *set_attr(const char *str)
 	case 'D':
 		move_cursor_back(strtol(str, (char **)&str, 10));
 		break;
+	case 'H':
+		if (!len)
+			move_cursor(0, 0);
+		break;
 	case 'J':
 		erase_till_end_of_screen();
 		break;
-- 
cgit v1.2.3-55-g6feb


From b7d776dee51ce10de0f996fd91789488bc659605 Mon Sep 17 00:00:00 2001
From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date: Tue, 14 Sep 2010 18:30:49 +1000
Subject: win32: winansi: implement \033[%u;%uH

---
 win32/winansi.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/win32/winansi.c b/win32/winansi.c
index 568f925aa..d95bd473b 100644
--- a/win32/winansi.c
+++ b/win32/winansi.c
@@ -278,6 +278,13 @@ static const char *set_attr(const char *str)
 	case 'H':
 		if (!len)
 			move_cursor(0, 0);
+		else {
+			int row = strtol(str, (char **)&str, 10);
+			if (*str == ';') {
+				int col = strtol(str+1, (char **)&str, 10);
+				move_cursor(col, row);
+			}
+		}
 		break;
 	case 'J':
 		erase_till_end_of_screen();
-- 
cgit v1.2.3-55-g6feb


From 0231af4e5b38956216a058ebf1e1619ae47dfa14 Mon Sep 17 00:00:00 2001
From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date: Tue, 14 Sep 2010 18:35:45 +1000
Subject: win32: read_key: add Page Up/Down and Insert

---
 win32/termios.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/win32/termios.c b/win32/termios.c
index 283e88b3a..e2dc96361 100644
--- a/win32/termios.c
+++ b/win32/termios.c
@@ -33,6 +33,7 @@ int64_t FAST_FUNC read_key(int fd, char *buf, int timeout UNUSED_PARAM)
 			DWORD state = record.Event.KeyEvent.dwControlKeyState;
 			switch (record.Event.KeyEvent.wVirtualKeyCode) {
 			case VK_DELETE: return KEYCODE_DELETE;
+			case VK_INSERT: return KEYCODE_INSERT;
 			case VK_UP: return KEYCODE_UP;
 			case VK_DOWN: return KEYCODE_DOWN;
 			case VK_RIGHT:
@@ -45,6 +46,8 @@ int64_t FAST_FUNC read_key(int fd, char *buf, int timeout UNUSED_PARAM)
 				return KEYCODE_LEFT;
 			case VK_HOME: return KEYCODE_HOME;
 			case VK_END: return KEYCODE_END;
+			case VK_PRIOR: return KEYCODE_PAGEUP;
+			case VK_NEXT: return KEYCODE_PAGEDOWN;
 			case VK_CAPITAL:
 			case VK_SHIFT:
 			case VK_CONTROL:
-- 
cgit v1.2.3-55-g6feb


From 7a30dffb59673ef5b5e1ff30248d2e72d6814fd5 Mon Sep 17 00:00:00 2001
From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date: Tue, 14 Sep 2010 20:42:01 +1000
Subject: win32: lineedit: enable history

---
 scripts/defconfig.mingw32 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/defconfig.mingw32 b/scripts/defconfig.mingw32
index 943c3f4ab..1d931503c 100644
--- a/scripts/defconfig.mingw32
+++ b/scripts/defconfig.mingw32
@@ -101,7 +101,7 @@ CONFIG_MD5_SIZE_VS_SPEED=2
 CONFIG_FEATURE_EDITING=y
 CONFIG_FEATURE_EDITING_MAX_LEN=1024
 # CONFIG_FEATURE_EDITING_VI is not set
-CONFIG_FEATURE_EDITING_HISTORY=0
+CONFIG_FEATURE_EDITING_HISTORY=64
 # CONFIG_FEATURE_EDITING_SAVEHISTORY is not set
 CONFIG_FEATURE_TAB_COMPLETION=y
 # CONFIG_FEATURE_USERNAME_COMPLETION is not set
-- 
cgit v1.2.3-55-g6feb