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:
parent
a07fde181a
commit
93dd1ff3c7
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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); });
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user