MultiSelectors takes a reference to the current selection and mutate it

This commit is contained in:
Maxime Coste 2013-12-13 09:11:48 +00:00
parent db048a0792
commit f53ba0baed
5 changed files with 29 additions and 27 deletions

View File

@ -282,7 +282,7 @@ struct nothing_selected : public runtime_error
void Editor::multi_select(const MultiSelector& selector) void Editor::multi_select(const MultiSelector& selector)
{ {
m_selections = selector(*m_buffer, std::move(m_selections)); selector(*m_buffer, m_selections);
check_invariant(); check_invariant();
} }

View File

@ -40,7 +40,7 @@ class Editor : public SafeCountable
{ {
public: public:
typedef std::function<Selection (const Buffer&, const Selection&)> Selector; typedef std::function<Selection (const Buffer&, const Selection&)> Selector;
typedef std::function<SelectionList (const Buffer&, SelectionList)> MultiSelector; typedef std::function<void (const Buffer&, SelectionList&)> MultiSelector;
Editor(Buffer& buffer); Editor(Buffer& buffer);
virtual ~Editor() {} virtual ~Editor() {}

View File

@ -497,12 +497,15 @@ void split_regex(Context& context, int)
void split_lines(Context& context, int) void split_lines(Context& context, int)
{ {
context.editor().multi_select([](const Buffer& buffer, context.editor().multi_select([](const Buffer& buffer,
SelectionList selections) { SelectionList& selections) {
SelectionList res; SelectionList res;
for (auto& sel : selections) for (auto& sel : selections)
{ {
if (sel.first().line == sel.last().line) if (sel.first().line == sel.last().line)
return SelectionList{ sel }; {
res.push_back(std::move(sel));
continue;
}
auto min = sel.min(); auto min = sel.min();
auto max = sel.max(); auto max = sel.max();
res.push_back({min, {min.line, buffer[min.line].length()-1}}); res.push_back({min, {min.line, buffer[min.line].length()-1}});
@ -510,7 +513,7 @@ void split_lines(Context& context, int)
res.push_back({line, {line, buffer[line].length()-1}}); res.push_back({line, {line, buffer[line].length()-1}});
res.push_back({max.line, max}); res.push_back({max.line, max});
} }
return res; selections = std::move(res);
}); });
} }
@ -519,17 +522,15 @@ void join_select_spaces(Context& context, int)
Editor& editor = context.editor(); Editor& editor = context.editor();
editor.select(select_whole_lines); editor.select(select_whole_lines);
editor.select(select_to_eol, SelectMode::Extend); editor.select(select_to_eol, SelectMode::Extend);
editor.multi_select([](const Buffer& buffer, SelectionList sel) editor.multi_select([](const Buffer& buffer, SelectionList& sel)
{ {
SelectionList res = select_all_matches(buffer, std::move(sel), select_all_matches(buffer, sel, Regex{"(\n\\h*)+"});
Regex{"(\n\\h*)+"});
// 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(sel.begin(), sel.end(),
[](const Selection& lhs, const Selection& rhs) [](const Selection& lhs, const Selection& rhs)
{ return lhs.min() < rhs.min(); })); { return lhs.min() < rhs.min(); }));
if (not res.empty() and res.back().max() == buffer.back_coord()) if (not sel.empty() and sel.back().max() == buffer.back_coord())
res.pop_back(); sel.pop_back();
return res;
}); });
editor.insert(" ", InsertMode::Replace); editor.insert(" ", InsertMode::Replace);
} }
@ -573,7 +574,7 @@ void indent(Context& context, int)
Editor& editor = context.editor(); Editor& editor = context.editor();
DynamicSelectionList sels{editor.buffer(), editor.selections()}; DynamicSelectionList sels{editor.buffer(), editor.selections()};
auto restore_sels = on_scope_end([&]{ editor.select((SelectionList)std::move(sels)); }); auto restore_sels = on_scope_end([&]{ editor.select((SelectionList)std::move(sels)); });
editor.multi_select([&indent](const Buffer& buf, SelectionList selections) { editor.multi_select([&indent](const Buffer& buf, SelectionList& selections) {
SelectionList res; SelectionList res;
for (auto& sel : selections) for (auto& sel : selections)
{ {
@ -583,7 +584,7 @@ void indent(Context& context, int)
res.emplace_back(line, line); res.emplace_back(line, line);
} }
} }
return res; selections = std::move(res);
}); });
editor.insert(indent, InsertMode::Insert); editor.insert(indent, InsertMode::Insert);
} }
@ -600,7 +601,7 @@ void deindent(Context& context, int)
DynamicSelectionList sels{editor.buffer(), editor.selections()}; DynamicSelectionList sels{editor.buffer(), editor.selections()};
auto restore_sels = on_scope_end([&]{ editor.select((SelectionList)std::move(sels)); }); auto restore_sels = on_scope_end([&]{ editor.select((SelectionList)std::move(sels)); });
editor.multi_select([indent_width,tabstop](const Buffer& buf, SelectionList selections) { editor.multi_select([indent_width,tabstop](const Buffer& buf, SelectionList& selections) {
SelectionList res; SelectionList res;
for (auto& sel : selections) for (auto& sel : selections)
{ {
@ -629,7 +630,7 @@ void deindent(Context& context, int)
} }
} }
} }
return res; selections = std::move(res);
}); });
editor.erase(); editor.erase();
} }

