in system/vi/vi.c [5172:5440]
static void vi_insert_mode(FAR struct vi_s *vi)
{
off_t start = vi->curpos;
int ch;
viinfo("Enter insert mode\n");
/* Print insert message */
vi_clearbottomline(vi);
vi_write(vi, g_fmtinsert, sizeof(g_fmtinsert));
vi_setcursor(vi, vi->cursor.row, vi->cursor.column);
vi->redrawline = true;
/* Loop while we are in insert mode */
while (vi->mode == MODE_INSERT || vi->mode == MODE_REPLACE)
{
/* Make sure that the display reflects the current state */
if (vi->redrawline || vi->drawtoeos || vi->fullredraw)
{
vi_showtext(vi);
}
/* Display the line and col number */
vi_showlinecol(vi);
vi_setcursor(vi, vi->cursor.row, vi->cursor.column);
/* Get the next character from the input */
#ifdef CONFIG_SYSTEM_VI_INCLUDE_COMMAND_REPEAT
/* Test for active cmdrepeat */
if (vi->cmdrepeat)
{
/* Read next command from command buffer */
ch = vi->cmdbuf[vi->cmdindex++];
}
else
#endif
{
ch = vi_getch(vi);
#ifdef CONFIG_SYSTEM_VI_INCLUDE_COMMAND_REPEAT
/* Any arrow, pgup, pgdn, etc. key resets command repeat */
if (ch == KEY_UP || ch == KEY_DOWN || ch == KEY_LEFT ||
ch == KEY_RIGHT || ch == KEY_HOME || ch == KEY_END ||
ch == KEY_PPAGE || ch == KEY_NPAGE)
{
vi->cmdcount = 1;
vi->redrawline = true;
}
else
{
vi_appendrepeat(vi, ch);
}
#endif
}
/* Test for printable character first since we will get mostly those,
* and this will give better performance.
*/
vi->updatereqcol = true;
if (isprint(ch) || ch == '\t')
{
/* Insert the filtered character into the buffer */
if (vi->mode == MODE_INSERT)
{
vi_insertch(vi, ch);
}
else
{
vi_replacech(vi, ch);
}
/* If we don't have to scroll the screen to display the
* character, then do a simple putch, otherwise request
* a line redraw.
*/
if (vi->cursor.column + 1 < vi->display.column && ch != '\t' &&
(vi->curpos + 1 == vi->textsize ||
vi->text[vi->curpos + 1] == '\n'))
{
vi_putch(vi, ch);
}
else
{
vi->redrawline = true;
}
vi->cursor.column++;
continue;
}
/* Any key press clears the error message */
vi->error = false;
vi->redrawline = true;
/* Handle the newly received character */
switch (ch)
{
case KEY_INSMODE_QUOTE: /* Quoted character follows */
{
/* Insert the next character unconditionally */
vi_insertch(vi, vi_getch(vi));
}
break;
case ASCII_DEL:
{
if (vi->curpos < vi->textsize)
{
if (vi->text[vi->curpos] == '\n')
{
vi->drawtoeos = true;
}
vi_shrinktext(vi, vi->curpos, 1);
}
}
break;
case ASCII_BS:
{
/* Backspace changes based on mode */
if (vi->mode == MODE_INSERT)
{
/* In insert mode, we remove characters */
if (vi->curpos > 0)
{
if (vi->text[vi->curpos - 1] == '\n')
{
vi->drawtoeos = true;
}
vi_shrinktext(vi, vi->curpos - 1, 1);
}
}
else
{
/* In replace mode, we simply move the cursor left */
if (vi->curpos > start)
{
vi->curpos = vi_cursorleft(vi, vi->curpos, 1);
}
}
}
break;
case ASCII_ESC: /* Escape exits insert mode */
{
vi_setmode(vi, MODE_COMMAND, 0);
vi->updatereqcol = true;
/* Move cursor 1 space to the left when exiting insert mode */
if (vi->curpos > 0 && vi->text[vi->curpos - 1] != '\n')
{
--vi->curpos;
}
}
break;
/* What do we do with carriage returns? */
case '\n': /* LF terminates line */
{
if (vi->mode == MODE_INSERT)
{
vi_insertch(vi, '\n');
}
else
{
vi_replacech(vi, '\n');
}
vi->drawtoeos = true;
}
break;
case KEY_UP: /* Move the cursor up one line */
{
vi->updatereqcol = false;
vi_cusorup(vi, 1);
}
break;
case KEY_DOWN: /* Move the cursor down one line */
{
vi->updatereqcol = false;
vi_cursordown(vi, 1);
}
break;
case KEY_LEFT: /* Move the cursor left N characters */
{
vi->curpos = vi_cursorleft(vi, vi->curpos, 1);
}
break;
case KEY_RIGHT: /* Move the cursor right one character */
{
vi->curpos = vi_cursorright(vi, vi->curpos, 1);
if (vi->curpos >= vi->textsize)
{
vi->curpos = vi->textsize;
}
}
break;
case KEY_HOME:
{
vi->curpos = vi_linebegin(vi, vi->curpos);
}
break;
case KEY_END:
{
vi->curpos = vi_lineend(vi, vi->curpos);
}
break;
case KEY_PPAGE:
{
vi->updatereqcol = false;
vi_cusorup(vi, vi->display.row);
}
break;
case KEY_NPAGE:
{
vi->updatereqcol = false;
vi_cursordown(vi, vi->display.row);
}
break;
default:
{
/* Don't print BEL if char is -1 from termcurses */
if (ch == -1)
{
continue;
}
else
{
VI_BEL(vi);
}
}
break;
}
}
vi_clearbottomline(vi);
}