summaryrefslogtreecommitdiff
path: root/src/selection.cc
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2019-11-12 21:56:45 +1100
committerMaxime Coste <mawww@kakoune.org>2019-11-12 21:56:45 +1100
commite964b68ab818a9c5be1c16f024ba346f3983a3e3 (patch)
tree6213845a6368411ec548bdc7806af62889887292 /src/selection.cc
parent7a8f57f97bbd057c35e0b47f9a4503856d8bd891 (diff)
Add support for selecting and exporting selections in display columns
Fixes #2724
Diffstat (limited to 'src/selection.cc')
-rw-r--r--src/selection.cc76
1 files changed, 37 insertions, 39 deletions
diff --git a/src/selection.cc b/src/selection.cc
index ef5ada64..0b29d3d2 100644
--- a/src/selection.cc
+++ b/src/selection.cc
@@ -472,31 +472,34 @@ void SelectionList::erase()
m_buffer->check_invariant();
}
-String selection_to_string(const Selection& selection)
+String selection_to_string(ColumnType column_type, const Buffer& buffer, const Selection& selection)
{
const auto& cursor = selection.cursor();
const auto& anchor = selection.anchor();
- return format("{}.{},{}.{}", anchor.line + 1, anchor.column + 1,
- cursor.line + 1, cursor.column + 1);
-}
-
-String selection_to_string_char(const Buffer& buffer, const Selection& selection)
-{
- const auto& cursor = selection.cursor();
- const auto& anchor = selection.anchor();
- return format("{}.{},{}.{}",
- anchor.line + 1, buffer[anchor.line].char_count_to(anchor.column) + 1,
- cursor.line + 1, buffer[cursor.line].char_count_to(cursor.column) + 1);
+ switch (column_type)
+ {
+ default:
+ case ColumnType::Byte:
+ return format("{}.{},{}.{}", anchor.line + 1, anchor.column + 1,
+ cursor.line + 1, cursor.column + 1);
+ case ColumnType::Codepoint:
+ return format("{}.{},{}.{}",
+ anchor.line + 1, buffer[anchor.line].char_count_to(anchor.column) + 1,
+ cursor.line + 1, buffer[cursor.line].char_count_to(cursor.column) + 1);
+ case ColumnType::DisplayColumn:
+ return format("{}.{},{}.{}",
+ anchor.line + 1, buffer[anchor.line].column_count_to(anchor.column) + 1,
+ cursor.line + 1, buffer[cursor.line].column_count_to(cursor.column) + 1);
+ }
}
-String selection_list_to_string(bool char_columns, const SelectionList& selections)
+String selection_list_to_string(ColumnType column_type, const SelectionList& selections)
{
auto& buffer = selections.buffer();
kak_assert(selections.timestamp() == buffer.timestamp());
auto to_string = [&](const Selection& selection) {
- return char_columns ? selection_to_string_char(buffer, selection)
- : selection_to_string(selection);
+ return selection_to_string(column_type, buffer, selection);
};
auto beg = &*selections.begin(), end = &*selections.end();
@@ -506,8 +509,7 @@ String selection_list_to_string(bool char_columns, const SelectionList& selectio
transform(to_string), ' ', false);
}
-template<typename ComputeCoord>
-Selection selection_from_string_impl(StringView desc, ComputeCoord compute_coord)
+Selection selection_from_string(ColumnType column_type, const Buffer& buffer, StringView desc)
{
auto comma = find(desc, ',');
auto dot_anchor = find(StringView{desc.begin(), comma}, '.');
@@ -516,6 +518,24 @@ Selection selection_from_string_impl(StringView desc, ComputeCoord compute_coord
if (comma == desc.end() or dot_anchor == comma or dot_cursor == desc.end())
throw runtime_error(format("'{}' does not follow <line>.<column>,<line>.<column> format", desc));
+ auto compute_coord = [&](int line, int column) -> BufferCoord {
+ if (line < 0 or column < 0)
+ throw runtime_error(format("coordinate {}.{} does exist in buffer", line, column));
+
+ switch (column_type)
+ {
+ default:
+ case ColumnType::Byte: return {line, column};
+ case ColumnType::Codepoint:
+ if (buffer.line_count() <= line or buffer[line].char_length() <= column)
+ throw runtime_error(format("coordinate {}.{} does exist in buffer", line, column));
+ return {line, buffer[line].byte_count_to(CharCount{column})};
+ case ColumnType::DisplayColumn:
+ if (buffer.line_count() <= line or buffer[line].column_length() <= column)
+ throw runtime_error(format("coordinate {}.{} does exist in buffer", line, column));
+ return {line, buffer[line].byte_count_to(ColumnCount{column})};
+ }
+ };
auto anchor = compute_coord(str_to_int({desc.begin(), dot_anchor}) - 1,
str_to_int({dot_anchor+1, comma}) - 1);
@@ -523,29 +543,7 @@ Selection selection_from_string_impl(StringView desc, ComputeCoord compute_coord
auto cursor = compute_coord(str_to_int({comma+1, dot_cursor}) - 1,
str_to_int({dot_cursor+1, desc.end()}) - 1);
- if (anchor.line < 0 or anchor.column < 0 or
- cursor.line < 0 or cursor.column < 0)
- throw runtime_error(format("coordinates must be >= 1: '{}'", desc));
-
return Selection{anchor, cursor};
}
-Selection selection_from_string(StringView desc)
-{
- return selection_from_string_impl(desc, [](int line, int column) {
- return BufferCoord{line, column};
- });
-}
-
-Selection selection_from_string_char(const Buffer& buffer, StringView desc)
-{
- return selection_from_string_impl(desc, [&](int line, int column) {
- if (line < 0 or buffer.line_count() <= line or
- column < 0 or buffer[line].char_length() <= column)
- throw runtime_error(format("coordinate {}.{} does exist in buffer", line, column));
-
- return BufferCoord{line, buffer[line].byte_count_to(CharCount{column})};
- });
-}
-
}