#include <cmd_proc.h>
#include "cmd_proc_priv.h"
#include <string.h>
+#include <ctype.h>
/* cmd_io line editor */
return 1;
}
+static void replace_history(ed_line_buf_t *el, cmd_io_t* io_stack)
+{
+ if(!el->lastch)
+ el->inbuf=0; /* Make inbuf consistent */
+ while (el->inbuf) { /* Delete previous input */
+ el->inbuf--;
+ while (cmd_io_putc(io_stack,'\b') < 0);
+ }
+ if (el->hist_idx >= 0) {
+ strncpy(el->buf, el->hist + el->hist_idx*el->alloc, el->alloc);
+ while (el->buf[el->inbuf]) {
+ el->lastch = el->buf[el->inbuf++];
+ while (cmd_io_putc(io_stack, el->lastch) < 0);
+ }
+ }
+ cmd_io_puts(io_stack, "\033[K"); /* Erase End of Line */
+}
+
+/**
+ * @return One when the character was consumed, zero otherwise.
+ */
+static int handle_history(ed_line_buf_t *el, char ch, cmd_io_t* io_stack)
+{
+ enum { NONE, UP, DOWN } dir = NONE;
+
+ if (!(el->hist && el->hist_size && el->hist_size >= 2*el->alloc))
+ return 0;
+
+ switch (ch) {
+ case 14: /* Ctrl-N */
+ dir = DOWN;
+ break;
+ case 16: /* Ctrl-P */
+ dir = UP;
+ break;
+ case '\033': /* ESC */
+ strcpy(el->esc, "\033");
+ return 1;
+ default:
+ if (!el->esc[0])
+ return 0;
+
+ char *p = el->esc+1;
+ while (*p && p < el->esc + sizeof(el->esc) - 2) p++;
+ if (!*p) {
+ p[0] = ch;
+ p[1] = 0;
+ }
+ if (isalpha(ch)) {
+ if (strcmp(el->esc, "\033[A") == 0) dir = UP;
+ else if (strcmp(el->esc, "\033[B") == 0) dir = DOWN;
+ el->esc[0] = 0;
+ }
+ if (dir == NONE)
+ return 1;
+ }
+
+ if (dir == DOWN) {
+ if (el->hist_idx >= 0)
+ el->hist_idx--;
+ else
+ return 1;
+ } else if (dir == UP) {
+ if ((el->hist_idx+2) * el->alloc <= el->hist_size &&
+ el->hist[(el->hist_idx+1) * el->alloc])
+ el->hist_idx++;
+ else
+ return 1;
+ }
+
+ replace_history(el, io_stack);
+ return 1;
+}
+
/* process input & perform echo if requested */
int cmd_io_line_in(cmd_io_t *cmd_io)
{
while((ch=cmd_io_getc(io_stack))>=0){
// DPRINT("Added %c (%d)\n", ch, ch);
+ if (handle_history(el, ch, io_stack) == 1)
+ continue;
int eol = cmd_ed_line_buf(el,ch);
if (eol == -1)
return -1;
while(cmd_io_putc(io_stack,'\r')<0);
while(cmd_io_putc(io_stack,'\n')<0);
}
+ if (el->hist && el->hist_size) {
+ el->hist_idx = -1;
+ if ((el->hist[0] && strcmp(el->buf, el->hist) == 0) || /* The same command as before */
+ !el->buf[0]) /* Empty line */
+ return 1; /* Don't add to the history */
+ memmove(el->hist + el->alloc, el->hist, el->hist_size - el->alloc);
+ strncpy(el->hist, el->buf, el->alloc);
+ }
return 1;
}
else