Move (keep|flip|remove|clear)_selections from editor method to free selectors
This commit is contained in:
parent
dad27fe1a0
commit
77590fe2e8
|
@ -17,20 +17,6 @@ Editor::Editor(Buffer& buffer)
|
||||||
m_selections(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()
|
void Editor::erase()
|
||||||
{
|
{
|
||||||
scoped_edition edition(*this);
|
scoped_edition edition(*this);
|
||||||
|
@ -165,48 +151,6 @@ void Editor::move_selections(LineCount offset, SelectMode mode)
|
||||||
m_selections.sort_and_merge_overlapping();
|
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)
|
void Editor::select(const Selection& selection, SelectMode mode)
|
||||||
{
|
{
|
||||||
if (mode == SelectMode::Replace)
|
if (mode == SelectMode::Replace)
|
||||||
|
|
|
@ -57,10 +57,6 @@ public:
|
||||||
SelectMode mode = SelectMode::Replace);
|
SelectMode mode = SelectMode::Replace);
|
||||||
void move_selections(CharCount move,
|
void move_selections(CharCount move,
|
||||||
SelectMode mode = SelectMode::Replace);
|
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)
|
void select(BufferCoord c, SelectMode mode = SelectMode::Replace)
|
||||||
{ select(Selection{ buffer().clamp(c) }, mode); }
|
{ select(Selection{ buffer().clamp(c) }, mode); }
|
||||||
void select(const Selection& sel,
|
void select(const Selection& sel,
|
||||||
|
|
|
@ -1055,10 +1055,10 @@ KeyMap keymap =
|
||||||
|
|
||||||
{ ':', command },
|
{ ':', command },
|
||||||
{ '|', pipe },
|
{ '|', pipe },
|
||||||
{ ' ', [](Context& context, int count) { if (count == 0) context.editor().clear_selections();
|
{ ' ', [](Context& context, int count) { if (count == 0) context.editor().select(clear_selections);
|
||||||
else context.editor().keep_selection(count-1); } },
|
else context.editor().select(std::bind(keep_selection, _1, _2, count-1)); } },
|
||||||
{ alt(' '), [](Context& context, int count) { if (count == 0) context.editor().flip_selections();
|
{ alt(' '), [](Context& context, int count) { if (count == 0) context.editor().select(flip_selections);
|
||||||
else context.editor().remove_selection(count-1); } },
|
else context.editor().select(std::bind(remove_selection, _1, _2, count-1)); } },
|
||||||
{ 'w', repeated(select<SelectMode::Replace>(select_to_next_word<Word>)) },
|
{ 'w', repeated(select<SelectMode::Replace>(select_to_next_word<Word>)) },
|
||||||
{ 'e', repeated(select<SelectMode::Replace>(select_to_next_word_end<Word>)) },
|
{ 'e', repeated(select<SelectMode::Replace>(select_to_next_word_end<Word>)) },
|
||||||
{ 'b', repeated(select<SelectMode::Replace>(select_to_previous_word<Word>)) },
|
{ 'b', repeated(select<SelectMode::Replace>(select_to_previous_word<Word>)) },
|
||||||
|
|
|
@ -51,6 +51,21 @@ inline BufferIterator erase(Buffer& buffer, const Range& range)
|
||||||
utf8::next(buffer.iterator_at(range.max())));
|
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>;
|
using CaptureList = std::vector<String>;
|
||||||
|
|
||||||
// A selection is a Range, associated with a CaptureList
|
// A selection is a Range, associated with a CaptureList
|
||||||
|
|
|
@ -626,6 +626,7 @@ void select_all_matches(const Buffer& buffer, SelectionList& selections,
|
||||||
}
|
}
|
||||||
if (result.empty())
|
if (result.empty())
|
||||||
throw runtime_error("nothing selected");
|
throw runtime_error("nothing selected");
|
||||||
|
result.set_main_index(result.size() - 1);
|
||||||
selections = std::move(result);
|
selections = std::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,6 +651,7 @@ void split_selection(const Buffer& buffer, SelectionList& selections,
|
||||||
}
|
}
|
||||||
result.emplace_back(begin.coord(), sel.max());
|
result.emplace_back(begin.coord(), sel.max());
|
||||||
}
|
}
|
||||||
|
result.set_main_index(result.size() - 1);
|
||||||
selections = std::move(result);
|
selections = std::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,47 @@
|
||||||
namespace Kakoune
|
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 };
|
enum WordType { Word, WORD };
|
||||||
|
|
||||||
template<WordType word_type>
|
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,
|
void select_all_matches(const Buffer& buffer, SelectionList& selections,
|
||||||
const Regex& regex);
|
const Regex& regex);
|
||||||
|
|
||||||
void split_selection(const Buffer& buffer, SelectionList& selections,
|
void split_selection(const Buffer& buffer, SelectionList& selections,
|
||||||
const Regex& separator_regex);
|
const Regex& separator_regex);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user