From b1b144d19f0469a958449e39b17d68158f6546bd Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Wed, 9 Dec 2015 12:01:37 -0800 Subject: [PATCH] Allow use of up/down arrows in multi-line command. --- Console.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/Console.cpp b/Console.cpp index b0b3768..463189c 100644 --- a/Console.cpp +++ b/Console.cpp @@ -411,6 +411,57 @@ static int CYConsoleKeyReturn(int count, int key) { return 0; } +template +static Type_ *CYmemrchr(Type_ *data, Type_ value, size_t size) { + while (size != 0) + if (data[--size] == value) + return data + size; + return NULL; +} + +static int CYConsoleKeyUp(int count, int key) { + char *after(CYmemrchr(rl_line_buffer, '\n', rl_point)); + if (after == NULL) { + if (int value = rl_get_previous_history(count, key)) + return value; + return 0; + } + + char *before(CYmemrchr(rl_line_buffer, '\n', after - rl_line_buffer)); + if (before == NULL) + before = rl_line_buffer - 1; + + ptrdiff_t offset(rl_line_buffer + rl_point - after); + if (offset > after - before) + rl_point = after - 1 - rl_line_buffer; + else + rl_point = before + offset - rl_line_buffer; + + return 0; +} + +static int CYConsoleKeyDown(int count, int key) { + char *after(static_cast(memchr(rl_line_buffer + rl_point, '\n', rl_end - rl_point))); + if (after == NULL) { + if (int value = rl_get_next_history(count, key)) + return value; + rl_point = 0; + return 0; + } + + char *before(CYmemrchr(rl_line_buffer, '\n', rl_point)); + if (before == NULL) + before = rl_line_buffer - 1; + + ptrdiff_t offset(rl_line_buffer + rl_point - before); + if (offset > rl_line_buffer + rl_end - after) + rl_point = rl_end; + else + rl_point = after + offset - rl_line_buffer; + + return 0; +} + static void Console(CYOptions &options) { std::string basedir; if (const char *home = getenv("HOME")) @@ -445,6 +496,21 @@ static void Console(CYOptions &options) { rl_redisplay_function = CYDisplayUpdate; +#if defined (__MSDOS__) + rl_bind_keyseq("\033[0A", &CYConsoleKeyUp); + rl_bind_keyseq("\033[0D", &CYConsoleKeyDown); +#endif + rl_bind_keyseq("\033[A", &CYConsoleKeyUp); + rl_bind_keyseq("\033[B", &CYConsoleKeyDown); + rl_bind_keyseq("\033OA", &CYConsoleKeyUp); + rl_bind_keyseq("\033OB", &CYConsoleKeyDown); +#if defined (__MINGW32__) + rl_bind_keyseq("\340H", &CYConsoleKeyUp); + rl_bind_keyseq("\340P", &CYConsoleKeyDown); + rl_bind_keyseq("\\000H", &CYConsoleKeyUp); + rl_bind_keyseq("\\000P", &CYConsoleKeyDown); +#endif + struct sigaction action; sigemptyset(&action.sa_mask); action.sa_handler = &sigint; -- 2.49.0