summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Felice <jason.m.felice@gmail.com>2019-11-12 19:45:48 -0500
committerJason Felice <jason.m.felice@gmail.com>2019-11-12 20:43:14 -0500
commit0f58f014289b12afd2391fb8cc5d99295ab7757d (patch)
treedac28c499a66a8b1fb042f62562c8ead4ff95806 /src
parenta7d3976a1002a80c4e5a17c989921025ded89450 (diff)
Fix display column computations
Closes #3201
Diffstat (limited to 'src')
-rw-r--r--src/buffer_utils.cc5
-rw-r--r--src/buffer_utils.hh4
-rw-r--r--src/commands.cc3
-rw-r--r--src/main.cc4
-rw-r--r--src/selection.cc24
-rw-r--r--src/selection.hh10
6 files changed, 30 insertions, 20 deletions
diff --git a/src/buffer_utils.cc b/src/buffer_utils.cc
index b6519d7d..4b6c3763 100644
--- a/src/buffer_utils.cc
+++ b/src/buffer_utils.cc
@@ -34,6 +34,11 @@ ColumnCount get_column(const Buffer& buffer,
return col;
}
+ColumnCount column_length(const Buffer& buffer, ColumnCount tabstop, LineCount line)
+{
+ return get_column(buffer, tabstop, BufferCoord{line, ByteCount{INT_MAX}});
+}
+
ByteCount get_byte_to_column(const Buffer& buffer, ColumnCount tabstop, DisplayCoord coord)
{
auto line = buffer[coord.line];
diff --git a/src/buffer_utils.hh b/src/buffer_utils.hh
index a635658b..586cbb1d 100644
--- a/src/buffer_utils.hh
+++ b/src/buffer_utils.hh
@@ -69,8 +69,8 @@ inline bool is_eow(const Buffer& buffer, BufferCoord coord)
return is_word(*(it-1)) and not is_word(*it);
}
-ColumnCount get_column(const Buffer& buffer,
- ColumnCount tabstop, BufferCoord coord);
+ColumnCount get_column(const Buffer& buffer, ColumnCount tabstop, BufferCoord coord);
+ColumnCount column_length(const Buffer& buffer, ColumnCount tabstop, LineCount line);
ByteCount get_byte_to_column(const Buffer& buffer, ColumnCount tabstop,
DisplayCoord coord);
diff --git a/src/commands.cc b/src/commands.cc
index cfacea99..27531aec 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -2349,7 +2349,8 @@ const CommandDesc select_cmd = {
column_type = ColumnType::Codepoint;
else if (parser.get_switch("display-column"))
column_type = ColumnType::DisplayColumn;
- context.selections_write_only() = selection_list_from_strings(buffer, column_type, parser.positionals_from(0), timestamp, 0);
+ ColumnCount tabstop = context.options()["tabstop"].get<int>();
+ context.selections_write_only() = selection_list_from_strings(buffer, column_type, parser.positionals_from(0), timestamp, 0, tabstop);
}
};
diff --git a/src/main.cc b/src/main.cc
index fca72b3b..7af8c0cb 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -261,7 +261,9 @@ static const EnvVarDesc builtin_env_vars[] = { {
}, {
"selections_display_column_desc", false,
[](StringView name, const Context& context, Quoting quoting)
- { return selection_list_to_string(ColumnType::DisplayColumn, context.selections()); }
+ { return selection_list_to_string(ColumnType::DisplayColumn,
+ context.selections(),
+ context.options()["tabstop"].get<int>()); }
}, {
"selection_length", false,
[](StringView name, const Context& context, Quoting quoting) -> String
diff --git a/src/selection.cc b/src/selection.cc
index 0b29d3d2..0a0983a5 100644
--- a/src/selection.cc
+++ b/src/selection.cc
@@ -472,7 +472,7 @@ void SelectionList::erase()
m_buffer->check_invariant();
}
-String selection_to_string(ColumnType column_type, const Buffer& buffer, const Selection& selection)
+String selection_to_string(ColumnType column_type, const Buffer& buffer, const Selection& selection, ColumnCount tabstop)
{
const auto& cursor = selection.cursor();
const auto& anchor = selection.anchor();
@@ -487,19 +487,20 @@ String selection_to_string(ColumnType column_type, const Buffer& buffer, const S
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:
+ kak_assert(tabstop != -1);
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);
+ anchor.line + 1, get_column(buffer, tabstop, anchor) + 1,
+ cursor.line + 1, get_column(buffer, tabstop, cursor) + 1);
}
}
-String selection_list_to_string(ColumnType column_type, const SelectionList& selections)
+String selection_list_to_string(ColumnType column_type, const SelectionList& selections, ColumnCount tabstop)
{
auto& buffer = selections.buffer();
kak_assert(selections.timestamp() == buffer.timestamp());
auto to_string = [&](const Selection& selection) {
- return selection_to_string(column_type, buffer, selection);
+ return selection_to_string(column_type, buffer, selection, tabstop);
};
auto beg = &*selections.begin(), end = &*selections.end();
@@ -509,7 +510,7 @@ String selection_list_to_string(ColumnType column_type, const SelectionList& sel
transform(to_string), ' ', false);
}
-Selection selection_from_string(ColumnType column_type, const Buffer& buffer, StringView desc)
+Selection selection_from_string(ColumnType column_type, const Buffer& buffer, StringView desc, ColumnCount tabstop)
{
auto comma = find(desc, ',');
auto dot_anchor = find(StringView{desc.begin(), comma}, '.');
@@ -520,7 +521,7 @@ Selection selection_from_string(ColumnType column_type, const Buffer& buffer, St
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));
+ throw runtime_error(format("coordinate {}.{} does not exist in buffer", line + 1, column + 1));
switch (column_type)
{
@@ -528,12 +529,13 @@ Selection selection_from_string(ColumnType column_type, const Buffer& buffer, St
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));
+ throw runtime_error(format("coordinate {}.{} does not exist in buffer", line + 1, column + 1));
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})};
+ kak_assert(tabstop != -1);
+ if (buffer.line_count() <= line or column_length(buffer, tabstop, line) <= column)
+ throw runtime_error(format("coordinate {}.{} does not exist in buffer", line + 1, column + 1));
+ return {line, get_byte_to_column(buffer, tabstop, DisplayCoord{line, ColumnCount{column}})};
}
};
diff --git a/src/selection.hh b/src/selection.hh
index a674e785..af56856e 100644
--- a/src/selection.hh
+++ b/src/selection.hh
@@ -163,19 +163,19 @@ enum class ColumnType
DisplayColumn
};
-Selection selection_from_string(ColumnType column_type, const Buffer& buffer, StringView desc);
-String selection_to_string(ColumnType column_type, const Buffer& buffer, const Selection& selection);
+Selection selection_from_string(ColumnType column_type, const Buffer& buffer, StringView desc, ColumnCount tabstop = -1);
+String selection_to_string(ColumnType column_type, const Buffer& buffer, const Selection& selection, ColumnCount tabstop = -1);
-String selection_list_to_string(ColumnType column_type, const SelectionList& selections);
+String selection_list_to_string(ColumnType column_type, const SelectionList& selections, ColumnCount tabstop = -1);
template<typename StringArray>
-SelectionList selection_list_from_strings(Buffer& buffer, ColumnType column_type, StringArray&& descs, size_t timestamp, size_t main)
+SelectionList selection_list_from_strings(Buffer& buffer, ColumnType column_type, StringArray&& descs, size_t timestamp, size_t main, ColumnCount tabstop = -1)
{
if ((column_type != ColumnType::Byte and timestamp != buffer.timestamp()) or timestamp > buffer.timestamp())
throw runtime_error{format("invalid timestamp '{}'", timestamp)};
auto from_string = [&](StringView desc) {
- return selection_from_string(column_type, buffer, desc);
+ return selection_from_string(column_type, buffer, desc, tabstop);
};
auto sels = descs | transform(from_string) | gather<Vector<Selection>>();