X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=interactive.c;h=3af90a6814d79e248178a3e47ae04cd066a8efad;hb=e854df2fe2cfb3ae90a439828fc13cc0fc470aa9;hp=190cdf295130a2d711074e7c5f5927174b312076;hpb=2031b9cab9304b02c0372f73eef54d9501277031;p=paraslash.git diff --git a/interactive.c b/interactive.c index 190cdf29..3af90a68 100644 --- a/interactive.c +++ b/interactive.c @@ -45,7 +45,7 @@ static struct i9e_private i9e_private, *i9ep = &i9e_private; * running. * * \return A negative return value of zero means the i9e task terminated. Only - * in this case it is safe to call ie9_close(). + * in this case it is safe to call i9e_close(). */ int i9e_get_error(void) { @@ -258,18 +258,6 @@ static void clear_bottom_line(void) rl_point = point; } -static bool input_available(void) -{ - fd_set rfds; - struct timeval tv = {0, 0}; - int ret; - - FD_ZERO(&rfds); - FD_SET(i9ep->ici->fds[0], &rfds); - ret = para_select(1, &rfds, NULL, &tv); - return ret > 0; -} - static void i9e_line_handler(char *line) { int ret; @@ -310,24 +298,29 @@ static int i9e_post_select(__a_unused struct sched *s, __a_unused void *context) ret = 0; if (i9ep->caught_sigint) goto rm_btrn; - while (input_available()) { + while (read_ok(i9ep->ici->fds[0]) > 0) { if (i9ep->stdout_btrn) { - unsigned len = i9ep->key_sequence_length; - assert(len < sizeof(i9ep->key_sequence) - 1); - buf = i9ep->key_sequence + len; - ret = read(i9ep->ici->fds[0], buf, 1); - if (ret < 0) { - ret = -ERRNO_TO_PARA_ERROR(errno); - goto rm_btrn; + while (i9ep->key_sequence_length < sizeof(i9ep->key_sequence) - 1) { + buf = i9ep->key_sequence + i9ep->key_sequence_length; + ret = read(i9ep->ici->fds[0], buf, 1); + if (ret < 0) { + ret = -ERRNO_TO_PARA_ERROR(errno); + goto rm_btrn; + } + if (ret == 0) { + ret = -E_I9E_EOF; + goto rm_btrn; + } + buf[1] = '\0'; + i9ep->key_sequence_length++; + rl_stuff_char((int)(unsigned char)*buf); + rl_callback_read_char(); + if (read_ok(i9ep->ici->fds[0]) <= 0) + break; } - ret = -E_I9E_EOF; - if (ret == 0) - goto rm_btrn; - buf[1] = '\0'; - i9ep->key_sequence_length++; - rl_stuff_char((int)(unsigned char)*buf); - } - rl_callback_read_char(); + i9ep->key_sequence_length = 0; + } else + rl_callback_read_char(); ret = 0; } if (!i9ep->stdout_btrn) @@ -556,7 +549,7 @@ __printf_2_3 void i9e_log(int ll, const char* fmt,...) * the given text. If the length of this text exceeds the width of the * terminal, the text is shortened by leaving out a part in the middle. */ -void ie9_print_status_bar(char *buf, unsigned len) +void i9e_print_status_bar(char *buf, unsigned len) { size_t x = i9ep->num_columns, y = (x - 4) / 2; @@ -605,17 +598,20 @@ void i9e_signal_dispatch(int sig_num) * \param n \sa \ref para_select(). * \param readfds \sa \ref para_select(). * \param writefds \sa \ref para_select(). - * \param timeout_tv \sa \ref para_select(). + * \param timeout \sa \ref para_select(). * * \return \sa \ref para_select(). * * The only difference between this function and \ref para_select() is that * \ref i9e_select() returns zero if the select call returned \p EINTR. */ -int i9e_select(int n, fd_set *readfds, fd_set *writefds, - struct timeval *timeout_tv) +int i9e_select(int n, fd_set *readfds, fd_set *writefds, int timeout) { - int ret = select(n, readfds, writefds, NULL, timeout_tv); + struct timeval tv; + int ret; + + ms2tv(timeout, &tv); + ret = select(n, readfds, writefds, NULL, &tv); if (ret < 0) { if (errno == EINTR) @@ -762,17 +758,25 @@ int i9e_print_completions(struct i9e_completer *completers) ci.argc = create_argv(ci.buffer, " ", &ci.argv); ci.word_num = compute_word_num(ci.buffer, " ", ci.point); + /* determine the current word to complete */ end = ci.buffer + ci.point; + + if (*end == ' ') { + if (ci.point == 0 || ci.buffer[ci.point - 1] == ' ') { + ci.word = para_strdup(NULL); + goto create_matches; + } else /* The cursor is positioned right after a word */ + end--; + } for (p = end; p > ci.buffer && *p != ' '; p--) ; /* nothing */ if (*p == ' ') p++; - n = end - p + 1; ci.word = para_malloc(n + 1); strncpy(ci.word, p, n); ci.word[n] = '\0'; - +create_matches: PARA_DEBUG_LOG("line: %s, point: %d (%c), wordnum: %d, word: %s\n", ci.buffer, ci.point, ci.buffer[ci.point], ci.word_num, ci.word); if (ci.word_num == 0)