Remove references to SelectionList from selectors

This commit is contained in:
Maxime Coste 2019-02-04 12:52:55 +11:00
parent 7f9fe32f2d
commit 4cb402ac1a
4 changed files with 34 additions and 24 deletions

View File

@ -973,8 +973,10 @@ void select_regex(Context& context, NormalParams params)
RegisterManager::instance()[reg].set(context, ex.str()); RegisterManager::instance()[reg].set(context, ex.str());
auto& selections = context.selections();
auto& buffer = selections.buffer();
if (not ex.empty() and not ex.str().empty()) if (not ex.empty() and not ex.str().empty())
select_all_matches(context.selections(), ex, capture); selections = SelectionList{buffer, select_matches(buffer, selections, ex, capture)};
}); });
} }
@ -998,8 +1000,10 @@ void split_regex(Context& context, NormalParams params)
RegisterManager::instance()[reg].set(context, ex.str()); RegisterManager::instance()[reg].set(context, ex.str());
auto& selections = context.selections();
auto& buffer = selections.buffer();
if (not ex.empty() and not ex.str().empty()) if (not ex.empty() and not ex.str().empty())
split_selections(context.selections(), ex, capture); selections = SelectionList{buffer, split_on_matches(buffer, selections, ex, capture)};
}); });
} }

View File

@ -129,6 +129,7 @@ struct SelectionList
void remove(size_t index); void remove(size_t index);
const Selection* data() const { return m_selections.data(); }
size_t size() const { return m_selections.size(); } size_t size() const { return m_selections.size(); }
bool operator==(const SelectionList& other) const { return m_buffer == other.m_buffer and m_selections == other.m_selections; } bool operator==(const SelectionList& other) const { return m_buffer == other.m_buffer and m_selections == other.m_selections; }

View File

