diff options
author | Jefferson Delfes <jefferson.delfes@gmail.com> | 2013-11-04 15:33:59 -0400 |
---|---|---|
committer | Jefferson Delfes <jefferson.delfes@gmail.com> | 2013-11-11 14:56:29 -0400 |
commit | f37a794ccd52c449890247c64fae17c1001b1bb5 (patch) | |
tree | e1868c3a66b6bda01dc45f44bea804c110fcee25 | |
parent | 52c4a6088f541da9480569af7dad3951e0b51d33 (diff) |
rl_helper: add history command management
We need a growable buffer which will store a list of command strings. So
when we press up or down keys, our line buffer is replaced with old
commands that we typed.
This also fix a possible bug, when we pass a copy of line buffer to line
processing callback. So we will not have problems if we change its value
(eg strtok).
-rw-r--r-- | rl_helper.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/rl_helper.c b/rl_helper.c index b066600..62a5cbe 100644 --- a/rl_helper.c +++ b/rl_helper.c @@ -60,6 +60,9 @@ size_t pos = 0; char seq[MAX_SEQ]; /* sequence buffer (escape codes) */ size_t seq_pos = 0; const char *prompt = "> "; +char **history = NULL; /* pointer to history buffer */ +int hs_len = 0; /* how much pointers we have in history buffer */ +int hs_cur = 0; /* current position of up/down keys navigation */ typedef struct { char sequence[MAX_SEQ]; @@ -223,8 +226,20 @@ bool rl_feed(int c) { break; case '\r': case '\n': - putchar('\n'); - line_cb(lnbuf); + if (strlen(lnbuf) > 0) { + char *dup = strdup(lnbuf); + /* alloc space in history buffer to new string pointer */ + hs_len++; + history = realloc(history, hs_len * sizeof(history[0])); + history[hs_len - 1] = strdup(lnbuf); + putchar('\n'); + line_cb(dup); /* send a copy, so we can change it */ + free(dup); + } else + /* don't parse empty lines */ + putchar('\n'); + + hs_cur = hs_len; rl_clear(); rl_reprint_prompt(); break; @@ -238,8 +253,27 @@ bool rl_feed(int c) { } break; case K_UP: + if (hs_cur > 0) { + /* we have more history commands up */ + hs_cur--; + strcpy(lnbuf, history[hs_cur]); + pos = strlen(history[hs_cur]); + rl_reprint_prompt(); + } + break; case K_DOWN: - /* history handle */ + if (hs_cur < hs_len - 1) { + /* we have more history commands down */ + hs_cur++; + strcpy(lnbuf, history[hs_cur]); + pos = strlen(history[hs_cur]); + rl_reprint_prompt(); + } else if (hs_cur == hs_len - 1) { + /* we don't have more commands down, let's clear the prompt */ + hs_cur++; + rl_clear(); + rl_reprint_prompt(); + } break; case K_RIGHT: if (pos < strlen(lnbuf)) { |