Support discarding selections in exec/eval -itersel
Only fail if all selections are discarded. Fixes #2841
This commit is contained in:
parent
3114995857
commit
91386a535c
|
@ -1782,26 +1782,38 @@ void context_wrap(const ParametersParser& parser, Context& context, StringView d
|
||||||
Vector<Selection> new_sels;
|
Vector<Selection> new_sels;
|
||||||
size_t main = 0;
|
size_t main = 0;
|
||||||
size_t timestamp = c.buffer().timestamp();
|
size_t timestamp = c.buffer().timestamp();
|
||||||
|
bool one_selection_succeeded = false;
|
||||||
for (auto& sel : sels)
|
for (auto& sel : sels)
|
||||||
{
|
{
|
||||||
c.selections_write_only() = SelectionList{sels.buffer(), sel, sels.timestamp()};
|
c.selections_write_only() = SelectionList{sels.buffer(), sel, sels.timestamp()};
|
||||||
c.selections().update();
|
c.selections().update();
|
||||||
|
|
||||||
func(parser, c);
|
try
|
||||||
|
|
||||||
if (not draft)
|
|
||||||
{
|
{
|
||||||
|
func(parser, c);
|
||||||
|
one_selection_succeeded = true;
|
||||||
|
|
||||||
if (&sels.buffer() != &c.buffer())
|
if (&sels.buffer() != &c.buffer())
|
||||||
throw runtime_error("buffer has changed while iterating on selections");
|
throw runtime_error("buffer has changed while iterating on selections");
|
||||||
|
|
||||||
update_selections(new_sels, main, c.buffer(), timestamp);
|
if (not draft)
|
||||||
timestamp = c.buffer().timestamp();
|
{
|
||||||
if (&sel == &sels.main())
|
update_selections(new_sels, main, c.buffer(), timestamp);
|
||||||
main = new_sels.size() + c.selections().main_index();
|
timestamp = c.buffer().timestamp();
|
||||||
|
if (&sel == &sels.main())
|
||||||
|
main = new_sels.size() + c.selections().main_index();
|
||||||
|
|
||||||
const auto middle = new_sels.insert(new_sels.end(), c.selections().begin(), c.selections().end());
|
const auto middle = new_sels.insert(new_sels.end(), c.selections().begin(), c.selections().end());
|
||||||
std::inplace_merge(new_sels.begin(), middle, new_sels.end(), compare_selections);
|
std::inplace_merge(new_sels.begin(), middle, new_sels.end(), compare_selections);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
catch (no_selections_remaining&) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not one_selection_succeeded)
|
||||||
|
{
|
||||||
|
c.selections_write_only() = std::move(sels);
|
||||||
|
throw no_selections_remaining{};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not draft)
|
if (not draft)
|
||||||
|
|
|
@ -113,7 +113,7 @@ void select(Context& context, T func)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to_remove.size() == selections.size())
|
if (to_remove.size() == selections.size())
|
||||||
throw runtime_error{"no selections remaining"};
|
throw no_selections_remaining{};
|
||||||
for (auto& i : to_remove | reverse())
|
for (auto& i : to_remove | reverse())
|
||||||
selections.remove(i);
|
selections.remove(i);
|
||||||
}
|
}
|
||||||
|
@ -1135,7 +1135,7 @@ void keep(Context& context, NormalParams params)
|
||||||
keep.push_back(sel);
|
keep.push_back(sel);
|
||||||
}
|
}
|
||||||
if (keep.empty())
|
if (keep.empty())
|
||||||
throw runtime_error("no selections remaining");
|
throw no_selections_remaining{};
|
||||||
context.selections_write_only() = std::move(keep);
|
context.selections_write_only() = std::move(keep);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1168,7 +1168,7 @@ void keep_pipe(Context& context, NormalParams)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (keep.empty())
|
if (keep.empty())
|
||||||
throw runtime_error("no selections remaining");
|
throw no_selections_remaining{};
|
||||||
if (new_main == -1)
|
if (new_main == -1)
|
||||||
new_main = keep.size() - 1;
|
new_main = keep.size() - 1;
|
||||||
context.selections_write_only().set(std::move(keep), new_main);
|
context.selections_write_only().set(std::move(keep), new_main);
|
||||||
|
@ -1775,7 +1775,7 @@ void trim_selections(Context& context, NormalParams)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to_remove.size() == selections.size())
|
if (to_remove.size() == selections.size())
|
||||||
throw runtime_error{"no selections remaining"};
|
throw no_selections_remaining{};
|
||||||
for (auto& i : to_remove | reverse())
|
for (auto& i : to_remove | reverse())
|
||||||
selections.remove(i);
|
selections.remove(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,18 @@
|
||||||
#include "keys.hh"
|
#include "keys.hh"
|
||||||
#include "keymap_manager.hh"
|
#include "keymap_manager.hh"
|
||||||
#include "string.hh"
|
#include "string.hh"
|
||||||
|
#include "exception.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
class Context;
|
class Context;
|
||||||
|
|
||||||
|
struct no_selections_remaining : runtime_error
|
||||||
|
{
|
||||||
|
no_selections_remaining() : runtime_error("no selections remaining") {}
|
||||||
|
};
|
||||||
|
|
||||||
struct NormalParams
|
struct NormalParams
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
|
|
1
test/compose/discard-selections-with-itersel/cmd
Normal file
1
test/compose/discard-selections-with-itersel/cmd
Normal file
|
@ -0,0 +1 @@
|
||||||
|
:exec -itersel <lt>a-k>ba<lt>ret><ret>d
|
3
test/compose/discard-selections-with-itersel/in
Normal file
3
test/compose/discard-selections-with-itersel/in
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
%(foo)
|
||||||
|
%(bar)
|
||||||
|
%(baz)
|
3
test/compose/discard-selections-with-itersel/out
Normal file
3
test/compose/discard-selections-with-itersel/out
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
foo
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user