View File

@ -597,8 +597,8 @@ Selection select_whole_buffer(const Buffer& buffer, const Selection&)
return Selection({0,0}, buffer.back_coord()); return Selection({0,0}, buffer.back_coord());
} }
SelectionList select_all_matches(const Buffer& buffer, SelectionList selections, void select_all_matches(const Buffer& buffer, SelectionList& selections,
const Regex& regex) const Regex& regex)
{ {
SelectionList result; SelectionList result;
for (auto& sel : selections) for (auto& sel : selections)
@ -624,11 +624,13 @@ SelectionList select_all_matches(const Buffer& buffer, SelectionList selections,
std::move(captures)); std::move(captures));
} }
} }
return result; if (result.empty())
throw runtime_error("nothing selected");
selections = std::move(result);
} }
SelectionList split_selection(const Buffer& buffer, SelectionList selections, void split_selection(const Buffer& buffer, SelectionList& selections,
const Regex& regex) const Regex& regex)
{ {
SelectionList result; SelectionList result;
for (auto& sel : selections) for (auto& sel : selections)
@ -648,7 +650,7 @@ SelectionList split_selection(const Buffer& buffer, SelectionList selections,
} }
result.emplace_back(begin.coord(), sel.max()); result.emplace_back(begin.coord(), sel.max());
} }
return result; selections = std::move(result);
} }
} }

View File

@ -88,7 +88,7 @@ bool find_match_in_buffer(const Buffer& buffer, const BufferIterator pos,
} }
template<Direction direction, SelectMode mode> template<Direction direction, SelectMode mode>
SelectionList select_next_match(const Buffer& buffer, SelectionList selections, void select_next_match(const Buffer& buffer, SelectionList& selections,
const Regex& regex) const Regex& regex)
{ {
auto& sel = selections.main(); auto& sel = selections.main();
@ -115,7 +115,7 @@ SelectionList select_next_match(const Buffer& buffer, SelectionList selections,
Selection res{begin.coord(), end.coord(), std::move(captures)}; Selection res{begin.coord(), end.coord(), std::move(captures)};
if (mode == SelectMode::Replace) if (mode == SelectMode::Replace)
return SelectionList{ std::move(res) }; selections = SelectionList{ std::move(res) };
else if (mode == SelectMode::ReplaceMain) else if (mode == SelectMode::ReplaceMain)
sel = std::move(res); sel = std::move(res);
else if (mode == SelectMode::Append) else if (mode == SelectMode::Append)
@ -124,13 +124,12 @@ SelectionList select_next_match(const Buffer& buffer, SelectionList selections,
selections.set_main_index(selections.size() - 1); selections.set_main_index(selections.size() - 1);
} }
selections.sort_and_merge_overlapping(); selections.sort_and_merge_overlapping();
return selections;
} }
SelectionList select_all_matches(const Buffer& buffer, SelectionList selection, void select_all_matches(const Buffer& buffer, SelectionList& selection,
const Regex& regex); const Regex& regex);
SelectionList split_selection(const Buffer& buffer, SelectionList selection, void split_selection(const Buffer& buffer, SelectionList& selection,
const Regex& separator_regex); const Regex& separator_regex);
using CodepointPair = std::pair<Codepoint, Codepoint>; using CodepointPair = std::pair<Codepoint, Codepoint>;