Remove begin/end from Ranges, replace with min/max

Ranges should not be utf8 aware (needed for end), and a lot of
uses for end() were in fact looking for max.
This commit is contained in:
Maxime Coste 2013-05-24 14:25:50 +02:00
parent a07fde181a
commit 93dd1ff3c7
8 changed files with 52 additions and 62 deletions

View File

@ -711,9 +711,9 @@ void info(const CommandParameters& params, Context& context)
auto it = sel.last(); auto it = sel.last();
String anchor = parser.option_value("anchor"); String anchor = parser.option_value("anchor");
if (anchor == "left") if (anchor == "left")
it = sel.begin(); it = sel.min();
else if (anchor == "right") else if (anchor == "right")
it = sel.end() - 1; it = sel.max();
else if (anchor != "cursor") else if (anchor != "cursor")
throw runtime_error("anchor param must be one of [left, right, cursor]"); throw runtime_error("anchor param must be one of [left, right, cursor]");
pos = context.window().display_position(it); pos = context.window().display_position(it);

View File

@ -38,7 +38,7 @@ void Editor::erase()
scoped_edition edition(*this); scoped_edition edition(*this);
for (auto& sel : m_selections) for (auto& sel : m_selections)
{ {
m_buffer->erase(sel.begin().coord(), sel.end().coord()); m_buffer->erase(sel.min(), utf8::next(sel.max()));
avoid_eol(sel); avoid_eol(sel);
} }
} }
@ -49,11 +49,11 @@ static BufferIterator prepare_insert(Buffer& buffer, const Selection& sel,
switch (mode) switch (mode)
{ {
case InsertMode::Insert: case InsertMode::Insert:
return sel.begin(); return sel.min();
case InsertMode::Replace: case InsertMode::Replace:
{ {
BufferIterator pos = sel.begin(); BufferIterator pos = sel.min();
buffer.erase(sel.begin().coord(), sel.end().coord()); buffer.erase(sel.min(), utf8::next(sel.max()));
return pos; return pos;
} }
case InsertMode::Append: case InsertMode::Append:
@ -66,16 +66,16 @@ static BufferIterator prepare_insert(Buffer& buffer, const Selection& sel,
return utf8::next(pos); return utf8::next(pos);
} }
case InsertMode::InsertAtLineBegin: case InsertMode::InsertAtLineBegin:
return buffer.iterator_at_line_begin(sel.begin()); return buffer.iterator_at_line_begin(sel.min());
case InsertMode::AppendAtLineEnd: case InsertMode::AppendAtLineEnd:
return buffer.iterator_at_line_end(sel.end()-1)-1; return buffer.iterator_at_line_end(sel.max())-1;
case InsertMode::InsertAtNextLineBegin: case InsertMode::InsertAtNextLineBegin:
return buffer.iterator_at_line_end(sel.end()-1); return buffer.iterator_at_line_end(sel.max());
case InsertMode::OpenLineBelow: case InsertMode::OpenLineBelow:
case InsertMode::OpenLineAbove: case InsertMode::OpenLineAbove:
{ {
auto line = mode == InsertMode::OpenLineAbove ? auto line = mode == InsertMode::OpenLineAbove ?
sel.begin().line() : (sel.end() - 1).line() + 1; sel.min().line() : sel.max().line() + 1;
buffer.insert(line, "\n"); buffer.insert(line, "\n");
return {buffer, line}; return {buffer, line};
} }
@ -135,7 +135,7 @@ std::vector<String> Editor::selections_content() const
static bool compare_selections(const Selection& lhs, const Selection& rhs) static bool compare_selections(const Selection& lhs, const Selection& rhs)
{ {
return lhs.begin() < rhs.begin(); return lhs.min() < rhs.min();
} }
template<typename OverlapsFunc> template<typename OverlapsFunc>
@ -163,14 +163,14 @@ void sort_and_merge_overlapping(SelectionList& selections, size_t& main_selectio
return; return;
const auto& main = selections[main_selection]; const auto& main = selections[main_selection];
const auto main_begin = main.begin(); const auto main_begin = main.min();
main_selection = std::count_if(selections.begin(), selections.end(), main_selection = std::count_if(selections.begin(), selections.end(),
[&](const Selection& sel) { [&](const Selection& sel) {
auto begin = sel.begin(); auto begin = sel.min();
if (begin == main_begin) if (begin == main_begin)
return &sel < &main; return &sel < &main;
else else
return sel.begin() < main_begin; return begin < main_begin;
}); });
std::stable_sort(selections.begin(), selections.end(), compare_selections); std::stable_sort(selections.begin(), selections.end(), compare_selections);
@ -369,7 +369,7 @@ public:
m_ranges.update_insert(begin, end); m_ranges.update_insert(begin, end);
auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), begin, auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), begin,
[](const BufferCoord& c, const Selection& sel) [](const BufferCoord& c, const Selection& sel)
{ return c < sel.begin().coord(); }); { return c < sel.min().coord(); });
m_ranges.emplace(it, registry().iterator_at(begin), m_ranges.emplace(it, registry().iterator_at(begin),
utf8::previous(registry().iterator_at(end))); utf8::previous(registry().iterator_at(end)));
} }
@ -383,7 +383,7 @@ public:
auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), begin, auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), begin,
[](const BufferCoord& c, const Selection& sel) [](const BufferCoord& c, const Selection& sel)
{ return c < sel.begin().coord(); }); { return c < sel.min().coord(); });
m_ranges.emplace(it, pos, pos); m_ranges.emplace(it, pos, pos);
} }
SelectionList& ranges() { return m_ranges; } SelectionList& ranges() { return m_ranges; }
@ -392,6 +392,12 @@ private:
SelectionList m_ranges; SelectionList m_ranges;
}; };
inline bool touches(const Range& lhs, const Range& rhs)
{
return lhs.min() <= rhs.min() ? utf8::next(lhs.max()) >= rhs.min()
: lhs.min() <= utf8::next(rhs.max());
}
bool Editor::undo() bool Editor::undo()
{ {
ModifiedRangesListener listener(buffer()); ModifiedRangesListener listener(buffer());
@ -457,16 +463,16 @@ IncrementalInserter::IncrementalInserter(Editor& editor, InsertMode mode)
utf8_it first, last; utf8_it first, last;
switch (mode) switch (mode)
{ {
case InsertMode::Insert: first = utf8_it(sel.end()) - 1; last = sel.begin(); break; case InsertMode::Insert: first = sel.max(); last = sel.min(); break;
case InsertMode::Replace: case InsertMode::Replace:
{ {
buffer.erase(sel.begin(), sel.end()); buffer.erase(sel.min(), utf8::next(sel.max()));
first = last = sel.begin(); first = last = sel.min();
break; break;
} }
case InsertMode::Append: case InsertMode::Append:
{ {
first = sel.begin(); first = sel.min();
last = std::max(sel.first(), sel.last()); last = std::max(sel.first(), sel.last());
// special case for end of lines, append to current line instead // special case for end of lines, append to current line instead
auto coord = last.underlying_iterator().coord(); auto coord = last.underlying_iterator().coord();
@ -477,13 +483,13 @@ IncrementalInserter::IncrementalInserter(Editor& editor, InsertMode mode)
case InsertMode::OpenLineBelow: case InsertMode::OpenLineBelow:
case InsertMode::AppendAtLineEnd: case InsertMode::AppendAtLineEnd:
first = utf8_it(buffer.iterator_at_line_end(utf8::previous(sel.end()))) - 1; first = utf8_it(buffer.iterator_at_line_end(sel.max())) - 1;
last = first; last = first;
break; break;
case InsertMode::OpenLineAbove: case InsertMode::OpenLineAbove:
case InsertMode::InsertAtLineBegin: case InsertMode::InsertAtLineBegin:
first = buffer.iterator_at_line_begin(sel.begin()); first = buffer.iterator_at_line_begin(sel.min());
if (mode == InsertMode::OpenLineAbove) if (mode == InsertMode::OpenLineAbove)
--first; --first;
else else

View File

@ -97,8 +97,9 @@ void register_env_vars()
shell_manager.register_env_var("selection_desc", shell_manager.register_env_var("selection_desc",
[](const String& name, const Context& context) [](const String& name, const Context& context)
{ auto& sel = context.editor().main_selection(); { auto& sel = context.editor().main_selection();
auto beg = sel.begin(); auto beg = sel.min();
return to_string(beg.line() + 1) + ':' + to_string(beg.column() + 1) + '+' + to_string((sel.end() - beg)); }); return to_string(beg.line() + 1) + ':' + to_string(beg.column() + 1) + '+' +
to_string((int)context.buffer().distance(beg, sel.max())+1); });
shell_manager.register_env_var("window_width", shell_manager.register_env_var("window_width",
[](const String& name, const Context& context) [](const String& name, const Context& context)
{ return to_string(context.window().dimensions().column); }); { return to_string(context.window().dimensions().column); });

View File

@ -247,7 +247,7 @@ void pipe(Context& context)
Editor& editor = context.editor(); Editor& editor = context.editor();
std::vector<String> strings; std::vector<String> strings;
for (auto& sel : context.editor().selections()) for (auto& sel : context.editor().selections())
strings.push_back(ShellManager::instance().pipe({sel.begin(), sel.end()}, strings.push_back(ShellManager::instance().pipe({sel.min(), utf8::next(sel.max())},
cmdline, context, {}, cmdline, context, {},
EnvVarMap{})); EnvVarMap{}));
editor.insert(strings, InsertMode::Replace); editor.insert(strings, InsertMode::Replace);
@ -333,8 +333,8 @@ void use_selection_as_search_pattern(Context& context)
auto& sels = context.editor().selections(); auto& sels = context.editor().selections();
for (auto& sel : sels) for (auto& sel : sels)
{ {
auto begin = sel.begin(); auto begin = sel.min();
auto end = sel.end(); auto end = utf8::next(sel.max());
auto content = "\\Q" + context.buffer().string(begin, end) + "\\E"; auto content = "\\Q" + context.buffer().string(begin, end) + "\\E";
if (smart) if (smart)
{ {
@ -476,8 +476,8 @@ void join_select_spaces(Context& context)
// remove last end of line if selected // remove last end of line if selected
kak_assert(std::is_sorted(res.begin(), res.end(), kak_assert(std::is_sorted(res.begin(), res.end(),
[](const Selection& lhs, const Selection& rhs) [](const Selection& lhs, const Selection& rhs)
{ return lhs.begin() < rhs.begin(); })); { return lhs.min() < rhs.min(); }));
if (not res.empty() and res.back().end() == sel.buffer().end()) if (not res.empty() and utf8::next(res.back().max()).is_end())
res.pop_back(); res.pop_back();
return res; return res;
}); });
@ -502,7 +502,7 @@ void keep(Context& context)
SelectionList keep; SelectionList keep;
for (auto& sel : sels) for (auto& sel : sels)
{ {
if (boost::regex_search(sel.begin(), sel.end(), ex) == matching) if (boost::regex_search(sel.min(), utf8::next(sel.max()), ex) == matching)
keep.push_back(sel); keep.push_back(sel);
} }
if (keep.empty()) if (keep.empty())

View File

@ -14,19 +14,9 @@ void Range::merge_with(const Range& range)
m_first = std::max(m_first, range.m_first); m_first = std::max(m_first, range.m_first);
} }
BufferIterator Range::begin() const
{
return std::min(m_first, m_last);
}
BufferIterator Range::end() const
{
return utf8::next(std::max(m_first, m_last));
}
String Range::content() const String Range::content() const
{ {
return m_first.buffer().string(begin(), end()); return m_first.buffer().string(min(), utf8::next(max()));
} }
void Range::check_invariant() const void Range::check_invariant() const
@ -137,7 +127,7 @@ void SelectionList::check_invariant() const
auto& sel = (*this)[i]; auto& sel = (*this)[i];
sel.check_invariant(); sel.check_invariant();
if (i+1 < size()) if (i+1 < size())
kak_assert(sel.begin() <= (*this)[i+1].begin()); kak_assert(sel.min() <= (*this)[i+1].min());
} }
#endif #endif
} }

