Merge remote-tracking branch 'eraserhd/display-column-fixes'
This commit is contained in:
commit
7afced07d0
|
@ -34,6 +34,11 @@ ColumnCount get_column(const Buffer& buffer,
|
||||||
return col;
|
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)
|
ByteCount get_byte_to_column(const Buffer& buffer, ColumnCount tabstop, DisplayCoord coord)
|
||||||
{
|
{
|
||||||
auto line = buffer[coord.line];
|
auto line = buffer[coord.line];
|
||||||
|
|
|
@ -69,8 +69,8 @@ inline bool is_eow(const Buffer& buffer, BufferCoord coord)
|
||||||
return is_word(*(it-1)) and not is_word(*it);
|
return is_word(*(it-1)) and not is_word(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnCount get_column(const Buffer& buffer,
|
ColumnCount get_column(const Buffer& buffer, ColumnCount tabstop, BufferCoord coord);
|
||||||
ColumnCount tabstop, BufferCoord coord);
|
ColumnCount column_length(const Buffer& buffer, ColumnCount tabstop, LineCount line);
|
||||||
|
|
||||||
ByteCount get_byte_to_column(const Buffer& buffer, ColumnCount tabstop,
|
ByteCount get_byte_to_column(const Buffer& buffer, ColumnCount tabstop,
|
||||||
DisplayCoord coord);
|
DisplayCoord coord);
|
||||||
|
|
|
@ -2349,7 +2349,8 @@ const CommandDesc select_cmd = {
|
||||||
column_type = ColumnType::Codepoint;
|
column_type = ColumnType::Codepoint;
|
||||||
else if (parser.get_switch("display-column"))
|
else if (parser.get_switch("display-column"))
|
||||||
column_type = ColumnType::DisplayColumn;
|
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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -261,7 +261,9 @@ static const EnvVarDesc builtin_env_vars[] = { {
|
||||||
}, {
|
}, {
|
||||||
"selections_display_column_desc", false,
|
"selections_display_column_desc", false,
|
||||||
[](StringView name, const Context& context, Quoting quoting)
|
[](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,
|
"selection_length", false,
|
||||||
[](StringView name, const Context& context, Quoting quoting) -> String
|
[](StringView name, const Context& context, Quoting quoting) -> String
|
||||||
|
|
|
@ -472,7 +472,7 @@ void SelectionList::erase()
|
||||||
m_buffer->check_invariant();
|
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& cursor = selection.cursor();
|
||||||
const auto& anchor = selection.anchor();
|
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,
|
anchor.line + 1, buffer[anchor.line].char_count_to(anchor.column) + 1,
|
||||||
cursor.line + 1, buffer[cursor.line].char_count_to(cursor.column) + 1);
|
cursor.line + 1, buffer[cursor.line].char_count_to(cursor.column) + 1);
|
||||||
case ColumnType::DisplayColumn:
|
case ColumnType::DisplayColumn:
|
||||||
|
kak_assert(tabstop != -1);
|
||||||
return format("{}.{},{}.{}",
|
return format("{}.{},{}.{}",
|
||||||
anchor.line + 1, buffer[anchor.line].column_count_to(anchor.column) + 1,
|
anchor.line + 1, get_column(buffer, tabstop, anchor) + 1,
|
||||||
cursor.line + 1, buffer[cursor.line].column_count_to(cursor.column) + 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();
|
auto& buffer = selections.buffer();
|
||||||
kak_assert(selections.timestamp() == buffer.timestamp());
|
kak_assert(selections.timestamp() == buffer.timestamp());
|
||||||
|
|
||||||
auto to_string = [&](const Selection& selection) {
|
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();
|
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);
|
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 comma = find(desc, ',');
|
||||||
auto dot_anchor = find(StringView{desc.begin(), comma}, '.');
|
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 {
|
auto compute_coord = [&](int line, int column) -> BufferCoord {
|
||||||
if (line < 0 or column < 0)
|
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)
|
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::Byte: return {line, column};
|
||||||
case ColumnType::Codepoint:
|
case ColumnType::Codepoint:
|
||||||
if (buffer.line_count() <= line or buffer[line].char_length() <= column)
|
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})};
|
return {line, buffer[line].byte_count_to(CharCount{column})};
|
||||||
case ColumnType::DisplayColumn:
|
case ColumnType::DisplayColumn:
|
||||||
if (buffer.line_count() <= line or buffer[line].column_length() <= column)
|
kak_assert(tabstop != -1);
|
||||||
throw runtime_error(format("coordinate {}.{} does exist in buffer", line, column));
|
if (buffer.line_count() <= line or column_length(buffer, tabstop, line) <= column)
|
||||||
return {line, buffer[line].byte_count_to(ColumnCount{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}})};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -163,19 +163,19 @@ enum class ColumnType
|
||||||
DisplayColumn
|
DisplayColumn
|
||||||
};
|
};
|
||||||
|
|
||||||
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 = -1);
|
||||||
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 = -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>
|
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())
|
if ((column_type != ColumnType::Byte and timestamp != buffer.timestamp()) or timestamp > buffer.timestamp())
|
||||||
throw runtime_error{format("invalid timestamp '{}'", timestamp)};
|
throw runtime_error{format("invalid timestamp '{}'", timestamp)};
|
||||||
|
|
||||||
auto from_string = [&](StringView desc) {
|
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>>();
|
auto sels = descs | transform(from_string) | gather<Vector<Selection>>();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user