diff --git a/src/selection.cc b/src/selection.cc index e0dbbecb36..f0b5b559cf 100644 --- a/src/selection.cc +++ b/src/selection.cc @@ -489,26 +489,41 @@ String selection_list_to_string(const SelectionList& selections) transform(selection_to_string), ' ', false); } -Selection selection_from_string(StringView desc) +static BufferCoord buffer_coord_from_string(const Buffer& buffer, StringView desc, size_t timestamp) { - auto comma = find(desc, ','); - auto dot_anchor = find(StringView{desc.begin(), comma}, '.'); - auto dot_cursor = find(StringView{comma, desc.end()}, '.'); - - if (comma == desc.end() or dot_anchor == comma or dot_cursor == desc.end()) - throw runtime_error(format("'{}' does not follow .,. format", desc)); - - BufferCoord anchor{str_to_int({desc.begin(), dot_anchor}) - 1, - str_to_int({dot_anchor+1, comma}) - 1}; + auto dot = find(desc, '.'); + if (dot == desc.end()) + throw runtime_error(format("'{}' does not follow .[bc] format", desc)); - BufferCoord cursor{str_to_int({comma+1, dot_cursor}) - 1, - str_to_int({dot_cursor+1, desc.end()}) - 1}; + auto is_suffix = [](char ch) { + return ch == 'b' || ch == 'c'; + }; + auto suffix = std::find_if(dot+1, desc.end(), is_suffix); + if (suffix != desc.end() and suffix+1 != desc.end()) + throw runtime_error(format("'{}' does not follow .[bc] format", desc)); - if (anchor.line < 0 or anchor.column < 0 or - cursor.line < 0 or cursor.column < 0) + const int line = str_to_int({desc.begin(), dot}) - 1; + const int column = str_to_int({dot+1, suffix}) - 1; + if (line < 0 or column < 0) throw runtime_error(format("coordinates must be >= 1: '{}'", desc)); - return Selection{anchor, cursor}; + if (suffix == desc.end() or *suffix == 'b') + return BufferCoord{line, column}; + else + { + if (timestamp != buffer.timestamp()) + throw runtime_error("codepoint columns are only allowed on latest timestamp"); + return BufferCoord{line, buffer[line].byte_count_to(CharCount{column})}; + } +} + +Selection selection_from_string(const Buffer& buffer, StringView desc, size_t timestamp) +{ + auto comma = find(desc, ','); + if (comma == desc.end()) + throw runtime_error(format("'{}' does not follow .[bc],.[bc] format", desc)); + return {buffer_coord_from_string(buffer, {desc.begin(), comma}, timestamp), + buffer_coord_from_string(buffer, {comma+1, desc.end()}, timestamp)}; } } diff --git a/src/selection.hh b/src/selection.hh index 34532f9b5f..101bbb2ddc 100644 --- a/src/selection.hh +++ b/src/selection.hh @@ -159,7 +159,7 @@ Vector compute_modified_ranges(Buffer& buffer, size_t timestamp); String selection_to_string(const Selection& selection); String selection_list_to_string(const SelectionList& selection); -Selection selection_from_string(StringView desc); +Selection selection_from_string(const Buffer& buffer, StringView desc, size_t timestamp); template SelectionList selection_list_from_strings(Buffer& buffer, StringArray&& descs, size_t timestamp, size_t main) @@ -167,7 +167,10 @@ SelectionList selection_list_from_strings(Buffer& buffer, StringArray&& descs, s if (timestamp > buffer.timestamp()) throw runtime_error{format("invalid timestamp '{}'", timestamp)}; - auto sels = descs | transform(selection_from_string) | gather>(); + auto parse_selection = [&buffer, timestamp](StringView desc) { + return selection_from_string(buffer, desc, timestamp); + }; + auto sels = descs | transform(parse_selection) | gather>(); if (sels.empty()) throw runtime_error{"empty selection description"}; if (main >= sels.size()) diff --git a/test/compose/select-codepoints/cmd b/test/compose/select-codepoints/cmd new file mode 100644 index 0000000000..08f144d90d --- /dev/null +++ b/test/compose/select-codepoints/cmd @@ -0,0 +1 @@ +:select 1.1c,1.2c 1.4c,1.5c 1.7c,1.7c 2.9c,2.7c 3.2c,3.5c 3.10c,3.11c 4.2c,4.3c 5.3c,5.3c diff --git a/test/compose/select-codepoints/in b/test/compose/select-codepoints/in new file mode 100644 index 0000000000..07ff7b32f3 --- /dev/null +++ b/test/compose/select-codepoints/in @@ -0,0 +1,5 @@ +lx λx.λy.y x +∃e∈C. ∀x∈C. x⊗e=e⊗x=x + λx.λy.y x̦x +-y̦͂- +-o̦͂- diff --git a/test/compose/select-codepoints/kak_quoted_selections b/test/compose/select-codepoints/kak_quoted_selections new file mode 100644 index 0000000000..96fe7aad01 --- /dev/null +++ b/test/compose/select-codepoints/kak_quoted_selections @@ -0,0 +1 @@ +'lx' 'λx' 'λ' '∀x∈' 'λx.λ' 'x̦' 'y̦' '̦'