Merged in nghiaho12/apps/command_history (pull request #3)
Added command history using up/down arrow keys.
This commit is contained in:
commit
b0e6db9b2e
@ -32,7 +32,15 @@ config READLINE_TABCOMPLETION
|
||||
depends on (BUILD_FLAT && BUILTIN) || READLINE_HAVE_EXTMATCH
|
||||
---help---
|
||||
Build in support for Unix-style tab completion. This feature was
|
||||
originally provided by Nghia.
|
||||
originally provided by Nghia Ho.
|
||||
|
||||
config READLINE_CMD_HISTORY_LEN
|
||||
int "Command line history"
|
||||
default 16
|
||||
depends on (BUILD_FLAT && BUILTIN) || READLINE_HAVE_EXTMATCH
|
||||
---help---
|
||||
Build in support for Unix-style command history using up and down arrow keys. This feature was
|
||||
originally provided by Nghia Ho.
|
||||
|
||||
if READLINE_TABCOMPLETION
|
||||
|
||||
|
@ -392,6 +392,12 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR char *buf, int buflen)
|
||||
int escape;
|
||||
int nch;
|
||||
|
||||
/* Nghia Ho: command history */
|
||||
static char cmd_history[CONFIG_READLINE_CMD_HISTORY_LEN][CONFIG_NSH_LINELEN]; /* circular buffer */
|
||||
static int cmd_history_head = -1; /* head of the circular buffer, most recent command */
|
||||
static int cmd_history_steps_from_head = 1; /* offset from head */
|
||||
static int cmd_history_len = 0; /* number of elements in the circular buffer */
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(buf && buflen > 0);
|
||||
@ -454,6 +460,63 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR char *buf, int buflen)
|
||||
{
|
||||
/* We are finished with the escape sequence */
|
||||
|
||||
/* Nghia Ho: intercept up and down arrow keys */
|
||||
if (cmd_history_len > 0)
|
||||
{
|
||||
if (ch == 'A') /* up arrow */
|
||||
{
|
||||
/* go to the past command in history */
|
||||
cmd_history_steps_from_head--;
|
||||
|
||||
if (-cmd_history_steps_from_head >= cmd_history_len)
|
||||
{
|
||||
cmd_history_steps_from_head = -(cmd_history_len - 1);
|
||||
}
|
||||
}
|
||||
else if (ch == 'B') /* down arrow */
|
||||
{
|
||||
/* go to the recent command in history */
|
||||
cmd_history_steps_from_head++;
|
||||
|
||||
if (cmd_history_steps_from_head > 1)
|
||||
{
|
||||
cmd_history_steps_from_head = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* clear out current command from the prompt */
|
||||
while (nch > 0)
|
||||
{
|
||||
nch--;
|
||||
|
||||
#ifdef CONFIG_READLINE_ECHO
|
||||
RL_PUTC(vtbl, ASCII_BS);
|
||||
RL_WRITE(vtbl, g_erasetoeol, sizeof(g_erasetoeol));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (cmd_history_steps_from_head != 1)
|
||||
{
|
||||
int idx = cmd_history_head + cmd_history_steps_from_head;
|
||||
|
||||
/* circular buffer wrap around */
|
||||
if (idx < 0)
|
||||
{
|
||||
idx = idx + CONFIG_READLINE_CMD_HISTORY_LEN;
|
||||
}
|
||||
else if (idx >= CONFIG_READLINE_CMD_HISTORY_LEN)
|
||||
{
|
||||
idx = idx - CONFIG_READLINE_CMD_HISTORY_LEN;
|
||||
}
|
||||
|
||||
for (int i=0; cmd_history[idx][i] != '\0'; i++)
|
||||
{
|
||||
buf[nch++] = cmd_history[idx][i];
|
||||
RL_PUTC(vtbl, cmd_history[idx][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
escape = 0;
|
||||
ch = 'a';
|
||||
}
|
||||
@ -520,6 +583,27 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR char *buf, int buflen)
|
||||
else if (ch == '\n' || ch == '\r')
|
||||
#endif
|
||||
{
|
||||
/* Nghia Ho: save history of command, only if there was something typed besides return character */
|
||||
if (nch >= 1)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
cmd_history_head = (cmd_history_head + 1) % CONFIG_READLINE_CMD_HISTORY_LEN;
|
||||
|
||||
for (i=0; (i < nch) && i < (CONFIG_NSH_LINELEN - 1); i++)
|
||||
{
|
||||
cmd_history[cmd_history_head][i] = buf[i];
|
||||
}
|
||||
|
||||
cmd_history[cmd_history_head][i] = '\0';
|
||||
cmd_history_steps_from_head = 1;
|
||||
|
||||
if (cmd_history_len < CONFIG_READLINE_CMD_HISTORY_LEN)
|
||||
{
|
||||
cmd_history_len++;
|
||||
}
|
||||
}
|
||||
|
||||
/* The newline is stored in the buffer along with the null
|
||||
* terminator.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user