View File

@ -26,10 +26,8 @@ public:
return m_first == other.m_first and m_last == other.m_last; return m_first == other.m_first and m_last == other.m_last;
} }
// returns min(first, last) const BufferIterator& min() const { return std::min(m_first, m_last); }
BufferIterator begin() const; const BufferIterator& max() const { return std::max(m_first, m_last); }
// returns max(first, last) + 1
BufferIterator end() const;
String content() const; String content() const;
@ -41,14 +39,8 @@ private:
inline bool overlaps(const Range& lhs, const Range& rhs) inline bool overlaps(const Range& lhs, const Range& rhs)
{ {
return lhs.begin() <= rhs.begin() ? lhs.end() > rhs.begin() return lhs.min() <= rhs.min() ? lhs.max() >= rhs.min()
: lhs.begin() < rhs.end(); : lhs.min() <= rhs.max();
}
inline bool touches(const Range& lhs, const Range& rhs)
{
return lhs.begin() <= rhs.begin() ? lhs.end() >= rhs.begin()
: lhs.begin() <= rhs.end();
} }
using CaptureList = std::vector<String>; using CaptureList = std::vector<String>;

View File

@ -598,7 +598,8 @@ template Selection select_next_match<false>(const Selection&, const Regex&);
SelectionList select_all_matches(const Selection& selection, const Regex& regex) SelectionList select_all_matches(const Selection& selection, const Regex& regex)
{ {
RegexIterator re_it(selection.begin(), selection.end(), regex); auto sel_end = utf8::next(selection.max());
RegexIterator re_it(selection.min(), sel_end, regex);
RegexIterator re_end; RegexIterator re_end;
SelectionList result; SelectionList result;
@ -607,7 +608,7 @@ SelectionList select_all_matches(const Selection& selection, const Regex& regex)
BufferIterator begin = (*re_it)[0].first; BufferIterator begin = (*re_it)[0].first;
BufferIterator end = (*re_it)[0].second; BufferIterator end = (*re_it)[0].second;
if (begin == selection.end()) if (begin == sel_end)
continue; continue;
CaptureList captures; CaptureList captures;
@ -623,12 +624,13 @@ SelectionList select_all_matches(const Selection& selection, const Regex& regex)
SelectionList split_selection(const Selection& selection, SelectionList split_selection(const Selection& selection,
const Regex& regex) const Regex& regex)
{ {
RegexIterator re_it(selection.begin(), selection.end(), regex, auto sel_end = utf8::next(selection.max());
RegexIterator re_it(selection.min(), sel_end, regex,
boost::regex_constants::match_nosubs); boost::regex_constants::match_nosubs);
RegexIterator re_end; RegexIterator re_end;
SelectionList result; SelectionList result;
BufferIterator begin = selection.begin(); BufferIterator begin = selection.min();
for (; re_it != re_end; ++re_it) for (; re_it != re_end; ++re_it)
{ {
BufferIterator end = (*re_it)[0].first; BufferIterator end = (*re_it)[0].first;
@ -636,8 +638,7 @@ SelectionList split_selection(const Selection& selection,
result.push_back(Selection(begin, (begin == end) ? end : utf8::previous(end))); result.push_back(Selection(begin, (begin == end) ? end : utf8::previous(end)));
begin = (*re_it)[0].second; begin = (*re_it)[0].second;
} }
result.push_back(Selection(begin, std::max(selection.first(), result.push_back(Selection(begin, selection.max()));
selection.last())));
return result; return result;
} }

View File

@ -61,8 +61,8 @@ void test_editor()
editor.multi_select(std::bind(select_all_matches, std::placeholders::_1, Regex{"\\n\\h*"})); editor.multi_select(std::bind(select_all_matches, std::placeholders::_1, Regex{"\\n\\h*"}));
for (auto& sel : editor.selections()) for (auto& sel : editor.selections())
{ {
kak_assert(*sel.begin() == '\n'); kak_assert(*sel.min() == '\n');
editor.buffer().erase(sel.begin(), sel.end()); editor.buffer().erase(sel.min(), utf8::next(sel.max()));
} }
} }
editor.undo(); editor.undo();