in system/cle/cle.c [675:1030]
static int cle_editloop(FAR struct cle_s *priv)
{
/* Loop while we are in command mode */
for (; ; )
{
#if 1 /* Perhaps here should be a config switch */
char state = 0;
#endif
int ch;
/* Make sure that the display reflects the current state */
cle_showtext(priv);
cle_setcursor(priv, priv->curpos);
/* Get the next character from the input */
#if 1 /* Perhaps here should be a config switch */
/* Simple decode of some VT100/xterm codes: left/right, up/dn,
* home/end, del
*/
/* loop till we have a ch */
for (; ; )
{
ch = cle_getch(priv);
if (ch < 0)
{
return -EIO;
}
else if (state != 0)
{
if (state == (char)1) /* Got ESC */
{
if (ch == '[' || ch == 'O')
{
state = ch;
}
else
{
break; /* break the for loop */
}
}
else if (state == '[')
{
/* Got ESC[ */
switch (ch)
{
case '3': /* ESC[3~ = DEL */
{
state = ch;
continue;
}
case 'A':
{
ch = KEY_UP;
}
break;
case 'B':
{
ch = KEY_DN;
}
break;
case 'C':
{
ch = KEY_RIGHT;
}
break;
case 'D':
{
ch = KEY_LEFT;
}
break;
case 'F':
{
ch = KEY_ENDLINE;
}
break;
case 'H':
{
ch = KEY_BEGINLINE;
}
break;
default:
break;
}
break; /* Break the 'for' loop */
}
else if (state == 'O')
{
/* got ESCO */
if (ch == 'F')
{
ch = KEY_ENDLINE;
}
break; /* Break the 'for' loop */
}
else if (state == '3')
{
if (ch == '~')
{
ch = KEY_DEL;
}
break; /* Break the 'for' loop */
}
else
{
break; /* Break the 'for' loop */
}
}
else if (ch == ASCII_ESC)
{
++state;
}
else
{
break; /* Break the 'for' loop, use the char */
}
}
#else
ch = cle_getch(priv);
if (ch < 0)
{
return -EIO;
}
#endif
/* Then handle the character. */
#ifdef CONFIG_SYSTEM_CLE_CMD_HISTORY
if (g_cmd_history_len > 0)
{
int i = 1;
switch (ch)
{
case KEY_UP:
/* Go to the past command in history */
g_cmd_history_steps_from_head--;
if (-g_cmd_history_steps_from_head >= g_cmd_history_len)
{
g_cmd_history_steps_from_head = -(g_cmd_history_len - 1);
}
break;
case KEY_DN:
/* Go to the recent command in history */
g_cmd_history_steps_from_head++;
if (g_cmd_history_steps_from_head > 1)
{
g_cmd_history_steps_from_head = 1;
}
break;
default:
i = 0;
break;
}
if (i != 0)
{
priv->nchars = 0;
priv->curpos = 0;
if (g_cmd_history_steps_from_head != 1)
{
int idx = g_cmd_history_head +
g_cmd_history_steps_from_head;
/* Circular buffer wrap around */
if (idx < 0)
{
idx = idx + CONFIG_SYSTEM_CLE_CMD_HISTORY_LEN;
}
else if (idx >= CONFIG_SYSTEM_CLE_CMD_HISTORY_LEN)
{
idx = idx - CONFIG_SYSTEM_CLE_CMD_HISTORY_LEN;
}
for (i = 0; g_cmd_history[idx][i] != '\0'; i++)
{
cle_insertch(priv, g_cmd_history[idx][i]);
}
priv->curpos = priv->nchars;
}
continue;
}
}
#endif /* CONFIG_SYSTEM_CLE_CMD_HISTORY */
switch (ch)
{
case KEY_BEGINLINE: /* Move cursor to start of current line */
{
priv->curpos = 0;
}
break;
case KEY_LEFT: /* Move the cursor left 1 character */
{
if (priv->curpos > 0)
{
priv->curpos--;
}
else
{
CLE_BEL(priv);
}
}
break;
case KEY_DEL: /* Delete 1 character at the cursor */
{
if (priv->curpos < priv->nchars)
{
cle_closetext(priv, priv->curpos, 1);
}
else
{
CLE_BEL(priv);
}
}
break;
case KEY_ENDLINE: /* Move cursor to end of current line */
{
priv->curpos = priv->nchars;
}
break;
case KEY_RIGHT: /* Move the cursor right one character */
{
if (priv->curpos < priv->nchars)
{
priv->curpos++;
}
else
{
CLE_BEL(priv);
}
}
break;
case ASCII_DEL:
case KEY_DELLEFT: /* Delete 1 character before the cursor */
{
if (priv->curpos > 0)
{
cle_closetext(priv, --priv->curpos, 1);
}
else
{
CLE_BEL(priv);
}
}
break;
case KEY_DELEOL: /* Delete to the end of the line */
{
priv->nchars = (priv->nchars > 0 ? priv->curpos : 0);
}
break;
case KEY_DELLINE: /* Delete to the end of the line */
{
priv->nchars = 0;
priv->curpos = 0;
}
break;
case KEY_CLRSCR: /* Clear the screen & return cursor to top */
cle_clrscr(priv);
break;
case KEY_QUOTE: /* Quoted character follows */
{
ch = cle_getch(priv);
if (ch < 0)
{
return -EIO;
}
/* Insert the next character unconditionally */
cle_insertch(priv, ch);
}
break;
/* Newline terminates editing. But what is a newline? */
case '\n': /* LF terminates line */
{
/* Add the newline to the buffer at the end of the line */
priv->curpos = priv->nchars;
cle_insertch(priv, '\n');
return OK;
}
break;
/* Text to insert or unimplemented/invalid keypresses */
default:
{
/* Ignore all control characters except for tab and newline */
if (!iscntrl(ch) || ch == '\t')
{
/* Insert the filtered character into the buffer */
cle_insertch(priv, ch);
/* Printable character will change the cursor position in */
if (ch != '\t')
{
priv->realpos++;
}
}
else
{
CLE_BEL(priv);
}
}
break;
}
}
return OK;
}