]> git.lizzy.rs Git - linenoise.git/blobdiff - linenoise.c
linenoise: Allow a completion callback user parameter
[linenoise.git] / linenoise.c
index 3e0243965c5377e33729739b6bf5437e4c83c963..de4f58dcda70c800459de510f96f75779b744e2f 100644 (file)
@@ -239,8 +239,8 @@ fatal:
     /* input modes: no break, no CR to NL, no parity check, no strip char,
      * no start/stop output control. */
     raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
-    /* output modes - disable post processing */
-    raw.c_oflag &= ~(OPOST);
+    /* output modes - actually, no need to disable post processing */
+    /*raw.c_oflag &= ~(OPOST);*/
     /* control modes - set 8 bit chars */
     raw.c_cflag |= (CS8);
     /* local modes - choing off, canonical off, no extended functions,
@@ -293,9 +293,9 @@ static void fd_printf(int fd, const char *format, ...)
     IGNORE_RC(write(fd, buf, n));
 }
 
-static void clearScreen(struct current *current)
+void linenoiseClearScreen(void)
 {
-    fd_printf(current->fd, "\x1b[H\x1b[2J");
+    fd_printf(STDOUT_FILENO, "\x1b[H\x1b[2J");
 }
 
 static void cursorToLeft(struct current *current)
@@ -320,7 +320,12 @@ static void eraseEol(struct current *current)
 
 static void setCursorPos(struct current *current, int x)
 {
-    fd_printf(current->fd, "\r\x1b[%dC", x);
+    if (x == 0) {
+        cursorToLeft(current);
+    }
+    else {
+        fd_printf(current->fd, "\r\x1b[%dC", x);
+    }
 }
 
 /**
@@ -627,24 +632,29 @@ static void disableRawMode(struct current *current)
     SetConsoleMode(current->inh, orig_consolemode);
 }
 
-static void clearScreen(struct current *current)
+void linenoiseClearScreen(void)
 {
+    HANDLE fh = GetStdHandle(STD_OUTPUT_HANDLE);
+
     COORD topleft = { 0, 0 };
     DWORD n;
 
-    FillConsoleOutputCharacter(current->outh, ' ',
+    FillConsoleOutputCharacter(fh, ' ',
         current->cols * current->rows, topleft, &n);
-    FillConsoleOutputAttribute(current->outh,
+    FillConsoleOutputAttribute(fh,
         FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN,
         current->cols * current->rows, topleft, &n);
-    SetConsoleCursorPosition(current->outh, topleft);
+    SetConsoleCursorPosition(fh, topleft);
 }
 
 static void cursorToLeft(struct current *current)
 {
-    COORD pos = { 0, (SHORT)current->y };
+    COORD pos;
     DWORD n;
 
+    pos.X = 0;
+    pos.Y = (SHORT)current->y;
+
     FillConsoleOutputAttribute(current->outh,
         FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, current->cols, pos, &n);
     current->x = 0;
@@ -652,9 +662,12 @@ static void cursorToLeft(struct current *current)
 
 static int outputChars(struct current *current, const char *buf, int len)
 {
-    COORD pos = { (SHORT)current->x, (SHORT)current->y };
+    COORD pos;
     DWORD n;
 
+    pos.X = (SHORT)current->x;
+    pos.Y = (SHORT)current->y;
+
     WriteConsoleOutputCharacter(current->outh, buf, len, pos, &n);
     current->x += len;
     return 0;
@@ -662,9 +675,12 @@ static int outputChars(struct current *current, const char *buf, int len)
 
 static void outputControlChar(struct current *current, char ch)
 {
-    COORD pos = { (SHORT)current->x, (SHORT)current->y };
+    COORD pos;
     DWORD n;
 
+    pos.X = (SHORT) current->x;
+    pos.Y = (SHORT) current->y;
+
     FillConsoleOutputAttribute(current->outh, BACKGROUND_INTENSITY, 2, pos, &n);
     outputChars(current, "^", 1);
     outputChars(current, &ch, 1);
@@ -672,15 +688,21 @@ static void outputControlChar(struct current *current, char ch)
 
 static void eraseEol(struct current *current)
 {
-    COORD pos = { (SHORT)current->x, (SHORT)current->y };
+    COORD pos;
     DWORD n;
 
+    pos.X = (SHORT) current->x;
+    pos.Y = (SHORT) current->y;
+
     FillConsoleOutputCharacter(current->outh, ' ', current->cols - current->x, pos, &n);
 }
 
 static void setCursorPos(struct current *current, int x)
 {
-    COORD pos = { (SHORT)x, (SHORT)current->y };
+    COORD pos;
+
+    pos.X = (SHORT)x;
+    pos.Y = (SHORT) current->y;
 
     SetConsoleCursorPosition(current->outh, pos);
     current->x = x;
@@ -1041,6 +1063,7 @@ static int insert_chars(struct current *current, int pos, const char *chars)
 
 #ifndef NO_COMPLETION
 static linenoiseCompletionCallback *completionCallback = NULL;
+static void *completionUserdata = NULL;
 
 static void beep() {
 #ifdef USE_TERMIOS
@@ -1060,7 +1083,7 @@ static int completeLine(struct current *current) {
     linenoiseCompletions lc = { 0, NULL };
     int c = 0;
 
-    completionCallback(current->buf,&lc);
+    completionCallback(current->buf,&lc,completionUserdata);
     if (lc.len == 0) {
         beep();
     } else {
@@ -1110,9 +1133,14 @@ static int completeLine(struct current *current) {
     return c; /* Return last read character */
 }
 
-/* Register a callback function to be called for tab-completion. */
-void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) {
+/* Register a callback function to be called for tab-completion.
+   Returns the prior callback so that the caller may (if needed)
+   restore it when done. */
+linenoiseCompletionCallback * linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn, void *userdata) {
+    linenoiseCompletionCallback * old = completionCallback;
     completionCallback = fn;
+    completionUserdata = userdata;
+    return old;
 }
 
 void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) {
@@ -1406,7 +1434,7 @@ history_navigation:
             }
             break;
         case ctrl('L'): /* Ctrl+L, clear screen */
-            clearScreen(current);
+            linenoiseClearScreen();
             /* Force recalc of window size for serial terminals */
             current->cols = 0;
             refreshLine(current->prompt, current);