VI: Several bug fixes
This commit is contained in:
parent
c873c4b3f2
commit
aadd63c7e7
199
system/vi/vi.c
199
system/vi/vi.c
@ -309,6 +309,8 @@ static off_t vi_cursorright(FAR struct vi_s *vi, off_t curpos,
|
|||||||
int ncolumns);
|
int ncolumns);
|
||||||
static void vi_delforward(FAR struct vi_s *vi);
|
static void vi_delforward(FAR struct vi_s *vi);
|
||||||
static void vi_delbackward(FAR struct vi_s *vi);
|
static void vi_delbackward(FAR struct vi_s *vi);
|
||||||
|
static void vi_linerange(FAR struct vi_s *vi, off_t *start, off_t *end);
|
||||||
|
static void vi_delline(FAR struct vi_s *vi);
|
||||||
static void vi_yank(FAR struct vi_s *vi);
|
static void vi_yank(FAR struct vi_s *vi);
|
||||||
static void vi_paste(FAR struct vi_s *vi);
|
static void vi_paste(FAR struct vi_s *vi);
|
||||||
static void vi_gotoline(FAR struct vi_s *vi);
|
static void vi_gotoline(FAR struct vi_s *vi);
|
||||||
@ -799,7 +801,7 @@ static off_t vi_linebegin(FAR struct vi_s *vi, off_t pos)
|
|||||||
* Name: vi_prevline
|
* Name: vi_prevline
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Search backward for the end of the previous line
|
* Search backward for the beginning of the previous line
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
@ -1375,10 +1377,10 @@ static void vi_scrollcheck(FAR struct vi_s *vi)
|
|||||||
|
|
||||||
while (curline < vi->winpos)
|
while (curline < vi->winpos)
|
||||||
{
|
{
|
||||||
/* Yes.. move the window position up by one line and check again */
|
/* Yes.. move the window position up to the beginning of the previous
|
||||||
|
* line line and check again */
|
||||||
|
|
||||||
pos = vi_prevline(vi, vi->winpos);
|
vi->winpos = vi_prevline(vi, vi->winpos);
|
||||||
vi->winpos = vi_linebegin(vi, pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset the cursor row position so that it is relative to the
|
/* Reset the cursor row position so that it is relative to the
|
||||||
@ -1654,13 +1656,12 @@ static void vi_cusorup(FAR struct vi_s *vi, int nlines)
|
|||||||
int remaining;
|
int remaining;
|
||||||
off_t start;
|
off_t start;
|
||||||
off_t end;
|
off_t end;
|
||||||
off_t pos;
|
|
||||||
|
|
||||||
vivdbg("nlines=%d\n", nlines);
|
vivdbg("nlines=%d\n", nlines);
|
||||||
|
|
||||||
/* How many lines do we need to move? Zero means 1 (so does 1) */
|
/* How many lines do we need to move? Zero means 1 (so does 1) */
|
||||||
|
|
||||||
remaining = (nlines == 0 ? 1 : nlines);
|
remaining = (nlines < 1 ? 1 : nlines);
|
||||||
|
|
||||||
/* Get the offset to the start of the current line */
|
/* Get the offset to the start of the current line */
|
||||||
|
|
||||||
@ -1670,14 +1671,15 @@ static void vi_cusorup(FAR struct vi_s *vi, int nlines)
|
|||||||
|
|
||||||
for (; remaining > 0; remaining--)
|
for (; remaining > 0; remaining--)
|
||||||
{
|
{
|
||||||
/* Get the start and end offset of the line */
|
/* Get the start position of the previous line */
|
||||||
|
|
||||||
pos = vi_prevline(vi, start);
|
start = vi_prevline(vi, start);
|
||||||
start = vi_linebegin(vi, pos);
|
|
||||||
end = start + vi->cursor.column + vi->hscroll;
|
|
||||||
|
|
||||||
/* Get the text buffer position to the horizontal cursor position */
|
/* Find the cursor position on the next line corresponding to the
|
||||||
|
* cursor position on the current line.
|
||||||
|
*/
|
||||||
|
|
||||||
|
end = start + vi->cursor.column + vi->hscroll;
|
||||||
vi_windowpos(vi, start, end, NULL, &vi->curpos);
|
vi_windowpos(vi, start, end, NULL, &vi->curpos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1700,7 +1702,7 @@ static void vi_cursordown(FAR struct vi_s *vi, int nlines)
|
|||||||
|
|
||||||
/* How many lines do we need to move? Zero means 1 (so does 1) */
|
/* How many lines do we need to move? Zero means 1 (so does 1) */
|
||||||
|
|
||||||
remaining = (nlines == 0 ? 1 : nlines);
|
remaining = (nlines < 1 ? 1 : nlines);
|
||||||
|
|
||||||
/* Get the offset to the start of the current line */
|
/* Get the offset to the start of the current line */
|
||||||
|
|
||||||
@ -1710,18 +1712,15 @@ static void vi_cursordown(FAR struct vi_s *vi, int nlines)
|
|||||||
|
|
||||||
for (; remaining > 0; remaining--)
|
for (; remaining > 0; remaining--)
|
||||||
{
|
{
|
||||||
if (!vi_lineend(vi, vi->curpos) < vi->textsize)
|
/* Get the start of the next line. */
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the start and end offset of the line */
|
|
||||||
|
|
||||||
start = vi_nextline(vi, start);
|
start = vi_nextline(vi, start);
|
||||||
end = start + vi->cursor.column + vi->hscroll;
|
|
||||||
|
|
||||||
/* Get the text buffer position to the horizontal cursor position */
|
/* Find the cursor position on the next line corresponding to the
|
||||||
|
* cursor position on the current line.
|
||||||
|
*/
|
||||||
|
|
||||||
|
end = start + vi->cursor.column + vi->hscroll;
|
||||||
vi_windowpos(vi, start, end, NULL, &vi->curpos);
|
vi_windowpos(vi, start, end, NULL, &vi->curpos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1742,8 +1741,13 @@ static off_t vi_cursorleft(FAR struct vi_s *vi, off_t curpos, int ncolumns)
|
|||||||
|
|
||||||
vivdbg("curpos=%ld ncolumns=%d\n", curpos, ncolumns);
|
vivdbg("curpos=%ld ncolumns=%d\n", curpos, ncolumns);
|
||||||
|
|
||||||
|
/* Loop decrementing the cursor position for each repitition count. Break
|
||||||
|
* out early if we hit either the beginning of the text buffer, or the end
|
||||||
|
* of the previous line.
|
||||||
|
*/
|
||||||
|
|
||||||
for (remaining = (ncolumns < 1 ? 1 : ncolumns);
|
for (remaining = (ncolumns < 1 ? 1 : ncolumns);
|
||||||
curpos > 0 && remaining > 0 && vi->text[curpos] != '\n';
|
curpos > 0 && remaining > 0 && vi->text[curpos - 1] != '\n';
|
||||||
curpos--, remaining--);
|
curpos--, remaining--);
|
||||||
|
|
||||||
return curpos;
|
return curpos;
|
||||||
@ -1765,6 +1769,10 @@ static off_t vi_cursorright(FAR struct vi_s *vi, off_t curpos, int ncolumns)
|
|||||||
|
|
||||||
vivdbg("curpos=%ld ncolumns=%d\n", curpos, ncolumns);
|
vivdbg("curpos=%ld ncolumns=%d\n", curpos, ncolumns);
|
||||||
|
|
||||||
|
/* Loop incrementing the cursor position for each repitition count. Break
|
||||||
|
* out early if we hit either the end of the text buffer, or the end of the line.
|
||||||
|
*/
|
||||||
|
|
||||||
for (remaining = (ncolumns < 1 ? 1 : ncolumns);
|
for (remaining = (ncolumns < 1 ? 1 : ncolumns);
|
||||||
curpos < vi->textsize && remaining > 0 && vi->text[curpos] != '\n';
|
curpos < vi->textsize && remaining > 0 && vi->text[curpos] != '\n';
|
||||||
curpos++, remaining--);
|
curpos++, remaining--);
|
||||||
@ -1787,8 +1795,17 @@ static void vi_delforward(FAR struct vi_s *vi)
|
|||||||
|
|
||||||
vivdbg("curpos=%ld value=%ld\n", (long)vi->curpos, vi->value);
|
vivdbg("curpos=%ld value=%ld\n", (long)vi->curpos, vi->value);
|
||||||
|
|
||||||
|
/* Get the cursor position as if we would have move the cursor right N
|
||||||
|
* times (which might be <N characters).
|
||||||
|
*/
|
||||||
|
|
||||||
end = vi_cursorright(vi, vi->curpos, vi->value);
|
end = vi_cursorright(vi, vi->curpos, vi->value);
|
||||||
size = end - vi->curpos - 1;
|
|
||||||
|
/* The difference from the current position then is the number of
|
||||||
|
* characters to be deleted.
|
||||||
|
*/
|
||||||
|
|
||||||
|
size = end - vi->curpos;
|
||||||
vi_shrinktext(vi, vi->curpos, size);
|
vi_shrinktext(vi, vi->curpos, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1808,12 +1825,84 @@ static void vi_delbackward(FAR struct vi_s *vi)
|
|||||||
|
|
||||||
vivdbg("curpos=%ld value=%ld\n", (long)vi->curpos, vi->value);
|
vivdbg("curpos=%ld value=%ld\n", (long)vi->curpos, vi->value);
|
||||||
|
|
||||||
start = vi_cursorleft(vi, vi->curpos, 1);
|
/* Back up one character. This is where the deletion will end */
|
||||||
end = vi_cursorleft(vi, start, vi->value);
|
|
||||||
size = end - start - 1;
|
end = vi_cursorleft(vi, vi->curpos, 1);
|
||||||
|
|
||||||
|
/* Get the cursor position as if we would have move the cursor left N
|
||||||
|
* times (which might be <N characters).
|
||||||
|
*/
|
||||||
|
|
||||||
|
start = vi_cursorleft(vi, end, vi->value);
|
||||||
|
|
||||||
|
/* The difference from the current position then is the number of
|
||||||
|
* characters to be deleted.
|
||||||
|
*/
|
||||||
|
|
||||||
|
size = end - start;
|
||||||
vi_shrinktext(vi, start, size);
|
vi_shrinktext(vi, start, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: vi_linerange
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Return the start and end positions for N lines int the text buffer,
|
||||||
|
* beginning at the current line. This is logic common to yanking and
|
||||||
|
* deleting lines.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void vi_linerange(FAR struct vi_s *vi, off_t *start, off_t *end)
|
||||||
|
{
|
||||||
|
off_t next;
|
||||||
|
int nlines;
|
||||||
|
|
||||||
|
/* Get the offset in the text buffer to the beginning of the current line */
|
||||||
|
|
||||||
|
*start = vi_linebegin(vi, vi->curpos);
|
||||||
|
|
||||||
|
/* Move one line unless a repetition count was provided */
|
||||||
|
|
||||||
|
nlines = (vi->value > 0 ? vi->value : 1);
|
||||||
|
|
||||||
|
/* Search ahead to find the end of the last line to yank */
|
||||||
|
|
||||||
|
for (next = *start; nlines > 1; nlines--)
|
||||||
|
{
|
||||||
|
next = vi_nextline(vi, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
*end = vi_lineend(vi, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: vi_delline
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Delete N lines from the text buffer, beginning at the current line.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void vi_delline(FAR struct vi_s *vi)
|
||||||
|
{
|
||||||
|
off_t delsize;
|
||||||
|
off_t start;
|
||||||
|
off_t end;
|
||||||
|
|
||||||
|
/* Get the offset in the text buffer corresponding to the range of lines to
|
||||||
|
* be deleted
|
||||||
|
*/
|
||||||
|
|
||||||
|
vi_linerange(vi, &start, &end);
|
||||||
|
vivdbg("start=%ld end=%ld\n", (long)start, (long)end);
|
||||||
|
|
||||||
|
/* Remove the text from the text buffer */
|
||||||
|
|
||||||
|
delsize = end - start + 1;
|
||||||
|
vi_shrinktext(vi, start, delsize);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: vi_yank
|
* Name: vi_yank
|
||||||
*
|
*
|
||||||
@ -1827,27 +1916,13 @@ static void vi_yank(FAR struct vi_s *vi)
|
|||||||
{
|
{
|
||||||
off_t start;
|
off_t start;
|
||||||
off_t end;
|
off_t end;
|
||||||
off_t next;
|
|
||||||
int nlines;
|
|
||||||
|
|
||||||
/* Get the offset in the text buffer to the beginning of the current line */
|
/* Get the offset in the text buffer corresponding to the range of lines to
|
||||||
|
* be yanked
|
||||||
|
*/
|
||||||
|
|
||||||
start = vi_linebegin(vi, vi->curpos);
|
vi_linerange(vi, &start, &end);
|
||||||
|
vivdbg("start=%ld end=%ld\n", (long)start, (long)end);
|
||||||
/* Move one line unless a repetition count was provided */
|
|
||||||
|
|
||||||
nlines = (vi->value > 0 ? vi->value : 1);
|
|
||||||
|
|
||||||
vivdbg("start=%ld nlines=%d\n", (long)start, nlines);
|
|
||||||
|
|
||||||
/* Search ahead to find the end of the last line to yank */
|
|
||||||
|
|
||||||
for (next = start; nlines > 1; nlines--)
|
|
||||||
{
|
|
||||||
next = vi_nextline(vi, next);
|
|
||||||
}
|
|
||||||
|
|
||||||
end = vi_lineend(vi, next);
|
|
||||||
|
|
||||||
/* Free any previously yanked lines */
|
/* Free any previously yanked lines */
|
||||||
|
|
||||||
@ -2115,8 +2190,8 @@ static void vi_cmd_mode(FAR struct vi_s *vi)
|
|||||||
{
|
{
|
||||||
if (vi->delarm)
|
if (vi->delarm)
|
||||||
{
|
{
|
||||||
off_t curline = vi_linebegin(vi, vi->curpos);
|
vi_delline(vi);
|
||||||
vi_shrinktext(vi, curline, vi_nextline(vi, curline) - curline);
|
vi->delarm = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2130,6 +2205,7 @@ static void vi_cmd_mode(FAR struct vi_s *vi)
|
|||||||
if (vi->yankarm)
|
if (vi->yankarm)
|
||||||
{
|
{
|
||||||
vi_yank(vi);
|
vi_yank(vi);
|
||||||
|
vi->yankarm = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2158,6 +2234,10 @@ static void vi_cmd_mode(FAR struct vi_s *vi)
|
|||||||
|
|
||||||
case KEY_CMDMODE_OPENBELOW: /* Enter insertion mode in new line below current */
|
case KEY_CMDMODE_OPENBELOW: /* Enter insertion mode in new line below current */
|
||||||
{
|
{
|
||||||
|
/* Go forward to the end of the current line */
|
||||||
|
|
||||||
|
vi->curpos = vi_lineend(vi, vi->curpos);
|
||||||
|
|
||||||
/* Insert a newline to break the line. The cursor now points
|
/* Insert a newline to break the line. The cursor now points
|
||||||
* beginning of the new line.
|
* beginning of the new line.
|
||||||
*/
|
*/
|
||||||
@ -2172,12 +2252,16 @@ static void vi_cmd_mode(FAR struct vi_s *vi)
|
|||||||
|
|
||||||
case KEY_CMDMODE_OPENABOVE: /* Enter insertion mode in new line above current */
|
case KEY_CMDMODE_OPENABOVE: /* Enter insertion mode in new line above current */
|
||||||
{
|
{
|
||||||
/* Insert a newline to break the line. Backup the cursor so
|
/* Back up to the beginning of the end of the previous line */
|
||||||
* that it points to the end of the (previous) current line.
|
|
||||||
|
off_t pos = vi_prevline(vi, vi->curpos);
|
||||||
|
vi->curpos = vi_lineend(vi, pos);
|
||||||
|
|
||||||
|
/* Insert a newline to open the line. The cursor will now point to the
|
||||||
|
* beginning of newly openly line before the current line.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vi_insertch(vi, '\n');
|
vi_insertch(vi, '\n');
|
||||||
vi->curpos = vi_prevline(vi, vi->curpos);
|
|
||||||
|
|
||||||
/* Then enter insert mode */
|
/* Then enter insert mode */
|
||||||
|
|
||||||
@ -2187,7 +2271,7 @@ static void vi_cmd_mode(FAR struct vi_s *vi)
|
|||||||
|
|
||||||
case KEY_CMDMODE_APPEND: /* Enter insertion mode after the current cursor position */
|
case KEY_CMDMODE_APPEND: /* Enter insertion mode after the current cursor position */
|
||||||
{
|
{
|
||||||
vi->curpos = vi_cursorleft(vi, vi->curpos, 1);
|
vi->curpos = vi_cursorright(vi, vi->curpos, 1);
|
||||||
vi_setmode(vi, MODE_INSERT, 0);
|
vi_setmode(vi, MODE_INSERT, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2242,10 +2326,14 @@ static void vi_cmd_mode(FAR struct vi_s *vi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Any non-numeric input will reset the accumulated value (after it has
|
/* Any non-numeric input will reset the accumulated value (after it has
|
||||||
* been used)
|
* been used). For the double character sequences, we need to retain
|
||||||
|
* the value until the next character is entered.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vi->value = 0;
|
if (!vi->delarm && !vi->yankarm)
|
||||||
|
{
|
||||||
|
vi->value = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2836,7 +2924,7 @@ static void vi_replacech_submode(FAR struct vi_s *vi)
|
|||||||
off_t end;
|
off_t end;
|
||||||
long nchars;
|
long nchars;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
int ch;
|
int ch = 0;
|
||||||
|
|
||||||
/* Get the number of characters to replace */
|
/* Get the number of characters to replace */
|
||||||
|
|
||||||
@ -2850,13 +2938,12 @@ static void vi_replacech_submode(FAR struct vi_s *vi)
|
|||||||
if (vi->curpos + nchars > end)
|
if (vi->curpos + nchars > end)
|
||||||
{
|
{
|
||||||
vi_error(vi, g_fmtnotvalid);
|
vi_error(vi, g_fmtnotvalid);
|
||||||
vi_exitsubmode(vi, MODE_COMMAND);
|
|
||||||
vi_setmode(vi, MODE_COMMAND, 0);
|
vi_setmode(vi, MODE_COMMAND, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop until we get the replacement character */
|
/* Loop until we get the replacement character */
|
||||||
|
|
||||||
while (!found)
|
while (vi->mode == SUBMODE_REPLACECH && !found)
|
||||||
{
|
{
|
||||||
/* Get the next character from the input */
|
/* Get the next character from the input */
|
||||||
|
|
||||||
@ -3023,7 +3110,7 @@ static void vi_insert_mode(FAR struct vi_s *vi)
|
|||||||
|
|
||||||
case ASCII_BS:
|
case ASCII_BS:
|
||||||
{
|
{
|
||||||
if (vi->curpos)
|
if (vi->curpos > 0)
|
||||||
{
|
{
|
||||||
vi_shrinktext(vi, --vi->curpos, 1);
|
vi_shrinktext(vi, --vi->curpos, 1);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user