From 0630b4f4f6f006702bbff973309f2487b9fab001 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 14 Feb 2023 22:00:12 +1100 Subject: [PATCH] Fix scroll_window not ensuring cursor lies on a codepoint start Fixes #4839 --- src/input_handler.cc | 12 +++------- .../regression/4839-scroll-invalid-cursor/cmd | 1 + test/regression/4839-scroll-invalid-cursor/in | 23 +++++++++++++++++++ .../4839-scroll-invalid-cursor/script | 2 ++ 4 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 test/regression/4839-scroll-invalid-cursor/cmd create mode 100644 test/regression/4839-scroll-invalid-cursor/in create mode 100644 test/regression/4839-scroll-invalid-cursor/script diff --git a/src/input_handler.cc b/src/input_handler.cc index 664490d6a..2564529ac 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -1820,21 +1820,15 @@ void scroll_window(Context& context, LineCount offset, bool mouse_dragging) SelectionList& selections = context.selections(); Selection& main_selection = selections.main(); const BufferCoord anchor = main_selection.anchor(); - const BufferCoord cursor = main_selection.cursor(); + const BufferCoordAndTarget cursor = main_selection.cursor(); auto cursor_off = mouse_dragging ? win_pos.line - window.position().line : 0; auto line = clamp(cursor.line + cursor_off, win_pos.line + scrolloff.line, win_pos.line + win_dim.line - 1 - scrolloff.line); - line = clamp(line, 0_line, buffer.line_count() - 1); - using std::min; using std::max; - // This is not exactly a clamp, and must be done in this order as - // byte_count_to could return line length - auto col = min(max(cursor.column, buffer[line].byte_count_to(win_pos.column)), - buffer[line].length()-1); - - BufferCoord new_cursor = { line, col }; + const ColumnCount tabstop = context.options()["tabstop"].get(); + auto new_cursor = buffer.offset_coord(cursor, line - cursor.line, tabstop); BufferCoord new_anchor = (mouse_dragging or new_cursor == cursor) ? anchor : new_cursor; window.set_position(win_pos); diff --git a/test/regression/4839-scroll-invalid-cursor/cmd b/test/regression/4839-scroll-invalid-cursor/cmd new file mode 100644 index 000000000..ec0f73a07 --- /dev/null +++ b/test/regression/4839-scroll-invalid-cursor/cmd @@ -0,0 +1 @@ +l diff --git a/test/regression/4839-scroll-invalid-cursor/in b/test/regression/4839-scroll-invalid-cursor/in new file mode 100644 index 000000000..3c2a5cb89 --- /dev/null +++ b/test/regression/4839-scroll-invalid-cursor/in @@ -0,0 +1,23 @@ +ab +😃 +😃 +😃 +😃 +😃 +😃 +😃 +😃 +😃 +😃 +😃 +😃 +😃 +😃 +😃 +😃 +😃 +😃 +😃 +😃 +😃 +😃 diff --git a/test/regression/4839-scroll-invalid-cursor/script b/test/regression/4839-scroll-invalid-cursor/script new file mode 100644 index 000000000..032276294 --- /dev/null +++ b/test/regression/4839-scroll-invalid-cursor/script @@ -0,0 +1,2 @@ +ui_out -ignore 1 +ui_out '{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "black", "bg": "white", "underline": "default", "attributes": [] }, "contents": "😃" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "\u000a" }]], { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }] }'