Skip to content

Commit

Permalink
Return an optional selection in most selectors, fail rather than keep…
Browse files Browse the repository at this point in the history
… current

Instead of returning the current selection when a selector fails, return
an empty Optional<Selection>. That means object selections will now
remove the selections that dont match the object.
  • Loading branch information
mawww committed Mar 3, 2017
1 parent 6759511 commit ddc5e95
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 114 deletions.
42 changes: 29 additions & 13 deletions src/normal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,33 +40,49 @@ void select(Context& context, T func)
if (mode == SelectMode::Append)
{
auto& sel = selections.main();
auto res = func(buffer, sel);
if (res.captures().empty())
res.captures() = sel.captures();
selections.push_back(res);
selections.set_main_index(selections.size() - 1);
if (auto res = func(buffer, sel))
{
if (res->captures().empty())
res->captures() = sel.captures();
selections.push_back(std::move(*res));
selections.set_main_index(selections.size() - 1);
}
}
else
{
for (auto& sel : selections)
Vector<int> to_remove;
for (int i = 0; i < (int)selections.size(); ++i)
{
auto& sel = selections[i];
auto res = func(buffer, sel);
if (not res)
{
to_remove.push_back(i);
continue;
}

if (mode == SelectMode::Extend)
sel.merge_with(res);
sel.merge_with(*res);
else
{
sel.anchor() = res.anchor();
sel.cursor() = res.cursor();
sel.anchor() = res->anchor();
sel.cursor() = res->cursor();
}
if (not res.captures().empty())
sel.captures() = std::move(res.captures());
if (not res->captures().empty())
sel.captures() = std::move(res->captures());
}

if (to_remove.size() == selections.size())
throw runtime_error{"no selections remaining"};
for (auto& i : to_remove | reverse())
selections.remove(i);
}

selections.sort_and_merge_overlapping();
selections.check_invariant();
}

template<SelectMode mode, Selection (*func)(const Buffer&, const Selection&)>
template<SelectMode mode, Optional<Selection> (*func)(const Buffer&, const Selection&)>
void select(Context& context, NormalParams)
{
select<mode>(context, func);
Expand Down Expand Up @@ -1053,7 +1069,7 @@ void select_object(Context& context, NormalParams params)
static constexpr struct ObjectType
{
Codepoint key;
Selection (*func)(const Buffer&, const Selection&, int, ObjectFlags);
Optional<Selection> (*func)(const Buffer&, const Selection&, int, ObjectFlags);
} selectors[] = {
{ 'w', select_word<Word> },
{ 'W', select_word<WORD> },
Expand Down
Loading

0 comments on commit ddc5e95

Please sign in to comment.