mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-05-13 16:37:27 +00:00
Fix line-at-once selection not extending wrapped lines into scrollback
Fixes #9437
This commit is contained in:
parent
bc5c349d53
commit
625e984b12
3 changed files with 59 additions and 4 deletions
|
|
@ -208,6 +208,8 @@ Detailed list of changes
|
|||
- kitten choose-files: Fix TAB completion in the choose save file name prompt
|
||||
not working with respect to the current working directory (:iss:`9387`)
|
||||
|
||||
- Fix line-at-once selection not extending wrapped lines into scrollback (:iss:`9437`)
|
||||
|
||||
|
||||
0.45.0 [2025-12-24]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -4922,14 +4922,18 @@ cell_is_blank(const CPUCell *c) {
|
|||
return !cell_has_text(c) || cell_is_char(c, ' ');
|
||||
}
|
||||
|
||||
bool
|
||||
screen_selection_range_for_line(Screen *self, index_type y, index_type *start, index_type *end) {
|
||||
if (y >= self->lines) { return false; }
|
||||
Line *line = visual_line_(self, y);
|
||||
static void
|
||||
screen_selection_range_for_line_(Line *line, index_type *start, index_type *end) {
|
||||
index_type xlimit = line->xnum, xstart = 0;
|
||||
while (xlimit > 0 && cell_is_blank(line->cpu_cells + xlimit - 1)) xlimit--;
|
||||
while (xstart < xlimit && cell_is_blank(line->cpu_cells + xstart)) xstart++;
|
||||
*start = xstart; *end = xlimit > 0 ? xlimit - 1 : 0;
|
||||
}
|
||||
|
||||
bool
|
||||
screen_selection_range_for_line(Screen *self, index_type y, index_type *start, index_type *end) {
|
||||
if (y >= self->lines) { return false; }
|
||||
screen_selection_range_for_line_(visual_line_(self, y), start, end);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -5260,6 +5264,18 @@ continue_line_upwards(Screen *self, index_type top_line, SelectionBoundary *star
|
|||
return top_line;
|
||||
}
|
||||
|
||||
static index_type
|
||||
continue_line_upwards_scrollback(Screen *self, int top_line, SelectionBoundary *start, SelectionBoundary *end) {
|
||||
index_type num_in_scrollback = 0;
|
||||
Line *line = NULL;
|
||||
while (range_line_is_continued(self, top_line) && (line = range_line_(self, top_line-1))) {
|
||||
screen_selection_range_for_line_(line, &start->x, &end->x) ;
|
||||
top_line--; num_in_scrollback++;
|
||||
}
|
||||
return num_in_scrollback;
|
||||
}
|
||||
|
||||
|
||||
static index_type
|
||||
continue_line_downwards(Screen *self, index_type bottom_line, SelectionBoundary *start, SelectionBoundary *end) {
|
||||
while (bottom_line + 1 < self->lines && visual_line_is_continued(self, bottom_line + 1)) {
|
||||
|
|
@ -5400,6 +5416,15 @@ do_update_selection(Screen *self, Selection *s, index_type x, index_type y, bool
|
|||
} else {
|
||||
top_line = continue_line_upwards(self, top_line, &up_start, &up_end);
|
||||
S;
|
||||
// extend into scrollback if needed
|
||||
if (top_line == 0 && self->linebuf == self->main_linebuf) {
|
||||
index_type num_in_scrollback = continue_line_upwards_scrollback(
|
||||
self, top_line, &up_start, &up_end);
|
||||
if (num_in_scrollback) {
|
||||
s->start_scrolled_by += num_in_scrollback;
|
||||
s->start.x = up_start.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef S
|
||||
|
|
@ -5413,6 +5438,15 @@ do_update_selection(Screen *self, Selection *s, index_type x, index_type y, bool
|
|||
if (!s->adjusting_start) { a = &s->end; b = &s->start; }
|
||||
if (adjusted_boundary_is_before) {
|
||||
a->in_left_half_of_cell = true; a->x = up_start.x; a->y = top_line;
|
||||
// extend into scrollback if needed
|
||||
if (top_line == 0 && self->linebuf == self->main_linebuf) {
|
||||
index_type num_in_scrollback = continue_line_upwards_scrollback(
|
||||
self, top_line, &up_start, &up_end);
|
||||
if (num_in_scrollback) {
|
||||
s->start_scrolled_by += num_in_scrollback;
|
||||
s->start.x = up_start.x;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
a->in_left_half_of_cell = false; a->x = down_end.x; a->y = bottom_line;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -235,6 +235,25 @@ class TestMouse(BaseTest):
|
|||
self.ae(sel(), ' 123\n 456')
|
||||
release(button=GLFW_MOUSE_BUTTON_RIGHT)
|
||||
|
||||
# line select for wrapped lines in scrollback
|
||||
s.reset()
|
||||
s.draw('ABCDE12345')
|
||||
s.linefeed(), s.carriage_return()
|
||||
s.draw(('X' * s.columns) * (s.lines-1))
|
||||
multi_click(x=1, count=3)
|
||||
self.ae(sel(), 'ABCDE12345')
|
||||
s.reset()
|
||||
s.draw('ABCDE12345')
|
||||
s.linefeed(), s.carriage_return()
|
||||
s.draw('678')
|
||||
s.linefeed(), s.carriage_return()
|
||||
s.draw(('X' * s.columns) * (s.lines-2))
|
||||
multi_click(x=1, y=1, count=3)
|
||||
self.ae(sel(), '678')
|
||||
press(x=2, button=GLFW_MOUSE_BUTTON_RIGHT)
|
||||
release(x=2, button=GLFW_MOUSE_BUTTON_RIGHT)
|
||||
self.ae(sel(), 'ABCDE12345\n678')
|
||||
|
||||
# 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