@ -3,11 +3,10 @@
#include "buffer_utils.hh" #include "buffer_utils.hh"
#include "context.hh" #include "context.hh"
#include "flags.hh" #include "flags.hh"
#include "optional.hh"
#include "option_types.hh" #include "option_types.hh"
#include "regex.hh" #include "regex.hh"
#include "selection.hh"
#include "string.hh" #include "string.hh"
#include "unicode.hh"
#include "unit_tests.hh" #include "unit_tests.hh"
#include "utf8_iterator.hh" #include "utf8_iterator.hh"
@ -38,6 +37,13 @@ ConstArrayView<Codepoint> get_extra_word_chars(const Context& context)
} }
Selection keep_direction(Selection res, const Selection& ref)
{
if ((res.cursor() < res.anchor()) != (ref.cursor() < ref.anchor()))
std::swap<BufferCoord>(res.cursor(), res.anchor());
return res;
}
template<WordType word_type> template<WordType word_type>
Optional<Selection> Optional<Selection>
select_to_next_word(const Context& context, const Selection& selection) select_to_next_word(const Context& context, const Selection& selection)
@ -913,14 +919,13 @@ Selection find_next_match(const Context& context, const Selection& sel, const Re
template Selection find_next_match<RegexMode::Forward>(const Context&, const Selection&, const Regex&, bool&); template Selection find_next_match<RegexMode::Forward>(const Context&, const Selection&, const Regex&, bool&);
template Selection find_next_match<RegexMode::Backward>(const Context&, const Selection&, const Regex&, bool&); template Selection find_next_match<RegexMode::Backward>(const Context&, const Selection&, const Regex&, bool&);
void select_all_matches(SelectionList& selections, const Regex& regex, int capture) Vector<Selection> select_matches(const Buffer& buffer, ConstArrayView<Selection> selections, const Regex& regex, int capture)
{ {
const int mark_count = (int)regex.mark_count(); const int mark_count = (int)regex.mark_count();
if (capture < 0 or capture > mark_count) if (capture < 0 or capture > mark_count)
throw runtime_error("invalid capture number"); throw runtime_error("invalid capture number");
Vector<Selection> result; Vector<Selection> result;
auto& buffer = selections.buffer();
ThreadedRegexVM<BufferIterator, RegexMode::Forward | RegexMode::Search> vm{*regex.impl()}; ThreadedRegexVM<BufferIterator, RegexMode::Forward | RegexMode::Search> vm{*regex.impl()};
for (auto& sel : selections) for (auto& sel : selections)
{ {
@ -948,26 +953,22 @@ void select_all_matches(SelectionList& selections, const Regex& regex, int captu
} }
if (result.empty()) if (result.empty())
throw runtime_error("nothing selected"); throw runtime_error("nothing selected");
return result;
// Avoid SelectionList::operator=(Vector<Selection>) as we know result is
// already sorted and non overlapping.
selections = SelectionList{buffer, std::move(result)};
} }
void split_selections(SelectionList& selections, const Regex& regex, int capture) Vector<Selection> split_on_matches(const Buffer& buffer, ConstArrayView<Selection> selections, const Regex& regex, int capture)
{ {
if (capture < 0 or capture > (int)regex.mark_count()) if (capture < 0 or capture > (int)regex.mark_count())
throw runtime_error("invalid capture number"); throw runtime_error("invalid capture number");
Vector<Selection> result; Vector<Selection> result;
auto& buffer = selections.buffer();
auto buf_end = buffer.end(); auto buf_end = buffer.end();
auto buf_begin = buffer.begin(); auto buf_begin = buffer.begin();
ThreadedRegexVM<BufferIterator, RegexMode::Forward | RegexMode::Search> vm{*regex.impl()}; ThreadedRegexVM<BufferIterator, RegexMode::Forward | RegexMode::Search> vm{*regex.impl()};
for (auto& sel : selections) for (auto& sel : selections)
{ {
auto begin = buffer.iterator_at(sel.min()); auto begin = buffer.iterator_at(sel.min());
auto sel_end = utf8::next(buffer.iterator_at(sel.max()), buffer.end()); auto sel_end = utf8::next(buffer.iterator_at(sel.max()), buf_end);
for (auto&& match : RegexIterator{begin, sel_end, vm, match_flags(buffer, begin, sel_end)}) for (auto&& match : RegexIterator{begin, sel_end, vm, match_flags(buffer, begin, sel_end)})
{ {
@ -987,8 +988,7 @@ void split_selections(SelectionList& selections, const Regex& regex, int capture
} }
if (result.empty()) if (result.empty())
throw runtime_error("nothing selected"); throw runtime_error("nothing selected");
return result;
selections = std::move(result);
} }
UnitTest test_find_surrounding{[]() UnitTest test_find_surrounding{[]()

View File

@ -1,20 +1,20 @@
#ifndef selectors_hh_INCLUDED #ifndef selectors_hh_INCLUDED
#define selectors_hh_INCLUDED #define selectors_hh_INCLUDED
#include "selection.hh" #include "optional.hh"
#include "meta.hh"
#include "unicode.hh"
#include "vector.hh"
namespace Kakoune namespace Kakoune
{ {
class Selection;
class Buffer;
class Regex; class Regex;
class Context; class Context;
inline Selection keep_direction(Selection res, const Selection& ref) Selection keep_direction(Selection res, const Selection& ref);
{
if ((res.cursor() < res.anchor()) != (ref.cursor() < ref.anchor()))
std::swap<BufferCoord>(res.cursor(), res.anchor());
return res;
}
template<WordType word_type> template<WordType word_type>
Optional<Selection> Optional<Selection>
@ -103,8 +103,13 @@ template<RegexMode mode>
Selection find_next_match(const Context& context, const Selection& sel, Selection find_next_match(const Context& context, const Selection& sel,
const Regex& regex, bool& wrapped); const Regex& regex, bool& wrapped);
void select_all_matches(SelectionList& selections, const Regex& regex, int capture = 0); Vector<Selection, MemoryDomain::Selections>
void split_selections(SelectionList& selections, const Regex& regex, int capture = 0); select_matches(const Buffer& buffer, ConstArrayView<Selection> selections,
const Regex& regex, int capture = 0);
Vector<Selection, MemoryDomain::Selections>
split_on_matches(const Buffer& buffer, ConstArrayView<Selection> selections,
const Regex& regex, int capture = 0);
Optional<Selection> Optional<Selection>
select_surrounding(const Context& context, const Selection& selection, select_surrounding(const Context& context, const Selection& selection,