From cc9eb4a5ec8b56bf5ef535275fd54684e7348e75 Mon Sep 17 00:00:00 2001 From: CPunch Date: Fri, 1 Sep 2023 17:16:10 -0500 Subject: [PATCH] lol oops --- util/linenoise-win32.c | 379 ++++++++++++++++++++++++++++++++++++++++ util/linenoise.c | 382 ----------------------------------------- 2 files changed, 379 insertions(+), 382 deletions(-) create mode 100644 util/linenoise-win32.c diff --git a/util/linenoise-win32.c b/util/linenoise-win32.c new file mode 100644 index 0000000..dae0bd8 --- /dev/null +++ b/util/linenoise-win32.c @@ -0,0 +1,379 @@ + +/* this code is not standalone + * it is included into linenoise.c + * for windows. + * It is deliberately kept separate so that + * applications that have no need for windows + * support can omit this + */ +static DWORD orig_consolemode = 0; + +static int flushOutput(struct current *current); +static void outputNewline(struct current *current); + +static void refreshStart(struct current *current) +{ + (void)current; +} + +static void refreshEnd(struct current *current) +{ + (void)current; +} + +static void refreshStartChars(struct current *current) +{ + assert(current->output == NULL); + /* We accumulate all output here */ + current->output = sb_alloc(); +#ifdef USE_UTF8 + current->ubuflen = 0; +#endif +} + +static void refreshNewline(struct current *current) +{ + DRL(""); + outputNewline(current); +} + +static void refreshEndChars(struct current *current) +{ + assert(current->output); + flushOutput(current); + sb_free(current->output); + current->output = NULL; +} + +static int enableRawMode(struct current *current) { + DWORD n; + INPUT_RECORD irec; + + current->outh = GetStdHandle(STD_OUTPUT_HANDLE); + current->inh = GetStdHandle(STD_INPUT_HANDLE); + + if (!PeekConsoleInput(current->inh, &irec, 1, &n)) { + return -1; + } + if (getWindowSize(current) != 0) { + return -1; + } + if (GetConsoleMode(current->inh, &orig_consolemode)) { + SetConsoleMode(current->inh, ENABLE_PROCESSED_INPUT); + } +#ifdef USE_UTF8 + /* XXX is this the right thing to do? */ + SetConsoleCP(65001); +#endif + return 0; +} + +static void disableRawMode(struct current *current) +{ + SetConsoleMode(current->inh, orig_consolemode); +} + +void linenoiseClearScreen(void) +{ + /* XXX: This is ugly. Should just have the caller pass a handle */ + struct current current; + + current.outh = GetStdHandle(STD_OUTPUT_HANDLE); + + if (getWindowSize(¤t) == 0) { + COORD topleft = { 0, 0 }; + DWORD n; + + FillConsoleOutputCharacter(current.outh, ' ', + current.cols * current.rows, topleft, &n); + FillConsoleOutputAttribute(current.outh, + FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, + current.cols * current.rows, topleft, &n); + SetConsoleCursorPosition(current.outh, topleft); + } +} + +static void cursorToLeft(struct current *current) +{ + COORD pos; + DWORD n; + + pos.X = 0; + pos.Y = (SHORT)current->y; + + FillConsoleOutputAttribute(current->outh, + FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, current->cols, pos, &n); + current->x = 0; +} + +#ifdef USE_UTF8 +static void flush_ubuf(struct current *current) +{ + COORD pos; + DWORD nwritten; + pos.Y = (SHORT)current->y; + pos.X = (SHORT)current->x; + SetConsoleCursorPosition(current->outh, pos); + WriteConsoleW(current->outh, current->ubuf, current->ubuflen, &nwritten, 0); + current->x += current->ubufcols; + current->ubuflen = 0; + current->ubufcols = 0; +} + +static void add_ubuf(struct current *current, int ch) +{ + /* This code originally by: Author: Mark E. Davis, 1994. */ + static const int halfShift = 10; /* used for shifting by 10 bits */ + + static const DWORD halfBase = 0x0010000UL; + static const DWORD halfMask = 0x3FFUL; + + #define UNI_SUR_HIGH_START 0xD800 + #define UNI_SUR_HIGH_END 0xDBFF + #define UNI_SUR_LOW_START 0xDC00 + #define UNI_SUR_LOW_END 0xDFFF + + #define UNI_MAX_BMP 0x0000FFFF + + if (ch > UNI_MAX_BMP) { + /* convert from unicode to utf16 surrogate pairs + * There is always space for one extra word in ubuf + */ + ch -= halfBase; + current->ubuf[current->ubuflen++] = (WORD)((ch >> halfShift) + UNI_SUR_HIGH_START); + current->ubuf[current->ubuflen++] = (WORD)((ch & halfMask) + UNI_SUR_LOW_START); + } + else { + current->ubuf[current->ubuflen++] = ch; + } + current->ubufcols += utf8_width(ch); + if (current->ubuflen >= UBUF_MAX_CHARS) { + flush_ubuf(current); + } +} +#endif + +static int flushOutput(struct current *current) +{ + const char *pt = sb_str(current->output); + int len = sb_len(current->output); + +#ifdef USE_UTF8 + /* convert utf8 in current->output into utf16 in current->ubuf + */ + while (len) { + int ch; + int n = utf8_tounicode(pt, &ch); + + pt += n; + len -= n; + + add_ubuf(current, ch); + } + flush_ubuf(current); +#else + DWORD nwritten; + COORD pos; + + pos.Y = (SHORT)current->y; + pos.X = (SHORT)current->x; + + SetConsoleCursorPosition(current->outh, pos); + WriteConsoleA(current->outh, pt, len, &nwritten, 0); + + current->x += len; +#endif + + sb_clear(current->output); + + return 0; +} + +static int outputChars(struct current *current, const char *buf, int len) +{ + if (len < 0) { + len = strlen(buf); + } + assert(current->output); + + sb_append_len(current->output, buf, len); + + return 0; +} + +static void outputNewline(struct current *current) +{ + /* On the last row output a newline to force a scroll */ + if (current->y + 1 == current->rows) { + outputChars(current, "\n", 1); + } + flushOutput(current); + current->x = 0; + current->y++; +} + +static void setOutputHighlight(struct current *current, const int *props, int nprops) +{ + int colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN; + int bold = 0; + int reverse = 0; + int i; + + for (i = 0; i < nprops; i++) { + switch (props[i]) { + case 0: + colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN; + bold = 0; + reverse = 0; + break; + case 1: + bold = FOREGROUND_INTENSITY; + break; + case 7: + reverse = 1; + break; + case 30: + colour = 0; + break; + case 31: + colour = FOREGROUND_RED; + break; + case 32: + colour = FOREGROUND_GREEN; + break; + case 33: + colour = FOREGROUND_RED | FOREGROUND_GREEN; + break; + case 34: + colour = FOREGROUND_BLUE; + break; + case 35: + colour = FOREGROUND_RED | FOREGROUND_BLUE; + break; + case 36: + colour = FOREGROUND_BLUE | FOREGROUND_GREEN; + break; + case 37: + colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN; + break; + } + } + + flushOutput(current); + + if (reverse) { + SetConsoleTextAttribute(current->outh, BACKGROUND_INTENSITY); + } + else { + SetConsoleTextAttribute(current->outh, colour | bold); + } +} + +static void eraseEol(struct current *current) +{ + COORD pos; + DWORD n; + + pos.X = (SHORT) current->x; + pos.Y = (SHORT) current->y; + + FillConsoleOutputCharacter(current->outh, ' ', current->cols - current->x, pos, &n); +} + +static void setCursorXY(struct current *current) +{ + COORD pos; + + pos.X = (SHORT) current->x; + pos.Y = (SHORT) current->y; + + SetConsoleCursorPosition(current->outh, pos); +} + + +static void setCursorPos(struct current *current, int x) +{ + current->x = x; + setCursorXY(current); +} + +static void cursorUp(struct current *current, int n) +{ + current->y -= n; + setCursorXY(current); +} + +static void cursorDown(struct current *current, int n) +{ + current->y += n; + setCursorXY(current); +} + +static int fd_read(struct current *current) +{ + while (1) { + INPUT_RECORD irec; + DWORD n; + if (WaitForSingleObject(current->inh, INFINITE) != WAIT_OBJECT_0) { + break; + } + if (!ReadConsoleInputW(current->inh, &irec, 1, &n)) { + break; + } + if (irec.EventType == KEY_EVENT) { + KEY_EVENT_RECORD *k = &irec.Event.KeyEvent; + if (k->bKeyDown || k->wVirtualKeyCode == VK_MENU) { + if (k->dwControlKeyState & ENHANCED_KEY) { + switch (k->wVirtualKeyCode) { + case VK_LEFT: + return SPECIAL_LEFT; + case VK_RIGHT: + return SPECIAL_RIGHT; + case VK_UP: + return SPECIAL_UP; + case VK_DOWN: + return SPECIAL_DOWN; + case VK_INSERT: + return SPECIAL_INSERT; + case VK_DELETE: + return SPECIAL_DELETE; + case VK_HOME: + return SPECIAL_HOME; + case VK_END: + return SPECIAL_END; + case VK_PRIOR: + return SPECIAL_PAGE_UP; + case VK_NEXT: + return SPECIAL_PAGE_DOWN; + case VK_RETURN: + return k->uChar.UnicodeChar; + } + } + /* Note that control characters are already translated in AsciiChar */ + else if (k->wVirtualKeyCode == VK_CONTROL) + continue; + else { + return k->uChar.UnicodeChar; + } + } + } + } + return -1; +} + +static int getWindowSize(struct current *current) +{ + CONSOLE_SCREEN_BUFFER_INFO info; + if (!GetConsoleScreenBufferInfo(current->outh, &info)) { + return -1; + } + current->cols = info.dwSize.X; + current->rows = info.dwSize.Y; + if (current->cols <= 0 || current->rows <= 0) { + current->cols = 80; + return -1; + } + current->y = info.dwCursorPosition.Y; + current->x = info.dwCursorPosition.X; + return 0; +} \ No newline at end of file diff --git a/util/linenoise.c b/util/linenoise.c index 3ed891a..cf6cc0a 100644 --- a/util/linenoise.c +++ b/util/linenoise.c @@ -2784,385 +2784,3 @@ char **linenoiseHistory(int *len) { } return history; } - -#ifdef WIN32 - -/* this code is not standalone - * it is included into linenoise.c - * for windows. - * It is deliberately kept separate so that - * applications that have no need for windows - * support can omit this - */ -static DWORD orig_consolemode = 0; - -static int flushOutput(struct current *current); -static void outputNewline(struct current *current); - -static void refreshStart(struct current *current) -{ - (void)current; -} - -static void refreshEnd(struct current *current) -{ - (void)current; -} - -static void refreshStartChars(struct current *current) -{ - assert(current->output == NULL); - /* We accumulate all output here */ - current->output = sb_alloc(); -#ifdef USE_UTF8 - current->ubuflen = 0; -#endif -} - -static void refreshNewline(struct current *current) -{ - DRL(""); - outputNewline(current); -} - -static void refreshEndChars(struct current *current) -{ - assert(current->output); - flushOutput(current); - sb_free(current->output); - current->output = NULL; -} - -static int enableRawMode(struct current *current) { - DWORD n; - INPUT_RECORD irec; - - current->outh = GetStdHandle(STD_OUTPUT_HANDLE); - current->inh = GetStdHandle(STD_INPUT_HANDLE); - - if (!PeekConsoleInput(current->inh, &irec, 1, &n)) { - return -1; - } - if (getWindowSize(current) != 0) { - return -1; - } - if (GetConsoleMode(current->inh, &orig_consolemode)) { - SetConsoleMode(current->inh, ENABLE_PROCESSED_INPUT); - } -#ifdef USE_UTF8 - /* XXX is this the right thing to do? */ - SetConsoleCP(65001); -#endif - return 0; -} - -static void disableRawMode(struct current *current) -{ - SetConsoleMode(current->inh, orig_consolemode); -} - -void linenoiseClearScreen(void) -{ - /* XXX: This is ugly. Should just have the caller pass a handle */ - struct current current; - - current.outh = GetStdHandle(STD_OUTPUT_HANDLE); - - if (getWindowSize(¤t) == 0) { - COORD topleft = { 0, 0 }; - DWORD n; - - FillConsoleOutputCharacter(current.outh, ' ', - current.cols * current.rows, topleft, &n); - FillConsoleOutputAttribute(current.outh, - FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, - current.cols * current.rows, topleft, &n); - SetConsoleCursorPosition(current.outh, topleft); - } -} - -static void cursorToLeft(struct current *current) -{ - COORD pos; - DWORD n; - - pos.X = 0; - pos.Y = (SHORT)current->y; - - FillConsoleOutputAttribute(current->outh, - FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, current->cols, pos, &n); - current->x = 0; -} - -#ifdef USE_UTF8 -static void flush_ubuf(struct current *current) -{ - COORD pos; - DWORD nwritten; - pos.Y = (SHORT)current->y; - pos.X = (SHORT)current->x; - SetConsoleCursorPosition(current->outh, pos); - WriteConsoleW(current->outh, current->ubuf, current->ubuflen, &nwritten, 0); - current->x += current->ubufcols; - current->ubuflen = 0; - current->ubufcols = 0; -} - -static void add_ubuf(struct current *current, int ch) -{ - /* This code originally by: Author: Mark E. Davis, 1994. */ - static const int halfShift = 10; /* used for shifting by 10 bits */ - - static const DWORD halfBase = 0x0010000UL; - static const DWORD halfMask = 0x3FFUL; - - #define UNI_SUR_HIGH_START 0xD800 - #define UNI_SUR_HIGH_END 0xDBFF - #define UNI_SUR_LOW_START 0xDC00 - #define UNI_SUR_LOW_END 0xDFFF - - #define UNI_MAX_BMP 0x0000FFFF - - if (ch > UNI_MAX_BMP) { - /* convert from unicode to utf16 surrogate pairs - * There is always space for one extra word in ubuf - */ - ch -= halfBase; - current->ubuf[current->ubuflen++] = (WORD)((ch >> halfShift) + UNI_SUR_HIGH_START); - current->ubuf[current->ubuflen++] = (WORD)((ch & halfMask) + UNI_SUR_LOW_START); - } - else { - current->ubuf[current->ubuflen++] = ch; - } - current->ubufcols += utf8_width(ch); - if (current->ubuflen >= UBUF_MAX_CHARS) { - flush_ubuf(current); - } -} -#endif - -static int flushOutput(struct current *current) -{ - const char *pt = sb_str(current->output); - int len = sb_len(current->output); - -#ifdef USE_UTF8 - /* convert utf8 in current->output into utf16 in current->ubuf - */ - while (len) { - int ch; - int n = utf8_tounicode(pt, &ch); - - pt += n; - len -= n; - - add_ubuf(current, ch); - } - flush_ubuf(current); -#else - DWORD nwritten; - COORD pos; - - pos.Y = (SHORT)current->y; - pos.X = (SHORT)current->x; - - SetConsoleCursorPosition(current->outh, pos); - WriteConsoleA(current->outh, pt, len, &nwritten, 0); - - current->x += len; -#endif - - sb_clear(current->output); - - return 0; -} - -static int outputChars(struct current *current, const char *buf, int len) -{ - if (len < 0) { - len = strlen(buf); - } - assert(current->output); - - sb_append_len(current->output, buf, len); - - return 0; -} - -static void outputNewline(struct current *current) -{ - /* On the last row output a newline to force a scroll */ - if (current->y + 1 == current->rows) { - outputChars(current, "\n", 1); - } - flushOutput(current); - current->x = 0; - current->y++; -} - -static void setOutputHighlight(struct current *current, const int *props, int nprops) -{ - int colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN; - int bold = 0; - int reverse = 0; - int i; - - for (i = 0; i < nprops; i++) { - switch (props[i]) { - case 0: - colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN; - bold = 0; - reverse = 0; - break; - case 1: - bold = FOREGROUND_INTENSITY; - break; - case 7: - reverse = 1; - break; - case 30: - colour = 0; - break; - case 31: - colour = FOREGROUND_RED; - break; - case 32: - colour = FOREGROUND_GREEN; - break; - case 33: - colour = FOREGROUND_RED | FOREGROUND_GREEN; - break; - case 34: - colour = FOREGROUND_BLUE; - break; - case 35: - colour = FOREGROUND_RED | FOREGROUND_BLUE; - break; - case 36: - colour = FOREGROUND_BLUE | FOREGROUND_GREEN; - break; - case 37: - colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN; - break; - } - } - - flushOutput(current); - - if (reverse) { - SetConsoleTextAttribute(current->outh, BACKGROUND_INTENSITY); - } - else { - SetConsoleTextAttribute(current->outh, colour | bold); - } -} - -static void eraseEol(struct current *current) -{ - COORD pos; - DWORD n; - - pos.X = (SHORT) current->x; - pos.Y = (SHORT) current->y; - - FillConsoleOutputCharacter(current->outh, ' ', current->cols - current->x, pos, &n); -} - -static void setCursorXY(struct current *current) -{ - COORD pos; - - pos.X = (SHORT) current->x; - pos.Y = (SHORT) current->y; - - SetConsoleCursorPosition(current->outh, pos); -} - - -static void setCursorPos(struct current *current, int x) -{ - current->x = x; - setCursorXY(current); -} - -static void cursorUp(struct current *current, int n) -{ - current->y -= n; - setCursorXY(current); -} - -static void cursorDown(struct current *current, int n) -{ - current->y += n; - setCursorXY(current); -} - -static int fd_read(struct current *current) -{ - while (1) { - INPUT_RECORD irec; - DWORD n; - if (WaitForSingleObject(current->inh, INFINITE) != WAIT_OBJECT_0) { - break; - } - if (!ReadConsoleInputW(current->inh, &irec, 1, &n)) { - break; - } - if (irec.EventType == KEY_EVENT) { - KEY_EVENT_RECORD *k = &irec.Event.KeyEvent; - if (k->bKeyDown || k->wVirtualKeyCode == VK_MENU) { - if (k->dwControlKeyState & ENHANCED_KEY) { - switch (k->wVirtualKeyCode) { - case VK_LEFT: - return SPECIAL_LEFT; - case VK_RIGHT: - return SPECIAL_RIGHT; - case VK_UP: - return SPECIAL_UP; - case VK_DOWN: - return SPECIAL_DOWN; - case VK_INSERT: - return SPECIAL_INSERT; - case VK_DELETE: - return SPECIAL_DELETE; - case VK_HOME: - return SPECIAL_HOME; - case VK_END: - return SPECIAL_END; - case VK_PRIOR: - return SPECIAL_PAGE_UP; - case VK_NEXT: - return SPECIAL_PAGE_DOWN; - case VK_RETURN: - return k->uChar.UnicodeChar; - } - } - /* Note that control characters are already translated in AsciiChar */ - else if (k->wVirtualKeyCode == VK_CONTROL) - continue; - else { - return k->uChar.UnicodeChar; - } - } - } - } - return -1; -} - -static int getWindowSize(struct current *current) -{ - CONSOLE_SCREEN_BUFFER_INFO info; - if (!GetConsoleScreenBufferInfo(current->outh, &info)) { - return -1; - } - current->cols = info.dwSize.X; - current->rows = info.dwSize.Y; - if (current->cols <= 0 || current->rows <= 0) { - current->cols = 80; - return -1; - } - current->y = info.dwCursorPosition.Y; - current->x = info.dwCursorPosition.X; - return 0; -} -#endif \ No newline at end of file