From d310acc780c521c5df7d73adb6bce9fba2832e10 Mon Sep 17 00:00:00 2001 From: Eric Myhre Date: Tue, 26 Sep 2023 04:37:13 +0200 Subject: [PATCH] Add word-and-line-from-point feature to possible mouse selection actions. --- kitty/fast_data_types.pyi | 1 + kitty/mouse.c | 5 +++++ kitty/options/definition.py | 10 ++++++++++ kitty/options/utils.py | 1 + kitty/screen.c | 11 ++++++++++- kitty/screen.h | 2 +- 6 files changed, 28 insertions(+), 2 deletions(-) diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index aaceac0ee..e32e7e880 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -35,6 +35,7 @@ MOUSE_SELECTION_NORMAL: int MOUSE_SELECTION_WORD: int MOUSE_SELECTION_RECTANGLE: int MOUSE_SELECTION_LINE_FROM_POINT: int +MOUSE_SELECTION_WORD_AND_LINE_FROM_POINT: int MOUSE_SELECTION_MOVE_END: int KITTY_VCS_REV: str NO_CLOSE_REQUESTED: int diff --git a/kitty/mouse.c b/kitty/mouse.c index 87db54f72..87ad347fa 100644 --- a/kitty/mouse.c +++ b/kitty/mouse.c @@ -689,6 +689,7 @@ typedef enum MouseSelectionType { MOUSE_SELECTION_WORD, MOUSE_SELECTION_LINE, MOUSE_SELECTION_LINE_FROM_POINT, + MOUSE_SELECTION_WORD_AND_LINE_FROM_POINT, MOUSE_SELECTION_MOVE_END, } MouseSelectionType; @@ -720,6 +721,9 @@ mouse_selection(Window *w, int code, int button) { case MOUSE_SELECTION_LINE_FROM_POINT: if (screen_selection_range_for_line(screen, w->mouse_pos.cell_y, &start, &end) && end > w->mouse_pos.cell_x) S(EXTEND_LINE_FROM_POINT); break; + case MOUSE_SELECTION_WORD_AND_LINE_FROM_POINT: + if (screen_selection_range_for_line(screen, w->mouse_pos.cell_y, &start, &end) && end > w->mouse_pos.cell_x) S(EXTEND_WORD_AND_LINE_FROM_POINT); + break; case MOUSE_SELECTION_EXTEND: extend_selection(w, false, true); break; @@ -1050,6 +1054,7 @@ init_mouse(PyObject *module) { PyModule_AddIntMacro(module, MOUSE_SELECTION_WORD); PyModule_AddIntMacro(module, MOUSE_SELECTION_LINE); PyModule_AddIntMacro(module, MOUSE_SELECTION_LINE_FROM_POINT); + PyModule_AddIntMacro(module, MOUSE_SELECTION_WORD_AND_LINE_FROM_POINT); PyModule_AddIntMacro(module, MOUSE_SELECTION_MOVE_END); if (PyModule_AddFunctions(module, module_methods) != 0) return false; return true; diff --git a/kitty/options/definition.py b/kitty/options/definition.py index 69d220d93..f95d02fa7 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -722,6 +722,11 @@ mma('Select line from point', long_text='Select from the clicked point to the end of the line.' ) +mma('Select a word at the point, together with the rest of the line', + 'select_word_and_line_from_point ctrl+alt+left triplepress ungrabbed mouse_selection word_and_line_from_point', + long_text='Select the word under the clicked point, as well as through the end of the line.' + ) + mma('Extend the current selection', 'extend_selection right press ungrabbed mouse_selection extend', long_text=''' @@ -759,6 +764,11 @@ mma('Select line from point even when grabbed', long_text='Select from the clicked point to the end of the line even when grabbed.' ) +mma('Select line from point even when grabbed', + 'select_word_and_line_from_point_grabbed ctrl+shift+alt+left triplepress ungrabbed,grabbed mouse_selection word_and_line_from_point', + long_text='Select the click word and to end of line, even when grabbed.' + ) + mma('Extend the current selection even when grabbed', 'extend_selection_grabbed shift+right press ungrabbed,grabbed mouse_selection extend', ) diff --git a/kitty/options/utils.py b/kitty/options/utils.py index 0beec1db1..29ee951ad 100644 --- a/kitty/options/utils.py +++ b/kitty/options/utils.py @@ -388,6 +388,7 @@ def mouse_selection(func: str, rest: str) -> FuncArgsType: 'word': defines.MOUSE_SELECTION_WORD, 'line': defines.MOUSE_SELECTION_LINE, 'line_from_point': defines.MOUSE_SELECTION_LINE_FROM_POINT, + 'word_and_line_from_point': defines.MOUSE_SELECTION_WORD_AND_LINE_FROM_POINT, } setattr(mouse_selection, 'code_map', cmap) return func, [cmap[rest]] diff --git a/kitty/screen.c b/kitty/screen.c index 9daba9f7a..58a8c40f8 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -3890,7 +3890,7 @@ screen_update_selection(Screen *self, index_type x, index_type y, bool in_left_h if (upd.set_as_nearest_extend || self->selections.extension_in_progress) { self->selections.extension_in_progress = true; bool start_is_nearer = false; - if (self->selections.extend_mode == EXTEND_LINE || self->selections.extend_mode == EXTEND_LINE_FROM_POINT) { + if (self->selections.extend_mode == EXTEND_LINE || self->selections.extend_mode == EXTEND_LINE_FROM_POINT || self->selections.extend_mode == EXTEND_WORD_AND_LINE_FROM_POINT) { if (abs_start.y == abs_end.y) { if (abs_current_input.y == abs_start.y) start_is_nearer = selection_boundary_less_than(&abs_start, &abs_end) ? (abs_current_input.x <= abs_start.x) : (abs_current_input.x <= abs_end.x); else start_is_nearer = selection_boundary_less_than(&abs_start, &abs_end) ? (abs_current_input.y > abs_start.y) : (abs_current_input.y < abs_end.y); @@ -3956,6 +3956,7 @@ screen_update_selection(Screen *self, index_type x, index_type y, bool in_left_h break; } case EXTEND_LINE_FROM_POINT: + case EXTEND_WORD_AND_LINE_FROM_POINT: case EXTEND_LINE: { bool adjust_both_ends = is_selection_empty(s); if (s->adjusting_start || adjust_both_ends) s->start_scrolled_by = self->scrolled_by; @@ -3976,6 +3977,14 @@ screen_update_selection(Screen *self, index_type x, index_type y, bool in_left_h if (x <= up_end.x) { S; s->start.x = MAX(x, up_start.x); } + } else if (self->selections.extend_mode == EXTEND_WORD_AND_LINE_FROM_POINT) { + if (x <= up_end.x) { + S; s->start.x = MAX(x, up_start.x); + } + const bool word_found_at_cursor = screen_selection_range_for_word(self, s->input_current.x, s->input_current.y, &start.y, &end.y, &start.x, &end.x, true); + if (word_found_at_cursor) { + *a = start; a->in_left_half_of_cell = true; + } } else { top_line = continue_line_upwards(self, top_line, &up_start, &up_end); S; diff --git a/kitty/screen.h b/kitty/screen.h index 482bb7a6d..c6c74ee5b 100644 --- a/kitty/screen.h +++ b/kitty/screen.h @@ -25,7 +25,7 @@ typedef struct { bool in_left_half_of_cell; } SelectionBoundary; -typedef enum SelectionExtendModes { EXTEND_CELL, EXTEND_WORD, EXTEND_LINE, EXTEND_LINE_FROM_POINT } SelectionExtendMode; +typedef enum SelectionExtendModes { EXTEND_CELL, EXTEND_WORD, EXTEND_LINE, EXTEND_LINE_FROM_POINT, EXTEND_WORD_AND_LINE_FROM_POINT } SelectionExtendMode; typedef struct { index_type x, x_limit;