Add support for string <-> selection list serialization
This commit is contained in:
parent
731c27c094
commit
eb9c95298e
|
@ -1479,6 +1479,20 @@ const CommandDesc set_register_cmd = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const CommandDesc select_cmd = {
|
||||||
|
"select",
|
||||||
|
nullptr,
|
||||||
|
"select <selections_desc>: select given selections",
|
||||||
|
ParameterDesc{{}, ParameterDesc::Flags::None, 1, 1},
|
||||||
|
CommandFlags::None,
|
||||||
|
CommandHelper{},
|
||||||
|
CommandCompleter{},
|
||||||
|
[](const ParametersParser& parser, Context& context)
|
||||||
|
{
|
||||||
|
context.selections() = selection_list_from_string(context.buffer(), parser[0]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const CommandDesc change_working_directory_cmd = {
|
const CommandDesc change_working_directory_cmd = {
|
||||||
"cd",
|
"cd",
|
||||||
nullptr,
|
nullptr,
|
||||||
|
@ -1574,6 +1588,7 @@ void register_commands()
|
||||||
register_command(face_cmd);
|
register_command(face_cmd);
|
||||||
register_command(set_client_name_cmd);
|
register_command(set_client_name_cmd);
|
||||||
register_command(set_register_cmd);
|
register_command(set_register_cmd);
|
||||||
|
register_command(select_cmd);
|
||||||
register_command(change_working_directory_cmd);
|
register_command(change_working_directory_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
src/main.cc
11
src/main.cc
|
@ -123,18 +123,11 @@ void register_env_vars()
|
||||||
}, {
|
}, {
|
||||||
"selection_desc",
|
"selection_desc",
|
||||||
[](StringView name, const Context& context)
|
[](StringView name, const Context& context)
|
||||||
{ auto& sel = context.selections().main();
|
{ return selection_to_string(context.buffer(), context.selections().main()); }
|
||||||
auto beg = sel.min();
|
|
||||||
return format("{}.{}+{}", beg.line + 1, beg.column + 1,
|
|
||||||
context.buffer().distance(beg, sel.max())+1); }
|
|
||||||
}, {
|
}, {
|
||||||
"selections_desc",
|
"selections_desc",
|
||||||
[](StringView name, const Context& context)
|
[](StringView name, const Context& context)
|
||||||
{ return join(transformed(context.selections(), [&](const Selection& sel) {
|
{ return selection_list_to_string(context.selections()); }
|
||||||
auto beg = sel.min();
|
|
||||||
return format("{}.{}+{}", beg.line + 1, beg.column + 1,
|
|
||||||
context.buffer().distance(beg, sel.max())+1);
|
|
||||||
}), ':'); }
|
|
||||||
}, {
|
}, {
|
||||||
"window_width",
|
"window_width",
|
||||||
[](StringView name, const Context& context) -> String
|
[](StringView name, const Context& context) -> String
|
||||||
|
|
|
@ -542,4 +542,44 @@ void SelectionList::erase()
|
||||||
m_buffer->check_invariant();
|
m_buffer->check_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String selection_to_string(const Buffer& buffer, const Selection& selection)
|
||||||
|
{
|
||||||
|
auto& cursor = selection.cursor();
|
||||||
|
auto& anchor = selection.anchor();
|
||||||
|
ByteCount distance = buffer.distance(anchor, cursor);
|
||||||
|
return format("{}.{}{}{}", anchor.line + 1, anchor.column + 1,
|
||||||
|
distance < 0 ? '-' : '+', abs(distance));
|
||||||
|
}
|
||||||
|
|
||||||
|
String selection_list_to_string(const SelectionList& selections)
|
||||||
|
{
|
||||||
|
const auto& buffer = selections.buffer();
|
||||||
|
return join(transformed(selections, [&buffer](const Selection& s)
|
||||||
|
{ return selection_to_string(buffer, s); }),
|
||||||
|
':', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Selection selection_from_string(const Buffer& buffer, StringView desc)
|
||||||
|
{
|
||||||
|
auto dot = find(desc, '.');
|
||||||
|
auto sign = std::find_if(dot, desc.end(), [](char c) { return c == '+' or c == '-'; });
|
||||||
|
|
||||||
|
if (dot == desc.end() or sign == desc.end())
|
||||||
|
throw runtime_error(format("'{}' does not follow <line>.<column>+<len> format", desc));
|
||||||
|
|
||||||
|
LineCount line = str_to_int({desc.begin(), dot}) - 1;
|
||||||
|
ByteCount column = str_to_int({dot+1, sign}) - 1;
|
||||||
|
ByteCoord anchor{line, column};
|
||||||
|
ByteCount count = (*sign == '+' ? 1 : -1) * str_to_int({sign+1, desc.end()});
|
||||||
|
return Selection{anchor, buffer.advance(anchor, count)};
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectionList selection_list_from_string(Buffer& buffer, StringView desc)
|
||||||
|
{
|
||||||
|
Vector<Selection> sels;
|
||||||
|
for (auto sel_desc : split(desc, ':'))
|
||||||
|
sels.push_back(selection_from_string(buffer, sel_desc));
|
||||||
|
return {buffer, std::move(sels)};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,6 +142,11 @@ private:
|
||||||
|
|
||||||
Vector<Selection> compute_modified_ranges(Buffer& buffer, size_t timestamp);
|
Vector<Selection> compute_modified_ranges(Buffer& buffer, size_t timestamp);
|
||||||
|
|
||||||
|
String selection_to_string(const Buffer& buffer, const Selection& selection);
|
||||||
|
String selection_list_to_string(const SelectionList& selection);
|
||||||
|
Selection selection_from_string(const Buffer& buffer, StringView desc);
|
||||||
|
SelectionList selection_list_from_string(Buffer& buffer, StringView desc);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // selection_hh_INCLUDED
|
#endif // selection_hh_INCLUDED
|
||||||
|
|
Loading…
Reference in New Issue
Block a user