diff --git a/src/buffer.cc b/src/buffer.cc index e5527693..1b5e1b1c 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -177,19 +177,19 @@ BufferCoord Buffer::clamp(BufferCoord coord) const return coord; } -BufferCoord Buffer::offset_coord(BufferCoord coord, CharCount offset, ColumnCount) +BufferCoord Buffer::offset_coord(BufferCoord coord, CharCount offset, ColumnCount, bool) { StringView line = m_lines[coord.line]; auto target = utf8::advance(&line[coord.column], offset < 0 ? line.begin() : line.end()-1, offset); return {coord.line, (int)(target - line.begin())}; } -BufferCoordAndTarget Buffer::offset_coord(BufferCoordAndTarget coord, LineCount offset, ColumnCount tabstop) +BufferCoordAndTarget Buffer::offset_coord(BufferCoordAndTarget coord, LineCount offset, ColumnCount tabstop, bool avoid_eol) { const auto column = coord.target == -1 ? get_column(*this, tabstop, coord) : coord.target; const auto line = Kakoune::clamp(coord.line + offset, 0_line, line_count()-1); const auto max_column = get_column(*this, tabstop, {line, m_lines[line].length()-1}); - const auto final_column = std::max(0_col, std::min(column, max_column - 1)); + const auto final_column = std::max(0_col, std::min(column, max_column - (avoid_eol ? 1 : 0))); return {line, get_byte_to_column(*this, tabstop, {line, final_column}), column}; } diff --git a/src/buffer.hh b/src/buffer.hh index cb71f8a1..64911a14 100644 --- a/src/buffer.hh +++ b/src/buffer.hh @@ -179,8 +179,8 @@ public: // returns nearest valid coordinates from given ones BufferCoord clamp(BufferCoord coord) const; - BufferCoord offset_coord(BufferCoord coord, CharCount offset, ColumnCount tabstop); - BufferCoordAndTarget offset_coord(BufferCoordAndTarget coord, LineCount offset, ColumnCount tabstop); + BufferCoord offset_coord(BufferCoord coord, CharCount offset, ColumnCount, bool); + BufferCoordAndTarget offset_coord(BufferCoordAndTarget coord, LineCount offset, ColumnCount tabstop, bool avoid_eol); const String& name() const { return m_name; } const String& display_name() const { return m_display_name; } diff --git a/src/input_handler.cc b/src/input_handler.cc index cdc928e9..f57f0029 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -1240,7 +1240,7 @@ private: const ColumnCount tabstop = context().options()["tabstop"].get(); for (auto& sel : selections) { - auto cursor = context().buffer().offset_coord(sel.cursor(), offset, tabstop); + auto cursor = context().buffer().offset_coord(sel.cursor(), offset, tabstop, false); sel.anchor() = sel.cursor() = cursor; } selections.sort_and_merge_overlapping(); diff --git a/src/normal.cc b/src/normal.cc index f8a6abf9..119d11d7 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -1741,7 +1741,7 @@ void move(Context& context, NormalParams params) auto& selections = context.selections(); for (auto& sel : selections) { - auto cursor = context.buffer().offset_coord(sel.cursor(), offset, tabstop); + auto cursor = context.buffer().offset_coord(sel.cursor(), offset, tabstop, true); sel.anchor() = mode == SelectMode::Extend ? sel.anchor() : cursor; sel.cursor() = cursor; }