From bb5bf6a13a57fa31bcdf4fa315086e7092eac578 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 15 Nov 2017 21:01:20 -0500 Subject: [PATCH] Implement f/F/t/T commands --- src/core/BufferView.cc | 90 ++++++++++++++++++++++++++++++++++++++++++ src/core/BufferView.h | 8 ++++ src/gui/Window.cc | 4 ++ 3 files changed, 102 insertions(+) diff --git a/src/core/BufferView.cc b/src/core/BufferView.cc index 43f6633..f4c65d0 100644 --- a/src/core/BufferView.cc +++ b/src/core/BufferView.cc @@ -163,6 +163,18 @@ bool BufferView::cursor_move(CursorMovement which, uint32_t c, bool allow_eol) case CursorMovement::SCREEN_ROW_DOWN: moved = move_cursor_screen_row_down(allow_eol); break; + case CursorMovement::FORWARD_UP_TO_CHAR: + moved = move_cursor_forward_up_to_char(c); + break; + case CursorMovement::FORWARD_ON_TO_CHAR: + moved = move_cursor_forward_on_to_char(c); + break; + case CursorMovement::BACK_UP_TO_CHAR: + moved = move_cursor_backward_up_to_char(c); + break; + case CursorMovement::BACK_ON_TO_CHAR: + moved = move_cursor_backward_on_to_char(c); + break; } if (moved) { @@ -181,6 +193,10 @@ bool BufferView::cursor_move(CursorMovement which, uint32_t c, bool allow_eol) break; case CursorMovement::SOL: case CursorMovement::EOL: + case CursorMovement::FORWARD_UP_TO_CHAR: + case CursorMovement::FORWARD_ON_TO_CHAR: + case CursorMovement::BACK_UP_TO_CHAR: + case CursorMovement::BACK_ON_TO_CHAR: determine_new_cursor_screen_row(); break; case CursorMovement::FIRST_LINE: @@ -430,6 +446,80 @@ void BufferView::move_forward_to_screen_position( } } +bool BufferView::move_cursor_forward_up_to_char(uint32_t c) +{ + Buffer::Iterator last_it = *m_iterator; + Buffer::Iterator it = *m_iterator; + while (it.go_right_in_line(false)) + { + if (*it == c) + { + if (last_it != *m_iterator) + { + *m_iterator = last_it; + return true; + } + else + { + return false; + } + } + last_it = it; + } + return false; +} + +bool BufferView::move_cursor_forward_on_to_char(uint32_t c) +{ + Buffer::Iterator it = *m_iterator; + while (it.go_right_in_line(false)) + { + if (*it == c) + { + *m_iterator = it; + return true; + } + } + return false; +} + +bool BufferView::move_cursor_backward_up_to_char(uint32_t c) +{ + Buffer::Iterator last_it = *m_iterator; + Buffer::Iterator it = *m_iterator; + while (it.go_left_in_line()) + { + if (*it == c) + { + if (last_it != *m_iterator) + { + *m_iterator = last_it; + return true; + } + else + { + return false; + } + } + last_it = it; + } + return false; +} + +bool BufferView::move_cursor_backward_on_to_char(uint32_t c) +{ + Buffer::Iterator it = *m_iterator; + while (it.go_left_in_line()) + { + if (*it == c) + { + *m_iterator = it; + return true; + } + } + return false; +} + int BufferView::calculate_rows_above_screen(int stop_at) { if (m_lines.empty()) diff --git a/src/core/BufferView.h b/src/core/BufferView.h index 809edac..8b9dbc4 100644 --- a/src/core/BufferView.h +++ b/src/core/BufferView.h @@ -26,6 +26,10 @@ public: LAST_LINE, SCREEN_ROW_UP, SCREEN_ROW_DOWN, + FORWARD_UP_TO_CHAR, + FORWARD_ON_TO_CHAR, + BACK_UP_TO_CHAR, + BACK_ON_TO_CHAR, }; class Iterator @@ -128,6 +132,10 @@ protected: void move_forward_to_screen_position( std::shared_ptr line, int target_row_offset, bool allow_eol); + bool move_cursor_forward_up_to_char(uint32_t c); + bool move_cursor_forward_on_to_char(uint32_t c); + bool move_cursor_backward_up_to_char(uint32_t c); + bool move_cursor_backward_on_to_char(uint32_t c); int calculate_rows_above_screen(int stop_at); int calculate_rows_below_screen(int stop_at); }; diff --git a/src/gui/Window.cc b/src/gui/Window.cc index 1c5d0d5..0c8cd5b 100644 --- a/src/gui/Window.cc +++ b/src/gui/Window.cc @@ -324,12 +324,16 @@ void Window::execute_command(const Command & command) switch (command.main.id) { case Command::GO_FORWARD_UP_TO_CHAR: + m_focused_buffer_pane->cursor_move(BufferPane::CursorMovement::FORWARD_UP_TO_CHAR, command.main.following_char); break; case Command::GO_FORWARD_ON_TO_CHAR: + m_focused_buffer_pane->cursor_move(BufferPane::CursorMovement::FORWARD_ON_TO_CHAR, command.main.following_char); break; case Command::GO_BACK_UP_TO_CHAR: + m_focused_buffer_pane->cursor_move(BufferPane::CursorMovement::BACK_UP_TO_CHAR, command.main.following_char); break; case Command::GO_BACK_ON_TO_CHAR: + m_focused_buffer_pane->cursor_move(BufferPane::CursorMovement::BACK_ON_TO_CHAR, command.main.following_char); break; case Command::DELETE_MOTION: break;