VI: Fix some display and cursor position bugs... still plenty of bugs

This commit is contained in:
Gregory Nutt 2014-01-20 17:53:11 -06:00
parent 66d58428e0
commit eefd9df8f5

View File

@ -284,9 +284,10 @@ static void vi_exitsubmode(FAR struct vi_s *vi, uint8_t mode);
/* Display management */ /* Display management */
static uint16_t vi_wincolumn(FAR struct vi_s *vi, off_t start, off_t end); static void vi_windowpos(FAR struct vi_s *vi, off_t start, off_t end,
uint16_t *pcolumn, off_t *ppos);
static void vi_scrollcheck(FAR struct vi_s *vi); static void vi_scrollcheck(FAR struct vi_s *vi);
static void vi_show(FAR struct vi_s *vi); static void vi_showtext(FAR struct vi_s *vi);
/* Command mode */ /* Command mode */
@ -1221,18 +1222,19 @@ static void vi_exitsubmode(FAR struct vi_s *vi, uint8_t mode)
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: vi_wincolumn * Name: vi_windowpos
* *
* Description: * Description:
* Based on the position of the cursor in the text buffer, determine the * Based on the position of the cursor in the text buffer, determine the
* display cursor position, performing TAB expansion as necessary. * horizontal display cursor position, performing TAB expansion as necessary.
* *
****************************************************************************/ ****************************************************************************/
static uint16_t vi_wincolumn(FAR struct vi_s *vi, off_t start, off_t end) static void vi_windowpos(FAR struct vi_s *vi, off_t start, off_t end,
uint16_t *pcolumn, off_t *ppos)
{ {
uint16_t column; uint16_t column;
off_t offset; off_t pos;
vivdbg("start=%ld end=%ld\n", (long)start, (long)end); vivdbg("start=%ld end=%ld\n", (long)start, (long)end);
@ -1245,24 +1247,24 @@ static uint16_t vi_wincolumn(FAR struct vi_s *vi, off_t start, off_t end)
end = vi->textsize; end = vi->textsize;
} }
/* Loop incrementing the text buffer offset while text buffer offset is /* Loop incrementing the text buffer position while text buffer position
* within range. * is within range.
*/ */
for (offset = start, column = 0; offset < end; offset++) for (pos = start, column = 0; pos < end; pos++)
{ {
/* Does this offset point to the newline terminator? */ /* Is there a newline terminator at this position? */
if (vi->text[offset] == '\n') if (vi->text[pos] == '\n')
{ {
/* Yes... break out of the loop return the cursor column */ /* Yes... break out of the loop return the cursor column */
break; break;
} }
/* No... does it refer to a TAB? */ /* No... Is there a TAB at this position? */
else if (vi->text[offset] == '\t') else if (vi->text[pos] == '\t')
{ {
/* Yes.. expand the TAB */ /* Yes.. expand the TAB */
@ -1277,7 +1279,17 @@ static uint16_t vi_wincolumn(FAR struct vi_s *vi, off_t start, off_t end)
} }
} }
return column; /* Now return the requested values */
if (ppos)
{
*ppos = pos;
}
if (pcolumn)
{
*pcolumn = column;
}
} }
/**************************************************************************** /****************************************************************************
@ -1292,6 +1304,7 @@ static void vi_scrollcheck(FAR struct vi_s *vi)
{ {
off_t curline; off_t curline;
off_t pos; off_t pos;
uint16_t tmp;
int column; int column;
int nlines; int nlines;
@ -1328,12 +1341,13 @@ static void vi_scrollcheck(FAR struct vi_s *vi)
vi->winpos = vi_nextline(vi, vi->winpos); vi->winpos = vi_nextline(vi, vi->winpos);
} }
/* Check if the cursor column is on the display. vi_wincolumn returns the /* Check if the cursor column is on the display. vi_windowpos returns the
* unrestricted column number of cursor. hscroll is the horizontal offset * unrestricted column number of cursor. hscroll is the horizontal offset
* in characters. * in characters.
*/ */
column = (int)vi_wincolumn(vi, curline, vi->curpos) - (int)vi->hscroll; vi_windowpos(vi, curline, vi->curpos, &tmp, NULL);
column = (int)tmp - (int)vi->hscroll;
/* Force the cursor column to lie on the display. First check if the /* Force the cursor column to lie on the display. First check if the
* column lies to the left of the horizontal scrolling position. If it * column lies to the left of the horizontal scrolling position. If it
@ -1421,7 +1435,7 @@ static void vi_scrollcheck(FAR struct vi_s *vi)
} }
/**************************************************************************** /****************************************************************************
* Name: vi_show * Name: vi_showtext
* *
* Description: * Description:
* Update the display based on the last operation. This function is * Update the display based on the last operation. This function is
@ -1430,7 +1444,7 @@ static void vi_scrollcheck(FAR struct vi_s *vi)
* *
****************************************************************************/ ****************************************************************************/
static void vi_show(FAR struct vi_s *vi) static void vi_showtext(FAR struct vi_s *vi)
{ {
off_t pos; off_t pos;
uint16_t row; uint16_t row;
@ -1477,11 +1491,13 @@ static void vi_show(FAR struct vi_s *vi)
endcol--; endcol--;
} }
/* Get the offset into this line corresponding to column 0, accounting /* Get the position into this line corresponding to display column 0,
* for horizontal scrolling and tab expansion. * accounting for horizontal scrolling and tab expansion. Add that to
* the line start offset to get the first offset to consider for
* display.
*/ */
pos = vi_wincolumn(vi, pos, pos + vi->hscroll); vi_windowpos(vi, pos, pos + vi->hscroll, NULL, &pos);
/* Set the cursor position to the beginning of this row and clear to /* Set the cursor position to the beginning of this row and clear to
* the end of the line. * the end of the line.
@ -1588,10 +1604,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 */
pos = vi_prevline(vi, start); pos = vi_prevline(vi, start);
start = vi_linebegin(vi, pos); start = vi_linebegin(vi, pos);
end = start + vi->cursor.column + vi->hscroll; end = start + vi->cursor.column + vi->hscroll;
vi->curpos = vi_wincolumn(vi, start, end);
/* Get the text buffer position to the horizontal cursor position */
vi_windowpos(vi, start, end, NULL, &vi->curpos);
} }
} }
@ -1628,9 +1649,14 @@ static void vi_cursordown(FAR struct vi_s *vi, int nlines)
break; 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; end = start + vi->cursor.column + vi->hscroll;
vi->curpos = vi_wincolumn(vi, start, end);
/* Get the text buffer position to the horizontal cursor position */
vi_windowpos(vi, start, end, NULL, &vi->curpos);
} }
} }
@ -1897,7 +1923,7 @@ static void vi_cmd_mode(FAR struct vi_s *vi)
{ {
/* Make sure that the display reflects the current state */ /* Make sure that the display reflects the current state */
vi_show(vi); vi_showtext(vi);
vi_setcursor(vi, vi->cursor.row, vi->cursor.column); vi_setcursor(vi, vi->cursor.row, vi->cursor.column);
/* Get the next character from the input */ /* Get the next character from the input */
@ -2881,7 +2907,7 @@ static void vi_insert_mode(FAR struct vi_s *vi)
{ {
/* Make sure that the display reflects the current state */ /* Make sure that the display reflects the current state */
vi_show(vi); vi_showtext(vi);
vi_setcursor(vi, vi->cursor.row, vi->cursor.column); vi_setcursor(vi, vi->cursor.row, vi->cursor.column);
/* Get the next character from the input */ /* Get the next character from the input */
@ -2996,7 +3022,7 @@ static void vi_replace_mode(FAR struct vi_s *vi)
{ {
/* Make sure that the display reflects the current state */ /* Make sure that the display reflects the current state */
vi_show(vi); vi_showtext(vi);
vi_setcursor(vi, vi->cursor.row, vi->cursor.column); vi_setcursor(vi, vi->cursor.row, vi->cursor.column);
/* Get the next character from the input */ /* Get the next character from the input */