From eb9c95298eced319c93b98689615dd1a61e86247 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 13 Apr 2015 15:21:26 +0100 Subject: [PATCH] Add support for string <-> selection list serialization --- src/commands.cc | 15 +++++++++++++++ src/main.cc | 11 ++--------- src/selection.cc | 40 ++++++++++++++++++++++++++++++++++++++++ src/selection.hh | 5 +++++ 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/commands.cc b/src/commands.cc index 80a8963e..964ae0e1 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -1479,6 +1479,20 @@ const CommandDesc set_register_cmd = { } }; +const CommandDesc select_cmd = { + "select", + nullptr, + "select : 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 = { "cd", nullptr, @@ -1574,6 +1588,7 @@ void register_commands() register_command(face_cmd); register_command(set_client_name_cmd); register_command(set_register_cmd); + register_command(select_cmd); register_command(change_working_directory_cmd); } diff --git a/src/main.cc b/src/main.cc index 9b0066c3..2d7280d2 100644 --- a/src/main.cc +++ b/src/main.cc @@ -123,18 +123,11 @@ void register_env_vars() }, { "selection_desc", [](StringView name, const Context& context) - { auto& sel = context.selections().main(); - auto beg = sel.min(); - return format("{}.{}+{}", beg.line + 1, beg.column + 1, - context.buffer().distance(beg, sel.max())+1); } + { return selection_to_string(context.buffer(), context.selections().main()); } }, { "selections_desc", [](StringView name, const Context& context) - { return join(transformed(context.selections(), [&](const Selection& sel) { - auto beg = sel.min(); - return format("{}.{}+{}", beg.line + 1, beg.column + 1, - context.buffer().distance(beg, sel.max())+1); - }), ':'); } + { return selection_list_to_string(context.selections()); } }, { "window_width", [](StringView name, const Context& context) -> String diff --git a/src/selection.cc b/src/selection.cc index 98c7288e..89bcc5ce 100644 --- a/src/selection.cc +++ b/src/selection.cc @@ -542,4 +542,44 @@ void SelectionList::erase() 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 .+ 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 sels; + for (auto sel_desc : split(desc, ':')) + sels.push_back(selection_from_string(buffer, sel_desc)); + return {buffer, std::move(sels)}; +} + } diff --git a/src/selection.hh b/src/selection.hh index 1bd27510..3001a94b 100644 --- a/src/selection.hh +++ b/src/selection.hh @@ -142,6 +142,11 @@ private: Vector 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