]> git.lizzy.rs Git - linenoise.git/commitdiff
Handle control characters in the line
authorSteve Bennett <steveb@workware.net.au>
Thu, 30 Sep 2010 20:07:42 +0000 (06:07 +1000)
committerSteve Bennett <steveb@workware.net.au>
Fri, 8 Apr 2011 01:37:19 +0000 (11:37 +1000)
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 <steveb@workware.net.au>
linenoise.c

index 96e4369d42bd9654e442abc85b4e1813b1627b46..cb29fa02b4b0f6bc3327b09345aaec0256e2e149 100644 (file)
@@ -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++;