diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f072f3a45..2c2c081c0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -18,6 +18,9 @@ version 0.9.0 [future] - A new remote control command "set-colors" to change the current and/or configured colors. +- When double-clicking to select a word, select wrods that continue onto the + next/prev line as well. + - Add an "include" directive for the config files to read multiple config files - Improve mouse selection for windows with padding. Moving the mouse into the diff --git a/kitty/mouse.c b/kitty/mouse.c index f01e9d44e..b9529ee79 100644 --- a/kitty/mouse.c +++ b/kitty/mouse.c @@ -260,9 +260,10 @@ multi_click(Window *w, unsigned int count) { index_type start, end; bool found_selection = false; SelectionExtendMode mode = EXTEND_CELL; + unsigned int y1 = w->mouse_cell_y, y2 = w->mouse_cell_y; switch(count) { case 2: - found_selection = screen_selection_range_for_word(screen, w->mouse_cell_x, w->mouse_cell_y, &start, &end); + found_selection = screen_selection_range_for_word(screen, w->mouse_cell_x, &y1, &y2, &start, &end); mode = EXTEND_WORD; break; case 3: @@ -273,8 +274,8 @@ multi_click(Window *w, unsigned int count) { break; } if (found_selection) { - screen_start_selection(screen, start, w->mouse_cell_y, false, mode); - screen_update_selection(screen, end, w->mouse_cell_y, false); + screen_start_selection(screen, start, y1, false, mode); + screen_update_selection(screen, end, y2, false); } } diff --git a/kitty/screen.c b/kitty/screen.c index 5bbe90b6c..ae2740f08 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -1676,17 +1676,31 @@ is_opt_word_char(char_type ch) { } bool -screen_selection_range_for_word(Screen *self, index_type x, index_type y, index_type *s, index_type *e) { - if (y >= self->lines || x >= self->columns) return false; +screen_selection_range_for_word(Screen *self, index_type x, index_type *y1, index_type *y2, index_type *s, index_type *e) { + if (*y1 >= self->lines || x >= self->columns) return false; index_type start, end; - Line *line = visual_line_(self, y); + Line *line = visual_line_(self, *y1); + *y2 = *y1; #define is_ok(x) (is_word_char((line->cells[x].ch)) || is_opt_word_char(line->cells[x].ch)) if (!is_ok(x)) { start = x; end = x + 1; } else { start = x, end = x; - while(start > 0 && is_ok(start - 1)) start--; - while(end < self->columns - 1 && is_ok(end + 1)) end++; + while(true) { + while(start > 0 && is_ok(start - 1)) start--; + if (start > 0 || !line->continued || *y1 == 0) break; + line = visual_line_(self, *y1 - 1); + if (!is_ok(self->columns - 1)) break; + (*y1)--; start = self->columns - 1; + } + line = visual_line_(self, *y2); + while(true) { + while(end < self->columns - 1 && is_ok(end + 1)) end++; + if (end < self->columns - 1 || *y2 >= self->lines - 1) break; + line = visual_line_(self, *y2 + 1); + if (!line->continued || !is_ok(0)) break; + (*y2)++; end = 0; + } } *s = start; *e = end; return true; @@ -1763,16 +1777,40 @@ screen_update_selection(Screen *self, index_type x, index_type y, bool ended) { index_type start, end; bool found = false; switch(self->selection.extend_mode) { - case EXTEND_WORD: - found = screen_selection_range_for_word(self, x, y, &start, &end); + case EXTEND_WORD: { + index_type y1 = y, y2; + found = screen_selection_range_for_word(self, x, &y1, &y2, &start, &end); + if (found) { +#define SMALLER(x1, y1, x2, y2) (y1 < y2 || (y1 == y2 && x1 < x2)) + if (SMALLER(self->selection.end_x, self->selection.end_y, self->selection.start_x, self->selection.start_y)) { + // extend leftwards + self->selection.end_x = start; self->selection.end_y = y1; + y1 = self->selection.start_y; + found = screen_selection_range_for_word(self, self->selection.start_x, &y1, &y2, &start, &end); + if (found) { + self->selection.start_x = end; self->selection.start_y = y2; + } + } else { + // extend rightwards + self->selection.end_x = end; self->selection.end_y = y2; + y1 = self->selection.start_y; + found = screen_selection_range_for_word(self, self->selection.start_x, &y1, &y2, &start, &end); + if (found) { + self->selection.start_x = start; self->selection.start_y = y1; + } + + } +#undef SMALLER + } break; + } case EXTEND_LINE: found = screen_selection_range_for_line(self, y, &start, &end); + if (found) self->selection.end_x = end; break; case EXTEND_CELL: break; } - if (found) self->selection.end_x = end; call_boss(set_primary_selection, NULL); } diff --git a/kitty/screen.h b/kitty/screen.h index 68dad0b3e..a4c5eb68f 100644 --- a/kitty/screen.h +++ b/kitty/screen.h @@ -158,7 +158,7 @@ bool screen_invert_colors(Screen *self); void screen_update_cell_data(Screen *self, void *address, size_t sz); bool screen_is_cursor_visible(Screen *self); bool screen_selection_range_for_line(Screen *self, index_type y, index_type *start, index_type *end); -bool screen_selection_range_for_word(Screen *self, index_type x, index_type y, index_type *start, index_type *end); +bool screen_selection_range_for_word(Screen *self, index_type x, index_type *, index_type *, index_type *start, index_type *end); void screen_start_selection(Screen *self, index_type x, index_type y, bool, SelectionExtendMode); void screen_update_selection(Screen *self, index_type x, index_type y, bool ended); bool screen_history_scroll(Screen *self, int amt, bool upwards);