From 15ea795648aa4a4a8aee366914ffe277a5e0c03c Mon Sep 17 00:00:00 2001 From: Steve Bennett Date: Fri, 1 Oct 2010 06:07:42 +1000 Subject: [PATCH] Handle control characters in the line Only allow tab (^I) to be inserted in the line, not other control characters. But display any control character as ^x and handle the cursor properly. Signed-off-by: Steve Bennett --- linenoise.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/linenoise.c b/linenoise.c index 96e4369..cb29fa0 100644 --- a/linenoise.c +++ b/linenoise.c @@ -189,6 +189,8 @@ static int getColumns(void) { static void refreshLine(int fd, const char *prompt, char *buf, size_t len, size_t pos, size_t cols) { char seq[64]; size_t plen = strlen(prompt); + int extra = 0; + size_t i, p; while((plen+pos) >= cols) { buf++; @@ -204,12 +206,26 @@ static void refreshLine(int fd, const char *prompt, char *buf, size_t len, size_ if (write(fd,seq,strlen(seq)) == -1) return; /* Write the prompt and the current buffer content */ if (write(fd,prompt,strlen(prompt)) == -1) return; - if (write(fd,buf,len) == -1) return; + /* Need special handling for control characters */ + p = 0; + for (i = 0; i < len; i++) { + if (buf[i] < ' ') { + write(fd, buf + p, i - p); + p = i + 1; + seq[0] = '^'; + seq[1] = buf[i] + '@'; + write(fd, seq, 2); + if (i < pos) { + extra++; + } + } + } + write(fd, buf + p, i - p); /* Erase to right */ snprintf(seq,64,"\x1b[0K"); if (write(fd,seq,strlen(seq)) == -1) return; /* Move cursor to original position. */ - snprintf(seq,64,"\x1b[0G\x1b[%dC", (int)(pos+plen)); + snprintf(seq,64,"\x1b[0G\x1b[%dC", (int)(pos+plen+extra)); if (write(fd,seq,strlen(seq)) == -1) return; } @@ -426,8 +442,9 @@ up_down_arrow: } break; default: - if (len < buflen) { - if (len == pos) { + /* Note that the only control character currently permitted is tab */ + if (len < buflen && (c == '\t' || c >= ' ')) { + if (len == pos && c >= ' ') { buf[pos] = c; pos++; len++; -- 2.44.0