From 8285da9d856b100d6f4631180408a42d0b35fff6 Mon Sep 17 00:00:00 2001 From: Steve Bennett Date: Thu, 29 Sep 2011 13:47:49 +1000 Subject: Sync linenoise with github Update comments, copyright, etc. Handle additional home, end sequences Don't add duplicate lines into history Signed-off-by: Steve Bennett --- linenoise.c | 84 +++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 45 insertions(+), 39 deletions(-) (limited to 'linenoise.c') diff --git a/linenoise.c b/linenoise.c index 4065d06..418bede 100644 --- a/linenoise.c +++ b/linenoise.c @@ -3,7 +3,8 @@ * * You can find the latest source code at: * - * http://github.com/antirez/linenoise + * http://github.com/msteveb/linenoise + * (forked from http://github.com/antirez/linenoise) * * Does a number of crazy assumptions that happen to be true in 99.9999% of * the 2010 UNIX computers around. @@ -12,6 +13,7 @@ * * Copyright (c) 2010, Salvatore Sanfilippo * Copyright (c) 2010, Pieter Noordhuis + * Copyright (c) 2011, Steve Bennett * * All rights reserved. * @@ -44,13 +46,11 @@ * - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html * - http://www.3waylabs.com/nw/WWW/products/wizcon/vt220.html * - * Todo list: - * - Win32 support - * - Save and load history containing newlines - * * Bloat: * - Completion? * + * Unix/termios + * ------------ * List of escape sequences used by this program, we do everything just * a few sequences. In order to be so cheap we may have some * flickering effect with some slow terminal, but the lesser sequences @@ -94,6 +94,12 @@ * DSR/CPR (Report cursor position) * Sequence: ESC [ 6 n * Effect: reports current cursor position as ESC [ NNN ; MMM R + * + * win32/console + * ------------- + * If __MINGW32__ is defined, the win32 console API is used. + * This could probably be made to work for the msvc compiler too. + * This support based in part on work by Jon Griffiths. */ #ifdef __MINGW32__ @@ -452,16 +458,22 @@ static int check_special(int fd) return SPECIAL_HOME; } } - if (c == '[' && c2 >= '1' && c2 <= '6') { + if (c == '[' && c2 >= '1' && c2 <= '8') { /* extended escape */ - int c3 = fd_read_char(fd, 50); - if (c2 == '3' && c3 == '~') { - /* delete char under cursor */ - return SPECIAL_DELETE; + c = fd_read_char(fd, 50); + if (c == '~') { + switch (c2) { + case '3': + return SPECIAL_DELETE; + case '7': + return SPECIAL_HOME; + case '8': + return SPECIAL_END; + } } - while (c3 != -1 && c3 != '~') { + while (c != -1 && c != '~') { /* .e.g \e[12~ or '\e[11;2~ discard the complete sequence */ - c3 = fd_read_char(fd, 50); + c = fd_read_char(fd, 50); } } @@ -974,8 +986,9 @@ process_char: free(history[history_len]); return -1; } - /* Otherwise delete char to right of cursor */ - if (remove_char(current, current->pos)) { + /* Otherwise fall through to delete char to right of cursor */ + case SPECIAL_DELETE: + if (remove_char(current, current->pos) == 1) { refreshLine(current->prompt, current); } break; @@ -1161,28 +1174,16 @@ process_char: refreshLine(current->prompt, current); } break; - - case SPECIAL_DELETE: - if (remove_char(current, current->pos) == 1) { - refreshLine(current->prompt, current); - } - break; + case ctrl('A'): /* Ctrl+a, go to the start of the line */ case SPECIAL_HOME: current->pos = 0; refreshLine(current->prompt, current); break; + case ctrl('E'): /* ctrl+e, go to the end of the line */ case SPECIAL_END: current->pos = current->chars; refreshLine(current->prompt, current); break; - default: - /* Only tab is allowed without ^V */ - if (c == '\t' || c >= ' ') { - if (insert_char(current, current->pos, c) == 1) { - refreshLine(current->prompt, current); - } - } - break; case ctrl('U'): /* Ctrl+u, delete to beginning of line. */ if (remove_chars(current, 0, current->pos)) { refreshLine(current->prompt, current); @@ -1193,21 +1194,20 @@ process_char: refreshLine(current->prompt, current); } break; - case ctrl('A'): /* Ctrl+a, go to the start of the line */ - current->pos = 0; - refreshLine(current->prompt, current); - break; - case ctrl('E'): /* ctrl+e, go to the end of the line */ - current->pos = current->chars; - refreshLine(current->prompt, current); - break; case ctrl('L'): /* Ctrl+L, clear screen */ - /* clear screen */ clearScreen(current); /* Force recalc of window size for serial terminals */ current->cols = 0; refreshLine(current->prompt, current); break; + default: + /* Only tab is allowed without ^V */ + if (c == '\t' || c >= ' ') { + if (insert_char(current, current->pos, c) == 1) { + refreshLine(current->prompt, current); + } + } + break; } } return current->len; @@ -1256,10 +1256,16 @@ int linenoiseHistoryAdd(const char *line) { if (history_max_len == 0) return 0; if (history == NULL) { - history = (char**)malloc(sizeof(char*)*history_max_len); + history = (char **)malloc(sizeof(char*)*history_max_len); if (history == NULL) return 0; memset(history,0,(sizeof(char*)*history_max_len)); } + + /* do not insert duplicate lines into history */ + if (history_len > 0 && strcmp(line, history[history_len - 1]) == 0) { + return 0; + } + linecopy = strdup(line); if (!linecopy) return 0; if (history_len == history_max_len) { @@ -1279,7 +1285,7 @@ int linenoiseHistorySetMaxLen(int len) { if (history) { int tocopy = history_len; - newHistory = (char**)malloc(sizeof(char*)*len); + newHistory = (char **)malloc(sizeof(char*)*len); if (newHistory == NULL) return 0; if (len < tocopy) tocopy = len; memcpy(newHistory,history+(history_max_len-tocopy), sizeof(char*)*tocopy); -- cgit v1.1