diff --git a/src/core/BufferView.cc b/src/core/BufferView.cc index 9ea5f1e..4f8ea39 100644 --- a/src/core/BufferView.cc +++ b/src/core/BufferView.cc @@ -495,38 +495,51 @@ void BufferView::move_forward_to_column(int to_column, bool allow_eol) bool BufferView::move_cursor_screen_row_up(bool allow_eol) { - if (m_cursor_row_offset > 0) + auto cursor_line_walker = get_cursor_line_walker(); + auto iterator_copy = m_iterator->clonep(); + if (cursor_line_walker.row_offset() > 0) { /* There are screen rows above the current in the current line. */ - auto start_of_line = std::make_shared(*m_iterator); - start_of_line->go_start_of_line(); - move_forward_to_screen_position(start_of_line, m_cursor_row_offset - 1, allow_eol); + iterator_copy->go_start_of_line(); + move_forward_to_screen_position(iterator_copy, cursor_line_walker.row_offset() - 1, allow_eol); } else { - auto previous_line = std::make_shared(*m_iterator); - if (!previous_line->go_previous_line()) + if (!iterator_copy->go_previous_line()) { return false; } - int target_row_offset = calculate_rows_in_line(previous_line) - 1; - move_forward_to_screen_position(previous_line, target_row_offset, allow_eol); + int target_row_offset = calculate_rows_in_line(iterator_copy) - 1; + move_forward_to_screen_position(iterator_copy, target_row_offset, allow_eol); } return true; } bool BufferView::move_cursor_screen_row_down(bool allow_eol) { - if (m_rows_in_cursor_line > (m_cursor_row_offset + 1)) + auto cursor_line_walker = get_cursor_line_walker(); + int target_row_offset = cursor_line_walker.row_offset() + 1; + bool moved = false; + for (; cursor_line_walker.is_valid(); cursor_line_walker++) { - /* There are screen rows below the current in the current line. */ - auto start_of_line = std::make_shared(*m_iterator); - start_of_line->go_start_of_line(); - move_forward_to_screen_position(start_of_line, m_cursor_row_offset + 1, allow_eol); + if (cursor_line_walker.row_offset() == target_row_offset) + { + if (((!cursor_line_walker.is_eol()) || allow_eol) && + ((!moved) || (cursor_line_walker.screen_column() <= m_target_screen_column))) + { + *m_iterator = *cursor_line_walker.iterator(); + m_cursor_row_offset = cursor_line_walker.row_offset(); + moved = true; + } + } + else if (cursor_line_walker.row_offset() > target_row_offset) + { + break; + } } - else + if (!moved) { - auto next_line = std::make_shared(*m_iterator); + auto next_line = m_iterator->clonep(); if (!next_line->go_next_line()) { return false; @@ -604,3 +617,17 @@ int BufferView::n_screen_rows_with_content() const } return 0; } + +BufferLineWalker BufferView::get_cursor_line_walker() +{ + auto start_of_line = m_iterator->clonep(); + start_of_line->go_start_of_line(); + for (auto it = horiz_iter(start_of_line); it.is_valid(); it++) + { + if (*it.iterator() == *m_iterator) + { + return it; + } + } + return horiz_iter(start_of_line); +} diff --git a/src/core/BufferView.h b/src/core/BufferView.h index 12af785..bf93910 100644 --- a/src/core/BufferView.h +++ b/src/core/BufferView.h @@ -143,6 +143,7 @@ protected: int calculate_rows_above_screen(int stop_at); int calculate_rows_below_screen(int stop_at); int n_screen_rows_with_content() const; + BufferLineWalker get_cursor_line_walker(); }; #endif