From 3a935b87350c1e38fc363ff37590b10ef64b947b Mon Sep 17 00:00:00 2001 From: Jeppe Ledet-Pedersen Date: Thu, 10 Jul 2025 20:35:50 +0200 Subject: [PATCH 1/2] slash: use explicit flush and reenable stream buffering Consolidate the writes into fewer syscalls. --- src/slash.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/slash.c b/src/slash.c index c2e541e..7b840b7 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; @@ -912,10 +917,10 @@ int slash_refresh(struct slash *slash) 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; @@ -959,7 +964,7 @@ int slash_refresh(struct slash *slash) slash->length_screen = slash->length; } - return 0; + return slash_write_flush(slash); } static void slash_insert(struct slash *slash, int c) @@ -1335,10 +1340,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; From 9414e1821560851ab0960b343d175e06cf3a54c9 Mon Sep 17 00:00:00 2001 From: Jeppe Ledet-Pedersen Date: Thu, 10 Jul 2025 20:57:38 +0200 Subject: [PATCH 2/2] slash: use CUB to move cursor back --- src/slash.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/src/slash.c b/src/slash.c index 7b840b7..f8d2fa6 100644 --- a/src/slash.c +++ b/src/slash.c @@ -911,6 +911,18 @@ 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"); @@ -927,21 +939,20 @@ int slash_refresh(struct slash *slash) } 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) { @@ -956,9 +967,10 @@ 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;