diff --git a/src/editor.cc b/src/editor.cc index 4f925374..95b4c0f5 100644 --- a/src/editor.cc +++ b/src/editor.cc @@ -17,20 +17,6 @@ Editor::Editor(Buffer& buffer) m_selections(buffer, { {{},{}} }) {} -void avoid_eol(const Buffer& buffer, BufferCoord& coord) -{ - const auto column = coord.column; - const auto& line = buffer[coord.line]; - if (column != 0 and column == line.length() - 1) - coord.column = line.byte_count_to(line.char_length() - 2); -} - -void avoid_eol(const Buffer& buffer, Range& sel) -{ - avoid_eol(buffer, sel.first()); - avoid_eol(buffer, sel.last()); -} - void Editor::erase() { scoped_edition edition(*this); @@ -165,48 +151,6 @@ void Editor::move_selections(LineCount offset, SelectMode mode) m_selections.sort_and_merge_overlapping(); } -void Editor::clear_selections() -{ - auto& sel = m_selections.main(); - auto& pos = sel.last(); - avoid_eol(*m_buffer, pos); - sel.first() = pos; - - m_selections = SelectionList{ std::move(sel) }; - check_invariant(); -} - -void Editor::flip_selections() -{ - for (auto& sel : m_selections) - std::swap(sel.first(), sel.last()); - check_invariant(); -} - -void Editor::keep_selection(int index) -{ - if (index < m_selections.size()) - { - size_t real_index = (index + m_selections.main_index() + 1) % m_selections.size(); - m_selections = SelectionList{ std::move(m_selections[real_index]) }; - } - check_invariant(); -} - -void Editor::remove_selection(int index) -{ - if (m_selections.size() > 1 and index < m_selections.size()) - { - size_t real_index = (index + m_selections.main_index() + 1) % m_selections.size(); - m_selections.erase(m_selections.begin() + real_index); - size_t main_index = m_selections.main_index(); - if (real_index <= main_index) - m_selections.set_main_index((main_index > 0 ? main_index - : m_selections.size()) - 1); - } - check_invariant(); -} - void Editor::select(const Selection& selection, SelectMode mode) { if (mode == SelectMode::Replace) diff --git a/src/editor.hh b/src/editor.hh index 16e4eb2b..f3076ad1 100644 --- a/src/editor.hh +++ b/src/editor.hh @@ -57,10 +57,6 @@ public: SelectMode mode = SelectMode::Replace); void move_selections(CharCount move, SelectMode mode = SelectMode::Replace); - void clear_selections(); - void flip_selections(); - void keep_selection(int index); - void remove_selection(int index); void select(BufferCoord c, SelectMode mode = SelectMode::Replace) { select(Selection{ buffer().clamp(c) }, mode); } void select(const Selection& sel, diff --git a/src/normal.cc b/src/normal.cc index 148b0369..219df354 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -1055,10 +1055,10 @@ KeyMap keymap = { ':', command }, { '|', pipe }, - { ' ', [](Context& context, int count) { if (count == 0) context.editor().clear_selections(); - else context.editor().keep_selection(count-1); } }, - { alt(' '), [](Context& context, int count) { if (count == 0) context.editor().flip_selections(); - else context.editor().remove_selection(count-1); } }, + { ' ', [](Context& context, int count) { if (count == 0) context.editor().select(clear_selections); + else context.editor().select(std::bind(keep_selection, _1, _2, count-1)); } }, + { alt(' '), [](Context& context, int count) { if (count == 0) context.editor().select(flip_selections); + else context.editor().select(std::bind(remove_selection, _1, _2, count-1)); } }, { 'w', repeated(select(select_to_next_word)) }, { 'e', repeated(select(select_to_next_word_end)) }, { 'b', repeated(select(select_to_previous_word)) }, diff --git a/src/selection.hh b/src/selection.hh index 6dae9e95..cd60f87d 100644 --- a/src/selection.hh +++ b/src/selection.hh @@ -51,6 +51,21 @@ inline BufferIterator erase(Buffer& buffer, const Range& range) utf8::next(buffer.iterator_at(range.max()))); } +inline void avoid_eol(const Buffer& buffer, BufferCoord& coord) +{ + const auto column = coord.column; + const auto& line = buffer[coord.line]; + if (column != 0 and column == line.length() - 1) + coord.column = line.byte_count_to(line.char_length() - 2); +} + +inline void avoid_eol(const Buffer& buffer, Range& sel) +{ + avoid_eol(buffer, sel.first()); + avoid_eol(buffer, sel.last()); +} + + using CaptureList = std::vector; // A selection is a Range, associated with a CaptureList diff --git a/src/selectors.cc b/src/selectors.cc index ac5523e7..dee4d1ef 100644 --- a/src/selectors.cc +++ b/src/selectors.cc @@ -626,6 +626,7 @@ void select_all_matches(const Buffer& buffer, SelectionList& selections, } if (result.empty()) throw runtime_error("nothing selected"); + result.set_main_index(result.size() - 1); selections = std::move(result); } @@ -650,6 +651,7 @@ void split_selection(const Buffer& buffer, SelectionList& selections, } result.emplace_back(begin.coord(), sel.max()); } + result.set_main_index(result.size() - 1); selections = std::move(result); } diff --git a/src/selectors.hh b/src/selectors.hh index 4005a716..64887e31 100644 --- a/src/selectors.hh +++ b/src/selectors.hh @@ -8,6 +8,47 @@ namespace Kakoune { +inline void clear_selections(const Buffer& buffer, SelectionList& selections) +{ + auto& sel = selections.main(); + auto& pos = sel.last(); + avoid_eol(buffer, pos); + sel.first() = pos; + + selections = SelectionList{ std::move(sel) }; +} + +inline void flip_selections(const Buffer&, SelectionList& selections) +{ + for (auto& sel : selections) + std::swap(sel.first(), sel.last()); + selections.check_invariant(); +} + +inline void keep_selection(const Buffer&, SelectionList& selections, int index) +{ + if (index < selections.size()) + { + size_t real_index = (index + selections.main_index() + 1) % selections.size(); + selections = SelectionList{ std::move(selections[real_index]) }; + } + selections.check_invariant(); +} + +inline void remove_selection(const Buffer&, SelectionList& selections, int index) +{ + if (selections.size() > 1 and index < selections.size()) + { + size_t real_index = (index + selections.main_index() + 1) % selections.size(); + selections.erase(selections.begin() + real_index); + size_t main_index = selections.main_index(); + if (real_index <= main_index) + selections.set_main_index((main_index > 0 ? main_index + : selections.size()) - 1); + } + selections.check_invariant(); +} + enum WordType { Word, WORD }; template @@ -127,7 +168,7 @@ void select_next_match(const Buffer& buffer, SelectionList& selections, } void select_all_matches(const Buffer& buffer, SelectionList& selections, - const Regex& regex); + const Regex& regex); void split_selection(const Buffer& buffer, SelectionList& selections, const Regex& separator_regex);