BufferPane: add functions to move cursor up/down by screen row

This commit is contained in:
Josh Holtrop 2017-01-01 23:00:44 -05:00
parent 0d0e47593b
commit 92d9597f2e
3 changed files with 75 additions and 0 deletions

View File

@ -163,6 +163,71 @@ void BufferPane::update_cursor_row(std::list<std::pair<int, Buffer::Iterator>> &
m_cursor_screen_row = std::min(rows_above, m_cursor_screen_row);
}
bool BufferPane::move_cursor_screen_row_up()
{
size_t previous_iterator_offset = m_iterator->offset();
if (m_cursor_row_offset > 0)
{
Buffer::Iterator start_of_line = *m_iterator;
start_of_line.go_start_of_line();
walk_line(start_of_line, [this](int row_offset, int screen_column, int virtual_column, int character_width, const Buffer::Iterator & i) {
if (((*i != '\n') || insert_mode()) &&
(screen_column <= m_cursor_screen_column) &&
(row_offset < m_cursor_row_offset))
{
*m_iterator = i;
}
});
}
else
{
if (!m_iterator->go_previous_line())
{
return false;
}
walk_line(*m_iterator, [this](int row_offset, int screen_column, int virtual_column, int character_width, const Buffer::Iterator & i) {
if (((*i != '\n') || insert_mode()) &&
(screen_column <= m_cursor_screen_column))
{
*m_iterator = i;
}
});
}
return m_iterator->offset() != previous_iterator_offset;
}
bool BufferPane::move_cursor_screen_row_down()
{
size_t previous_iterator_offset = m_iterator->offset();
Buffer::Iterator start_of_line = *m_iterator;
start_of_line.go_start_of_line();
walk_line(start_of_line, [this](int row_offset, int screen_column, int virtual_column, int character_width, const Buffer::Iterator & i) {
if (((*i != '\n') || insert_mode()) &&
(screen_column <= m_cursor_screen_column) &&
(row_offset > m_cursor_row_offset))
{
*m_iterator = i;
}
});
if (m_iterator->offset() != previous_iterator_offset)
{
return true;
}
if (!m_iterator->go_next_line())
{
return false;
}
walk_line(*m_iterator, [this](int row_offset, int screen_column, int virtual_column, int character_width, const Buffer::Iterator & i) {
if (((*i != '\n') || insert_mode()) &&
(screen_column <= m_cursor_screen_column) &&
(row_offset == 0))
{
*m_iterator = i;
}
});
return m_iterator->offset() != previous_iterator_offset;
}
int BufferPane::determine_new_cursor_screen_row()
{
if (m_screen_lines.size() > 0)
@ -456,6 +521,12 @@ void BufferPane::cursor_move(Window::CursorMovement which)
}
}
break;
case Window::CursorMovement::SCREEN_ROW_UP:
moved = move_cursor_screen_row_up();
break;
case Window::CursorMovement::SCREEN_ROW_DOWN:
moved = move_cursor_screen_row_down();
break;
}
if (moved)
{

View File

@ -38,6 +38,8 @@ protected:
int screen_rows_below_line(const Buffer::Iterator & line);
int screen_rows_above_line(const Buffer::Iterator & line, std::list<std::pair<int, Buffer::Iterator>> & backward_lines);
void update_cursor_row(std::list<std::pair<int, Buffer::Iterator>> & backward_lines);
bool move_cursor_screen_row_up();
bool move_cursor_screen_row_down();
void walk_line(const Buffer::Iterator & start_of_line, std::function<void(int, int, int, int, const Buffer::Iterator &)> callback);
int determine_new_cursor_screen_row();
int col_x(int col)

View File

@ -35,6 +35,8 @@ public:
EOL,
FIRST_LINE,
LAST_LINE,
SCREEN_ROW_UP,
SCREEN_ROW_DOWN,
};
enum class EnterInsertModeMode : uint8_t