From 82d592d574ef3665b322297039cf23097d11ceb4 Mon Sep 17 00:00:00 2001 From: Anders Holck Date: Wed, 29 Apr 2026 12:48:58 +0200 Subject: [PATCH] Fix input line wrapping pushing chat up - Horizontal scroll for input when exceeding terminal width - Never wraps to next line or disturbs scroll region --- main.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 9c5b1bf..a027efc 100644 --- a/main.c +++ b/main.c @@ -768,10 +768,58 @@ static size_t utf8_back(const char *buf, size_t pos) static void redraw_input(const char *input_line, size_t input_len, size_t input_pos) { + int avail = term_cols - 2; /* columns available after "> " */ + size_t total_cols = display_cols(input_line, input_len); size_t cpos_cols = display_cols(input_line, input_pos); + printf("\033[%d;1H\033[K\033[32m>\033[0m ", term_rows); - fwrite(input_line, 1, input_len, stdout); - printf("\033[%d;%dH", term_rows, (int)(cpos_cols + 3)); + + if ((int)total_cols <= avail) { + /* Fits entirely */ + fwrite(input_line, 1, input_len, stdout); + printf("\033[%d;%dH", term_rows, (int)(cpos_cols + 3)); + } else { + /* Scroll horizontally: show a window around cursor */ + size_t win_start_bytes = 0; + size_t win_start_cols = 0; + + /* If cursor is past the visible area, shift window */ + if ((int)cpos_cols >= avail) { + /* Move window so cursor is near the right edge */ + size_t target_cols = cpos_cols - (size_t)(avail - 1); + size_t i = 0, cols = 0; + while (i < input_len && cols < target_cols) { + unsigned char c = (unsigned char)input_line[i]; + if (c < 0x80) i++; + else if ((c & 0xE0) == 0xC0) i += 2; + else if ((c & 0xF0) == 0xE0) i += 3; + else if ((c & 0xF8) == 0xF0) i += 4; + else i++; + cols++; + } + win_start_bytes = i; + win_start_cols = cols; + } + + /* Write characters that fit in avail columns */ + size_t i = win_start_bytes; + int cols_written = 0; + while (i < input_len && cols_written < avail) { + unsigned char c = (unsigned char)input_line[i]; + size_t clen = 1; + if (c >= 0x80) { + if ((c & 0xE0) == 0xC0) clen = 2; + else if ((c & 0xF0) == 0xE0) clen = 3; + else if ((c & 0xF8) == 0xF0) clen = 4; + } + fwrite(input_line + i, 1, clen, stdout); + i += clen; + cols_written++; + } + + int cursor_col = (int)(cpos_cols - win_start_cols + 3); + printf("\033[%d;%dH", term_rows, cursor_col); + } fflush(stdout); }