diff --git a/src/slash.c b/src/slash.c index c2e541e..f8d2fa6 100644 --- a/src/slash.c +++ b/src/slash.c @@ -173,6 +173,11 @@ static int slash_write(struct slash *slash, const char *buf, size_t count) return fwrite(buf, 1, count, slash->file_write) == count ? (int)count : -1; } +static int slash_write_flush(struct slash *slash) +{ + return fflush(slash->file_write) == 0 ? 0 : -1; +} + static int slash_read(struct slash *slash, void *buf, size_t count) { return fread(buf, 1, count, slash->file_read) == count ? (int)count : -1; @@ -906,37 +911,48 @@ static bool slash_history_previous(struct slash *slash) } /* Line editing */ +static int slash_cursor_back(struct slash *slash, size_t n) +{ + /* If we need to move more than 3 colums, CUB uses fewer bytes */ + if (n > 3) { + slash_printf(slash, ESCAPE("%zuD"), n); + } else { + while (n--) + slash_putchar(slash, '\b'); + } + + return 0; +} int slash_refresh(struct slash *slash) { const char *esc = ESCAPE("K"); if (slash->refresh_full) { slash_putchar(slash, '\r'); - if (slash_write(slash, slash->prompt, slash->prompt_length) < 0) - return -1; if (slash_write(slash, esc, strlen(esc)) < 0) return -1; + if (slash_write(slash, slash->prompt, slash->prompt_length) < 0) + return -1; slash->cursor_screen = 0; slash->length_screen = 0; slash->refresh_full = false; } if (slash->refresh_buffer) { - while (slash->cursor_screen > 0) { - slash_putchar(slash, '\b'); - slash->cursor_screen--; - } + slash_cursor_back(slash, slash->cursor_screen); + slash->cursor_screen = 0; slash->refresh_buffer = false; } - while (slash->cursor_screen != slash->cursor) { - if (slash->cursor_screen < slash->cursor) { - slash_putchar(slash, slash->buffer[slash->cursor_screen]); - slash->cursor_screen++; - } else if (slash->cursor_screen > slash->cursor) { - slash_putchar(slash, '\b'); - slash->cursor_screen--; - } + while (slash->cursor_screen < slash->cursor) { + slash_putchar(slash, slash->buffer[slash->cursor_screen]); + slash->cursor_screen++; + } + + if (slash->cursor_screen > slash->cursor) { + slash_cursor_back(slash, + slash->cursor_screen - slash->cursor); + slash->cursor_screen = slash->cursor; } if (slash->length_screen != slash->length) { @@ -951,15 +967,16 @@ int slash_refresh(struct slash *slash) return -1; } - while (slash->cursor_screen > slash->cursor) { - slash_putchar(slash, '\b'); - slash->cursor_screen--; + if (slash->cursor_screen > slash->cursor) { + slash_cursor_back(slash, + slash->cursor_screen - slash->cursor); + slash->cursor_screen = slash->cursor; } slash->length_screen = slash->length; } - return 0; + return slash_write_flush(slash); } static void slash_insert(struct slash *slash, int c) @@ -1335,10 +1352,6 @@ int slash_init(struct slash *slash, /* Set default prompt */ slash_set_prompt(slash, "slash> "); - /* Disable stream buffering */ - setvbuf(slash->file_read, NULL, _IONBF, 0); - setvbuf(slash->file_write, NULL, _IONBF, 0); - /* Initialize line buffer */ slash->buffer = line; slash->line_size = line_size;