adjust cursor movement to optionally allow moving to EOL

This commit is contained in:
Josh Holtrop 2016-10-15 15:54:45 -04:00
parent 4ebe81c062
commit 261cc9abf8
4 changed files with 24 additions and 15 deletions

View File

@ -138,7 +138,7 @@ bool PieceTable::Cursor::go_start_of_line()
return rv; return rv;
} }
bool PieceTable::Cursor::go_end_of_line() bool PieceTable::Cursor::go_end_of_line(bool allow_on_eol)
{ {
if (!iterator.valid()) if (!iterator.valid())
return false; return false;
@ -148,11 +148,14 @@ bool PieceTable::Cursor::go_end_of_line()
(iterator.piece->next != iterator.piece_table->end_piece)) (iterator.piece->next != iterator.piece_table->end_piece))
{ {
iterator.go_next_piece(); iterator.go_next_piece();
rv = true;
} }
uint32_t current_column = column; uint32_t current_column = column;
iterator.go_end_of_piece(); iterator.go_end_of_piece();
calculate_column(); calculate_column();
if (!allow_on_eol)
{
go_left(1);
}
if (column != current_column) if (column != current_column)
rv = true; rv = true;
return rv; return rv;
@ -214,7 +217,7 @@ bool PieceTable::Cursor::go_left(int n)
return true; return true;
} }
bool PieceTable::Cursor::go_right(int n) bool PieceTable::Cursor::go_right(int n, bool allow_on_eol)
{ {
if (!iterator.valid()) if (!iterator.valid())
return false; return false;
@ -222,7 +225,13 @@ bool PieceTable::Cursor::go_right(int n)
{ {
return false; return false;
} }
Iterator iterator_2 = iterator;
iterator.go_next_position(); iterator.go_next_position();
if ((!allow_on_eol) && is_end_of_line())
{
iterator = iterator_2;
return false;
}
uint32_t chr = *iterator; uint32_t chr = *iterator;
if (chr == '\t') if (chr == '\t')
{ {
@ -307,7 +316,7 @@ void PieceTable::Cursor::calculate_column()
while ((tmp_cursor.iterator.piece != iterator.piece) || while ((tmp_cursor.iterator.piece != iterator.piece) ||
(tmp_cursor.iterator.offset < iterator.offset)) (tmp_cursor.iterator.offset < iterator.offset))
{ {
tmp_cursor.go_right(1); tmp_cursor.go_right(1, true);
} }
column = tmp_cursor.column; column = tmp_cursor.column;
} }
@ -317,7 +326,7 @@ void PieceTable::Cursor::forward_to_column(uint32_t c)
int32_t diff = abs((int32_t)(c - column)); int32_t diff = abs((int32_t)(c - column));
if (diff == 0) if (diff == 0)
return; return;
while (go_right(1)) while (go_right(1, false))
{ {
int32_t new_diff = abs((int32_t)(c - column)); int32_t new_diff = abs((int32_t)(c - column));
if (new_diff > diff) if (new_diff > diff)

View File

@ -102,11 +102,11 @@ public:
Cursor(PieceTable * pt); Cursor(PieceTable * pt);
bool go_start_of_line(); bool go_start_of_line();
bool go_end_of_line(); bool go_end_of_line(bool allow_on_eol);
bool go_up(int n, uint32_t desired_column); bool go_up(int n, uint32_t desired_column);
bool go_down(int n, uint32_t desired_column); bool go_down(int n, uint32_t desired_column);
bool go_left(int n); bool go_left(int n);
bool go_right(int n); bool go_right(int n, bool allow_on_eol);
bool operator==(const Cursor & c) bool operator==(const Cursor & c)
{ {
return (c.line == line) && (c.column == column); return (c.line == line) && (c.column == column);

View File

@ -300,7 +300,7 @@ void Window::cursor_move(int which)
m_target_column = m_cursor->column; m_target_column = m_cursor->column;
break; break;
case CURSOR_RIGHT: case CURSOR_RIGHT:
moved = m_cursor->go_right(1); moved = m_cursor->go_right(1, false);
m_target_column = m_cursor->column; m_target_column = m_cursor->column;
break; break;
case CURSOR_UP: case CURSOR_UP:
@ -314,7 +314,7 @@ void Window::cursor_move(int which)
m_target_column = 0u; m_target_column = 0u;
break; break;
case CURSOR_EOL: case CURSOR_EOL:
moved = m_cursor->go_end_of_line(); moved = m_cursor->go_end_of_line(false);
m_target_column = 0x7FFFFFFFu; m_target_column = 0x7FFFFFFFu;
break; break;
} }
@ -329,7 +329,7 @@ void Window::cursor_move(int which)
case CURSOR_UP: case CURSOR_UP:
{ {
PieceTable::Cursor c = *m_cursor; PieceTable::Cursor c = *m_cursor;
c.go_end_of_line(); c.go_end_of_line(false);
row_offset = m_cursor->column / m_columns - c.column / m_columns - 1 - current_row_offset; row_offset = m_cursor->column / m_columns - c.column / m_columns - 1 - current_row_offset;
} }
break; break;
@ -337,7 +337,7 @@ void Window::cursor_move(int which)
{ {
PieceTable::Cursor c = *m_cursor; PieceTable::Cursor c = *m_cursor;
c.go_up(1, 0u); c.go_up(1, 0u);
c.go_end_of_line(); c.go_end_of_line(false);
row_offset = c.column / m_columns - current_row_offset + 1 + m_cursor->column / m_columns; row_offset = c.column / m_columns - current_row_offset + 1 + m_cursor->column / m_columns;
} }
break; break;
@ -347,7 +347,7 @@ void Window::cursor_move(int which)
case CURSOR_EOL: case CURSOR_EOL:
{ {
PieceTable::Cursor c = *m_cursor; PieceTable::Cursor c = *m_cursor;
c.go_end_of_line(); c.go_end_of_line(false);
row_offset = c.column / m_columns - current_row_offset; row_offset = c.column / m_columns - current_row_offset;
} }
break; break;
@ -373,7 +373,7 @@ std::pair<int, PieceTable::Cursor> Window::calculate_start_position()
if (cursor.go_up(1, 0u)) if (cursor.go_up(1, 0u))
{ {
PieceTable::Cursor c = cursor; PieceTable::Cursor c = cursor;
c.go_end_of_line(); c.go_end_of_line(false);
row -= c.column / m_columns + 1; row -= c.column / m_columns + 1;
} }
else else
@ -424,7 +424,7 @@ void Window::draw_buffer()
(character != '\t')) (character != '\t'))
draw_buffer_character(screen_column, screen_row, character); draw_buffer_character(screen_column, screen_row, character);
} }
if (!cursor.go_right(1)) if (!cursor.go_right(1, false))
{ {
bool last_row = !cursor.go_down(1, 0); bool last_row = !cursor.go_down(1, 0);
if (last_vertical_crosshair_row < row) if (last_vertical_crosshair_row < row)

View File

@ -30,7 +30,7 @@ TEST(BufferTest, allows_navigating_using_cursors)
ASSERT_EQ((uint32_t)'H', **cursor); ASSERT_EQ((uint32_t)'H', **cursor);
cursor->go_up(1, cursor->column); cursor->go_up(1, cursor->column);
ASSERT_EQ((uint32_t)'H', **cursor); ASSERT_EQ((uint32_t)'H', **cursor);
cursor->go_right(1); cursor->go_right(1, false);
ASSERT_EQ((uint32_t)'e', **cursor); ASSERT_EQ((uint32_t)'e', **cursor);
cursor->go_down(1, cursor->column); cursor->go_down(1, cursor->column);
ASSERT_EQ((uint32_t)'h', **cursor); ASSERT_EQ((uint32_t)'h', **cursor);