From 43fb64a91359c078b9692cfc87f0b035d3f25f5f Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Wed, 28 Sep 2011 14:23:43 +0000 Subject: [PATCH] Window: selection behaviour now depends on a window state more vi-like behaviour, hit the v key to toggle append selection mode, this means much more keys become available for mapping, as caps are now longer reserved to append mode. --- src/main.cc | 45 +++++++++++++++++---------------------------- src/window.cc | 16 +++++++++++++--- src/window.hh | 13 ++++++++++++- 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/main.cc b/src/main.cc index f5992f0d..09bd3239 100644 --- a/src/main.cc +++ b/src/main.cc @@ -370,7 +370,7 @@ void do_search(Window& window) else RegisterManager::instance()['/'] = ex; - window.select(false, RegexSelector(ex)); + window.select(RegexSelector(ex)); } catch (prompt_aborted&) {} } @@ -379,7 +379,7 @@ void do_search_next(Window& window) { std::string& ex = RegisterManager::instance()['/']; if (not ex.empty()) - window.select(false, RegexSelector(ex)); + window.select(RegexSelector(ex)); else print_status("no search pattern"); } @@ -414,28 +414,18 @@ void do_paste(Window& window, int count) std::unordered_map> keymap = { - { 'h', [](Window& window, int count) { window.move_cursor(WindowCoord(0, -std::max(count,1))); window.empty_selections(); } }, - { 'j', [](Window& window, int count) { window.move_cursor(WindowCoord( std::max(count,1), 0)); window.empty_selections(); } }, - { 'k', [](Window& window, int count) { window.move_cursor(WindowCoord(-std::max(count,1), 0)); window.empty_selections(); } }, - { 'l', [](Window& window, int count) { window.move_cursor(WindowCoord(0, std::max(count,1))); window.empty_selections(); } }, + { 'h', [](Window& window, int count) { window.move_cursor(WindowCoord(0, -std::max(count,1))); } }, + { 'j', [](Window& window, int count) { window.move_cursor(WindowCoord( std::max(count,1), 0)); } }, + { 'k', [](Window& window, int count) { window.move_cursor(WindowCoord(-std::max(count,1), 0)); } }, + { 'l', [](Window& window, int count) { window.move_cursor(WindowCoord(0, std::max(count,1))); } }, - { 'H', [](Window& window, int count) { window.select(true, std::bind(move_select, std::ref(window), _1, - WindowCoord(0, -std::max(count,1)))); } }, - { 'J', [](Window& window, int count) { window.select(true, std::bind(move_select, std::ref(window), _1, - WindowCoord( std::max(count,1), 0))); } }, - { 'K', [](Window& window, int count) { window.select(true, std::bind(move_select, std::ref(window), _1, - WindowCoord(-std::max(count,1), 0))); } }, - { 'L', [](Window& window, int count) { window.select(true, std::bind(move_select, std::ref(window), _1, - WindowCoord(0, std::max(count,1)))); } }, - - { 't', [](Window& window, int count) { window.select(false, std::bind(select_to, _1, getch(), count, false)); } }, - { 'f', [](Window& window, int count) { window.select(false, std::bind(select_to, _1, getch(), count, true)); } }, + { 't', [](Window& window, int count) { window.select(std::bind(select_to, _1, getch(), count, false)); } }, + { 'f', [](Window& window, int count) { window.select(std::bind(select_to, _1, getch(), count, true)); } }, { 'd', do_erase }, { 'c', do_change }, { 'i', [](Window& window, int count) { do_insert(window); } }, { 'a', [](Window& window, int count) { do_insert(window, true); } }, - { 'o', [](Window& window, int count) { window.select(true, select_line); window.append("\n"); do_insert(window, true); } }, { 'g', do_go }, @@ -443,20 +433,19 @@ std::unordered_map> keymap { 'p', do_paste }, { 'P', do_paste }, - { '%', [](Window& window, int count) { window.select(false, [](const BufferIterator& cursor) + { 'v', [](Window& window, int count) { window.set_select_mode(window.select_mode() == Window::SelectMode::Append ? + Window::SelectMode::Normal : Window::SelectMode::Append); } }, + + { '%', [](Window& window, int count) { window.select([](const BufferIterator& cursor) { return Selection(cursor.buffer().begin(), cursor.buffer().end()-1); }); } }, { ':', [](Window& window, int count) { do_command(); } }, { ' ', [](Window& window, int count) { window.empty_selections(); } }, - { 'w', [](Window& window, int count) { do { window.select(false, select_to_next_word); } while(--count > 0); } }, - { 'W', [](Window& window, int count) { do { window.select(true, select_to_next_word); } while(--count > 0); } }, - { 'e', [](Window& window, int count) { do { window.select(false, select_to_next_word_end); } while(--count > 0); } }, - { 'E', [](Window& window, int count) { do { window.select(true, select_to_next_word_end); } while(--count > 0); } }, - { 'b', [](Window& window, int count) { do { window.select(false, select_to_previous_word); } while(--count > 0); } }, - { 'B', [](Window& window, int count) { do { window.select(true, select_to_previous_word); } while(--count > 0); } }, - { '.', [](Window& window, int count) { do { window.select(false, select_line); } while(--count > 0); } }, - { 'm', [](Window& window, int count) { window.select(false, select_matching); } }, - { 'M', [](Window& window, int count) { window.select(true, select_matching); } }, + { 'w', [](Window& window, int count) { do { window.select(select_to_next_word); } while(--count > 0); } }, + { 'e', [](Window& window, int count) { do { window.select(select_to_next_word_end); } while(--count > 0); } }, + { 'b', [](Window& window, int count) { do { window.select(select_to_previous_word); } while(--count > 0); } }, + { '.', [](Window& window, int count) { do { window.select(select_line); } while(--count > 0); } }, + { 'm', [](Window& window, int count) { window.select(select_matching); } }, { '/', [](Window& window, int count) { do_search(window); } }, { 'n', [](Window& window, int count) { do_search_next(window); } }, { 'u', [](Window& window, int count) { do { if (not window.undo()) { print_status("nothing left to undo"); break; } } while(--count > 0); } }, diff --git a/src/window.cc b/src/window.cc index 85ab632d..0631416f 100644 --- a/src/window.cc +++ b/src/window.cc @@ -37,6 +37,7 @@ Window::Window(Buffer& buffer) : m_buffer(buffer), m_position(0, 0), m_dimensions(0, 0), + m_select_mode(SelectMode::Normal), m_current_inserter(nullptr) { m_selections.push_back(Selection(buffer.begin(), buffer.begin())); @@ -153,11 +154,11 @@ void Window::empty_selections() m_selections.push_back(std::move(sel)); } -void Window::select(bool append, const Selector& selector) +void Window::select(const Selector& selector) { check_invariant(); - if (not append) + if (m_select_mode == SelectMode::Normal) { Selection sel = selector(m_selections.back().last()); m_selections.clear(); @@ -183,7 +184,16 @@ BufferString Window::selection_content() const void Window::move_cursor(const WindowCoord& offset) { - move_cursor_to(cursor_position() + offset); + if (m_select_mode == SelectMode::Normal) + move_cursor_to(cursor_position() + offset); + else + { + for (auto& sel : m_selections) + { + WindowCoord pos = line_and_column_at(sel.last()); + sel = Selection(sel.first(), iterator_at(pos + offset)); + } + } } void Window::move_cursor_to(const WindowCoord& new_pos) diff --git a/src/window.hh b/src/window.hh index 911e9ceb..e953cf60 100644 --- a/src/window.hh +++ b/src/window.hh @@ -45,6 +45,13 @@ public: typedef BufferString String; typedef std::function Selector; + enum class SelectMode + { + Normal, + Append, + LineAppend, + }; + void erase(); void insert(const String& string); void append(const String& string); @@ -64,7 +71,7 @@ public: void move_cursor_to(const WindowCoord& new_pos); void empty_selections(); - void select(bool append, const Selector& selector); + void select(const Selector& selector); BufferString selection_content() const; void set_dimensions(const WindowCoord& dimensions); @@ -76,6 +83,9 @@ public: bool undo(); bool redo(); + SelectMode select_mode() const { return m_select_mode; } + void set_select_mode(SelectMode select_mode) { m_select_mode = select_mode; } + private: friend class Buffer; @@ -92,6 +102,7 @@ private: friend class IncrementalInserter; IncrementalInserter* m_current_inserter; + SelectMode m_select_mode; Buffer& m_buffer; BufferCoord m_position; WindowCoord m_dimensions;