diff --git a/docs/changelog.rst b/docs/changelog.rst index 763dd71d8..f2ed37cda 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -101,6 +101,8 @@ Detailed list of changes - A new option :opt:`clear_selection_on_clipboard_loss` to clear selections when they no longer reflect the contents of the clipboard +- Fix a regression in the previous release that caused empty lines to be skipped when copying text from a selection (:iss:`8435`) + - Fix flickering of hyperlink underline when client program continuously redraws on mouse movement (:iss:`8414`) diff --git a/kitty/screen.c b/kitty/screen.c index 4182e8c8f..3c2a1bc8b 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -3580,7 +3580,8 @@ text_for_range(Screen *self, const Selection *sel, bool insert_newlines, bool st const bool is_first_line = y == min_y, is_last_line = y + 1 >= y_limit; const bool add_trailing_newline = insert_newlines && !is_last_line; PyObject *text = NULL; - if (x_limit <= x_start && is_only_whitespace_line) { // we want a newline on only whitespace lines even if they are continued + if (x_limit <= x_start && (is_only_whitespace_line || line_is_empty(line))) { + // we want a newline on only whitespace lines even if they are continued text = add_trailing_newline ? nl : empty; text = Py_NewRef(text); } else { @@ -3627,7 +3628,8 @@ ansi_for_range(Screen *self, const Selection *sel, bool insert_newlines, bool st } } - if (x_limit <= x_start && is_only_whitespace_line) { // we want a newline on only whitespace lines even if they are continued + if (x_limit <= x_start && (is_only_whitespace_line || line_is_empty(line))) { + // we want a newline on only whitespace lines even if they are continued if (insert_newlines) need_newline = true; } else { char_type prefix_char = need_newline ? '\n' : 0; diff --git a/kitty_tests/mouse.py b/kitty_tests/mouse.py index 468aa1286..a2a9e6d33 100644 --- a/kitty_tests/mouse.py +++ b/kitty_tests/mouse.py @@ -79,8 +79,9 @@ class TestMouse(BaseTest): def move(x=0, y=0, button=-1, q=None): ev(x=x, y=y, button=button) if q is not None: - s = sel() - self.ae(s, q, f'{s!r} != {q!r} after movement to x={x} y={y}') + sl = sel() + from kitty.window import as_text + self.ae(sl, q, f'{sl!r} != {q!r} after movement to x={x} y={y}. Screen contents: {as_text(s)!r}') def multi_click(x=0, y=0, count=2): clear_click_queue = True @@ -277,3 +278,12 @@ class TestMouse(BaseTest): move(x=3.6, y=2, q='abcd') press(x=3, y=0, button=GLFW_MOUSE_BUTTON_RIGHT) self.ae(sel(), '4567890abcd') + + # blank line select + s.reset() + s.draw('abcde') + s.linefeed(), s.carriage_return() + s.linefeed(), s.carriage_return() + s.draw('12345') + press(x=0, y=0) + move(x=2, y=2, q='abcde\n\n12')