Move (keep|flip|remove|clear)_selections from editor method to free selectors

This commit is contained in:
Maxime Coste 2013-12-14 14:08:26 +00:00
parent dad27fe1a0
commit 77590fe2e8
6 changed files with 63 additions and 65 deletions

View File

@ -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)

View File

@ -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,

View File

@ -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<SelectMode::Replace>(select_to_next_word<Word>)) },
{ 'e', repeated(select<SelectMode::Replace>(select_to_next_word_end<Word>)) },
{ 'b', repeated(select<SelectMode::Replace>(select_to_previous_word<Word>)) },

View File

@ -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<String>;
// A selection is a Range, associated with a CaptureList

View File

@ -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);
}

View File

@ -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<WordType word_type>
@ -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);