API converted to be readline alike. Ctrl-d behavior fixed.

This commit is contained in:
antirez
2010-03-22 17:24:28 +01:00
parent 17a7d33e79
commit 2c54c88c46
3 changed files with 24 additions and 14 deletions

View File

@@ -3,17 +3,14 @@
#include "linenoise.h" #include "linenoise.h"
int main(void) { int main(void) {
char buf[1024]; char *line;
int retval;
while(1) { while((line = linenoise("hello> ")) != NULL) {
retval = linenoise(buf,1024,"hello> "); if (line[0] != '\0') {
if (retval > 0) { printf("echo: '%s'\n", line);
printf("echo: '%s'\n", buf); linenoiseHistoryAdd(line);
linenoiseHistoryAdd(buf);
} else if (retval == -1) {
exit(1);
} }
free(line);
} }
return 0; return 0;
} }

View File

@@ -80,6 +80,8 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <unistd.h> #include <unistd.h>
#define LINENOISE_MAX_LINE 4096
static struct termios orig_termios; /* in order to restore at exit */ static struct termios orig_termios; /* in order to restore at exit */
static int rawmode = 0; /* for atexit() function to check if restore is needed*/ static int rawmode = 0; /* for atexit() function to check if restore is needed*/
static int atexit_registered = 0; /* register atexit just 1 time */ static int atexit_registered = 0; /* register atexit just 1 time */
@@ -154,7 +156,7 @@ static int getColumns(void) {
return ws.ws_col; return ws.ws_col;
} }
static void refreshLine(int fd, char *prompt, char *buf, size_t len, size_t pos, size_t cols) { static void refreshLine(int fd, const char *prompt, char *buf, size_t len, size_t pos, size_t cols) {
char seq[64]; char seq[64];
size_t plen = strlen(prompt); size_t plen = strlen(prompt);
@@ -181,7 +183,7 @@ static void refreshLine(int fd, char *prompt, char *buf, size_t len, size_t pos,
if (write(fd,seq,strlen(seq)) == -1) return; if (write(fd,seq,strlen(seq)) == -1) return;
} }
static int linenoisePrompt(int fd, char *buf, size_t buflen, char *prompt) { static int linenoisePrompt(int fd, char *buf, size_t buflen, const char *prompt) {
size_t plen = strlen(prompt); size_t plen = strlen(prompt);
size_t pos = 0; size_t pos = 0;
size_t len = 0; size_t len = 0;
@@ -205,9 +207,11 @@ static int linenoisePrompt(int fd, char *buf, size_t buflen, char *prompt) {
if (nread <= 0) return len; if (nread <= 0) return len;
switch(c) { switch(c) {
case 13: /* enter */ case 13: /* enter */
case 4: /* ctrl+d */
history_len--; history_len--;
return len; return len;
case 4: /* ctrl+d */
history_len--;
return (len == 0) ? -1 : (int)len;
case 3: /* ctrl+c */ case 3: /* ctrl+c */
errno = EAGAIN; errno = EAGAIN;
return -1; return -1;
@@ -302,7 +306,7 @@ static int linenoisePrompt(int fd, char *buf, size_t buflen, char *prompt) {
return len; return len;
} }
int linenoise(char *buf, size_t buflen, char *prompt) { static int linenoiseRaw(char *buf, size_t buflen, const char *prompt) {
int fd = STDIN_FILENO; int fd = STDIN_FILENO;
int count; int count;
@@ -317,6 +321,15 @@ int linenoise(char *buf, size_t buflen, char *prompt) {
return count; return count;
} }
char *linenoise(const char *prompt) {
char buf[LINENOISE_MAX_LINE];
int count;
count = linenoiseRaw(buf,LINENOISE_MAX_LINE,prompt);
if (count == -1) return NULL;
return strdup(buf);
}
/* Using a circular buffer is smarter, but a bit more complex to handle. */ /* Using a circular buffer is smarter, but a bit more complex to handle. */
int linenoiseHistoryAdd(char *line) { int linenoiseHistoryAdd(char *line) {
if (history_max_len == 0) return 0; if (history_max_len == 0) return 0;

View File

@@ -34,7 +34,7 @@
#ifndef __LINENOISE_H #ifndef __LINENOISE_H
#define __LINENOISE_H #define __LINENOISE_H
int linenoise(char *buf, size_t buflen, char *prompt); char *linenoise(const char *prompt);
int linenoiseHistoryAdd(char *line); int linenoiseHistoryAdd(char *line);
int linenoiseHistorySetMaxLen(int len); int linenoiseHistorySetMaxLen(int len);