Respect columns when copying selection, not just bytes
This commit is contained in:
parent
46f37a6050
commit
00bde4ef48
|
@ -26,6 +26,26 @@ CharCount get_column(const Buffer& buffer,
|
||||||
return col;
|
return col;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ByteCount get_byte_to_column(const Buffer& buffer, CharCount tabstop, CharCoord coord)
|
||||||
|
{
|
||||||
|
auto line = buffer[coord.line];
|
||||||
|
auto col = 0_char;
|
||||||
|
auto it = line.begin();
|
||||||
|
while (it != line.end() and coord.column > col)
|
||||||
|
{
|
||||||
|
if (*it == '\t')
|
||||||
|
{
|
||||||
|
col = (col / tabstop + 1) * tabstop;
|
||||||
|
if (col > coord.column) // the target column was in the tab
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++col;
|
||||||
|
it = utf8::next(it, line.end());
|
||||||
|
}
|
||||||
|
return (int)(it - line.begin());
|
||||||
|
}
|
||||||
|
|
||||||
Buffer* create_buffer_from_data(StringView data, StringView name,
|
Buffer* create_buffer_from_data(StringView data, StringView name,
|
||||||
Buffer::Flags flags, time_t fs_timestamp)
|
Buffer::Flags flags, time_t fs_timestamp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,6 +27,9 @@ inline CharCount char_length(const Buffer& buffer, const Selection& range)
|
||||||
CharCount get_column(const Buffer& buffer,
|
CharCount get_column(const Buffer& buffer,
|
||||||
CharCount tabstop, ByteCoord coord);
|
CharCount tabstop, ByteCoord coord);
|
||||||
|
|
||||||
|
ByteCount get_byte_to_column(const Buffer& buffer, CharCount tabstop,
|
||||||
|
CharCoord coord);
|
||||||
|
|
||||||
Buffer* create_fifo_buffer(String name, int fd, bool scroll = false);
|
Buffer* create_fifo_buffer(String name, int fd, bool scroll = false);
|
||||||
|
|
||||||
Buffer* create_buffer_from_data(StringView data, StringView name,
|
Buffer* create_buffer_from_data(StringView data, StringView name,
|
||||||
|
|
|
@ -976,20 +976,32 @@ void copy_selections_on_next_lines(Context& context, NormalParams params)
|
||||||
{
|
{
|
||||||
auto& selections = context.selections();
|
auto& selections = context.selections();
|
||||||
auto& buffer = context.buffer();
|
auto& buffer = context.buffer();
|
||||||
|
const CharCount tabstop = context.options()["tabstop"].get<int>();
|
||||||
Vector<Selection> result;
|
Vector<Selection> result;
|
||||||
for (auto& sel : selections)
|
for (auto& sel : selections)
|
||||||
{
|
{
|
||||||
auto anchor = sel.anchor();
|
auto anchor = sel.anchor();
|
||||||
auto cursor = sel.cursor();
|
auto cursor = sel.cursor();
|
||||||
|
CharCount cursor_col = get_column(buffer, tabstop, cursor);
|
||||||
|
CharCount anchor_col = get_column(buffer, tabstop, anchor);
|
||||||
result.push_back(std::move(sel));
|
result.push_back(std::move(sel));
|
||||||
for (int i = 0; i < std::max(params.count, 1); ++i)
|
for (int i = 0; i < std::max(params.count, 1); ++i)
|
||||||
{
|
{
|
||||||
LineCount offset = (direction == Forward ? 1 : -1) * (i + 1);
|
LineCount offset = (direction == Forward ? 1 : -1) * (i + 1);
|
||||||
ByteCoord new_anchor{anchor.line + offset, anchor.column};
|
|
||||||
ByteCoordAndTarget new_cursor{cursor.line + offset, cursor.column, cursor.target};
|
const LineCount anchor_line = anchor.line + offset;
|
||||||
if (buffer.is_valid(new_anchor) and not buffer.is_end(new_anchor) and
|
const LineCount cursor_line = cursor.line + offset;
|
||||||
buffer.is_valid(new_cursor) and not buffer.is_end(new_cursor))
|
|
||||||
result.emplace_back(new_anchor, new_cursor);
|
if (anchor_line >= buffer.line_count() or cursor_line >= buffer.line_count())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ByteCount anchor_byte = get_byte_to_column(buffer, tabstop, {anchor_line, anchor_col});
|
||||||
|
ByteCount cursor_byte = get_byte_to_column(buffer, tabstop, {cursor_line, cursor_col});
|
||||||
|
|
||||||
|
if (anchor_byte != buffer[anchor_line].length() and
|
||||||
|
cursor_byte != buffer[cursor_line].length())
|
||||||
|
result.emplace_back(ByteCoord{anchor_line, anchor_byte},
|
||||||
|
ByteCoordAndTarget{cursor_line, cursor_byte, cursor.target});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
selections = std::move(result);
|
selections = std::move(result);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user