From 92d9597f2e425f789334ae9e33140d5f53d90459 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sun, 1 Jan 2017 23:00:44 -0500 Subject: [PATCH] BufferPane: add functions to move cursor up/down by screen row --- src/gui/BufferPane.cc | 71 +++++++++++++++++++++++++++++++++++++++++++ src/gui/BufferPane.h | 2 ++ src/gui/Window.h | 2 ++ 3 files changed, 75 insertions(+) diff --git a/src/gui/BufferPane.cc b/src/gui/BufferPane.cc index 7928533..fef6ca1 100644 --- a/src/gui/BufferPane.cc +++ b/src/gui/BufferPane.cc @@ -163,6 +163,71 @@ void BufferPane::update_cursor_row(std::list> & 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) { diff --git a/src/gui/BufferPane.h b/src/gui/BufferPane.h index 81cd5d8..782e1ce 100644 --- a/src/gui/BufferPane.h +++ b/src/gui/BufferPane.h @@ -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> & backward_lines); void update_cursor_row(std::list> & 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 callback); int determine_new_cursor_screen_row(); int col_x(int col) diff --git a/src/gui/Window.h b/src/gui/Window.h index d69c71a..cee712f 100644 --- a/src/gui/Window.h +++ b/src/gui/Window.h @@ -35,6 +35,8 @@ public: EOL, FIRST_LINE, LAST_LINE, + SCREEN_ROW_UP, + SCREEN_ROW_DOWN, }; enum class EnterInsertModeMode : uint8_t