mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-05-13 16:37:27 +00:00
Fix triple-click line selection not extending wrapped lines beyond viewport bottom
Similar to commit 625e984 which fixed extending into scrollback (above viewport),
this fix extends line selection below the viewport when a wrapped line continues
past the bottom edge. Adds continue_line_downwards_offscreen() and applies it
in both the initial selection and extending selection code paths.
Agent-Logs-Url: https://github.com/kovidgoyal/kitty/sessions/e548ce84-fdb7-4fd1-b3df-e1166b45f5bd
Co-authored-by: kovidgoyal <1308621+kovidgoyal@users.noreply.github.com>
This commit is contained in:
parent
114cd5cbc4
commit
82bf8923cc
3 changed files with 60 additions and 0 deletions
|
|
@ -217,6 +217,8 @@ Detailed list of changes
|
|||
|
||||
- Fix dragging of splits layout borders sometimes moving in the wrong direction or having no effect (:pull:`9447`)
|
||||
|
||||
- Fix triple-click line selection not extending wrapped lines beyond the bottom edge of the viewport
|
||||
|
||||
- Password input in kittens: hide the cursor and display a blinking 🔒 at the end of typed characters to make it visually clear the user is entering a password
|
||||
|
||||
- edit-in-kitty: Ignore environment variables as some editors execute code present in env vars
|
||||
|
|
|
|||
|
|
@ -5395,6 +5395,17 @@ continue_line_downwards(Screen *self, index_type bottom_line, SelectionBoundary
|
|||
return bottom_line;
|
||||
}
|
||||
|
||||
static index_type
|
||||
continue_line_downwards_offscreen(Screen *self, int bottom_line, SelectionBoundary *start, SelectionBoundary *end) {
|
||||
index_type num_offscreen = 0;
|
||||
Line *line = NULL;
|
||||
while ((line = checked_range_line(self, bottom_line + 1)) && range_line_is_continued(self, bottom_line + 1)) {
|
||||
screen_selection_range_for_line_(line, &start->x, &end->x);
|
||||
bottom_line++; num_offscreen++;
|
||||
}
|
||||
return num_offscreen;
|
||||
}
|
||||
|
||||
static int
|
||||
clamp_selection_input_to_multicell(Screen *self, const Selection *s, index_type x, index_type y, bool in_left_half_of_cell) {
|
||||
int delta = 0;
|
||||
|
|
@ -5538,6 +5549,16 @@ do_update_selection(Screen *self, Selection *s, index_type x, index_type y, bool
|
|||
s->start.x = up_start.x;
|
||||
}
|
||||
}
|
||||
// extend below viewport if needed
|
||||
if (bottom_line >= self->lines - 1 && self->scrolled_by > 0 && self->linebuf == self->main_linebuf) {
|
||||
int range_bottom = (int)bottom_line - (int)self->scrolled_by;
|
||||
index_type num_below_viewport = continue_line_downwards_offscreen(
|
||||
self, range_bottom, &down_start, &down_end);
|
||||
if (num_below_viewport) {
|
||||
s->end_scrolled_by -= num_below_viewport;
|
||||
s->end.x = down_end.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef S
|
||||
|
|
@ -5562,6 +5583,16 @@ do_update_selection(Screen *self, Selection *s, index_type x, index_type y, bool
|
|||
}
|
||||
} else {
|
||||
a->in_left_half_of_cell = false; a->x = down_end.x; a->y = bottom_line;
|
||||
// extend below viewport if needed
|
||||
if (bottom_line >= self->lines - 1 && self->scrolled_by > 0 && self->linebuf == self->main_linebuf) {
|
||||
int range_bottom = (int)bottom_line - (int)self->scrolled_by;
|
||||
index_type num_below_viewport = continue_line_downwards_offscreen(
|
||||
self, range_bottom, &down_start, &down_end);
|
||||
if (num_below_viewport) {
|
||||
s->end_scrolled_by -= num_below_viewport;
|
||||
s->end.x = down_end.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
// allow selecting whitespace at the start of the top line
|
||||
if (a->y == top_line && s->input_current.y == top_line && s->input_current.x < a->x && adjusted_boundary_is_before) a->x = s->input_current.x;
|
||||
|
|
|
|||
|
|
@ -255,6 +255,33 @@ class TestMouse(BaseTest):
|
|||
release(x=2, button=GLFW_MOUSE_BUTTON_RIGHT)
|
||||
self.ae(sel(), 'ABCDE12345\n678')
|
||||
|
||||
# line select for wrapped lines below viewport
|
||||
s.reset()
|
||||
s.scroll(100, False)
|
||||
# draw enough content to enable scrolling: fill lines-1 visual lines, then draw a long wrapped line
|
||||
s.draw(('X' * s.columns) * (s.lines - 1))
|
||||
s.linefeed(), s.carriage_return()
|
||||
s.draw('ABCDE12345') # wraps to 2 visual lines, second one pushed below viewport
|
||||
# scroll up by 1 so top visual line of the wrapped text is visible but bottom wraps off-screen
|
||||
s.scroll(1, True)
|
||||
multi_click(x=1, y=s.lines - 1, count=3)
|
||||
self.ae(sel(), 'ABCDE12345')
|
||||
# extending selection to a line that wraps below viewport
|
||||
s.reset()
|
||||
s.scroll(100, False)
|
||||
s.draw(('X' * s.columns) * (s.lines - 2))
|
||||
s.linefeed(), s.carriage_return()
|
||||
s.draw('678')
|
||||
s.linefeed(), s.carriage_return()
|
||||
s.draw('ABCDE12345')
|
||||
s.scroll(1, True)
|
||||
multi_click(x=1, y=3, count=3)
|
||||
self.ae(sel(), '678')
|
||||
press(x=2, y=s.lines - 1, button=GLFW_MOUSE_BUTTON_RIGHT)
|
||||
release(x=2, y=s.lines - 1, button=GLFW_MOUSE_BUTTON_RIGHT)
|
||||
self.ae(sel(), '678\nABCDE12345')
|
||||
s.scroll(100, False)
|
||||
|
||||
# Rectangle select
|
||||
init()
|
||||
press(x=1, y=1, modifiers=GLFW_MOD_ALT | GLFW_MOD_CONTROL)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue