diff --git a/src/core/BufferView.cc b/src/core/BufferView.cc index fe802e8..3878c3a 100644 --- a/src/core/BufferView.cc +++ b/src/core/BufferView.cc @@ -402,14 +402,20 @@ void BufferView::move_forward_to_screen_position( bool allow_eol) { *m_iterator = *line; + bool moved_to_target_row = false; for (auto it = horiz_iter(line); it.is_valid(); it++) { - if ((allow_eol || (!it.is_eol())) && + if (((!it.is_eol()) || allow_eol) && ((it.row_offset() < target_row_offset) || + (!moved_to_target_row) || (it.screen_column() <= m_target_screen_column))) { *m_iterator = *it.iterator(); m_cursor_row_offset = it.row_offset(); + if (it.row_offset() == target_row_offset) + { + moved_to_target_row = true; + } } else { diff --git a/test/src/test_BufferView.cc b/test/src/test_BufferView.cc index adbd7a1..364e132 100644 --- a/test/src/test_BufferView.cc +++ b/test/src/test_BufferView.cc @@ -729,3 +729,31 @@ TEST(BufferViewTest, scrolls_past_empty_lines) bv.update(); EXPECT_EQ(0, LineNumber(iterator)); } + +TEST(BufferViewTest, moving_cursor_screen_row_down_jumps_past_wrapped_tab) +{ + static const char data[] = + "0\n" + "1abc\tdefghijklmnopqrstuvwxyz\n" + "2\n" + "3\n"; + auto b = std::make_shared((const uint8_t *)data, strlen(data)); + auto iterator = b->add_cursor(); + BufferView bv(b, iterator, Cwd); + bv.resize(5, 10); + bv.update(); + EXPECT_EQ(C('0'), **iterator); + EXPECT_EQ(0, bv.cursor_screen_row()); + bv.cursor_move(BufferView::CursorMovement::SCREEN_ROW_DOWN, false); + bv.update(); + EXPECT_EQ(C('1'), **iterator); + EXPECT_EQ(1, bv.cursor_screen_row()); + bv.cursor_move(BufferView::CursorMovement::SCREEN_ROW_DOWN, false); + bv.update(); + EXPECT_EQ(C('d'), **iterator); + EXPECT_EQ(2, bv.cursor_screen_row()); + bv.cursor_move(BufferView::CursorMovement::SCREEN_ROW_DOWN, false); + bv.update(); + EXPECT_EQ(C('f'), **iterator); + EXPECT_EQ(3, bv.cursor_screen_row()); +}