From a7e5b949a6f569169765681476a2b3e2193bb0ef Mon Sep 17 00:00:00 2001 From: mc36 Date: Fri, 27 Mar 2026 08:21:30 +0100 Subject: [PATCH] adding mouse action line_from_begin see #9755 --- kitty/fast_data_types.pyi | 1 + kitty/mouse.c | 5 +++++ kitty/options/definition.py | 8 ++++++++ kitty/options/types.py | 6 ++++++ kitty/options/utils.py | 1 + kitty/screen.c | 7 +++++-- kitty/screen.h | 2 +- 7 files changed, 27 insertions(+), 3 deletions(-) diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index f9d39f5b2..8e779461e 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -51,6 +51,7 @@ MOUSE_SELECTION_EXTEND: int MOUSE_SELECTION_NORMAL: int MOUSE_SELECTION_WORD: int MOUSE_SELECTION_RECTANGLE: int +MOUSE_SELECTION_LINE_FROM_BEGIN: int MOUSE_SELECTION_LINE_FROM_POINT: int MOUSE_SELECTION_UPTO_SURROUNDING_WHITESPACE: int MOUSE_SELECTION_WORD_AND_LINE_FROM_POINT: int diff --git a/kitty/mouse.c b/kitty/mouse.c index a80375cd1..63df1e16d 100644 --- a/kitty/mouse.c +++ b/kitty/mouse.c @@ -1110,6 +1110,7 @@ typedef enum MouseSelectionType { MOUSE_SELECTION_RECTANGLE, MOUSE_SELECTION_WORD, MOUSE_SELECTION_LINE, + MOUSE_SELECTION_LINE_FROM_BEGIN, MOUSE_SELECTION_LINE_FROM_POINT, MOUSE_SELECTION_WORD_AND_LINE_FROM_POINT, MOUSE_SELECTION_MOVE_END, @@ -1141,6 +1142,9 @@ mouse_selection(Window *w, int code, int button) { case MOUSE_SELECTION_LINE: if (screen_selection_range_for_line(screen, w->mouse_pos.cell_y, &start, &end)) S(EXTEND_LINE); break; + case MOUSE_SELECTION_LINE_FROM_BEGIN: + if (screen_selection_range_for_line(screen, w->mouse_pos.cell_y, &start, &end)) S(EXTEND_LINE_FROM_BEGIN); + break; 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; @@ -1591,6 +1595,7 @@ init_mouse(PyObject *module) { PyModule_AddIntMacro(module, MOUSE_SELECTION_RECTANGLE); PyModule_AddIntMacro(module, MOUSE_SELECTION_WORD); PyModule_AddIntMacro(module, MOUSE_SELECTION_LINE); + PyModule_AddIntMacro(module, MOUSE_SELECTION_LINE_FROM_BEGIN); 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); diff --git a/kitty/options/definition.py b/kitty/options/definition.py index 23f1ef023..639c99619 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -972,6 +972,10 @@ mma('Select a line', 'select_line left triplepress ungrabbed mouse_selection line', ) +mma('Select line from beginning of line', + 'select_line_from_begin left triplepress ungrabbed mouse_selection line_from_begin', + ) + mma('Select line from point', 'select_line_from_point ctrl+alt+left triplepress ungrabbed mouse_selection line_from_point', long_text='Select from the clicked point to the end of the line.' @@ -1019,6 +1023,10 @@ mma('Select a line even when grabbed', 'select_line_grabbed shift+left triplepress ungrabbed,grabbed mouse_selection line', ) +mma('Select line from begin even when grabbed', + 'select_line_from_begin_grabbed left triplepress ungrabbed,grabbed mouse_selection line_from_begin', + ) + mma('Select line from point even when grabbed', 'select_line_from_point_grabbed ctrl+shift+alt+left triplepress ungrabbed,grabbed mouse_selection line_from_point', long_text='Select from the clicked point to the end of the line even when grabbed.' diff --git a/kitty/options/types.py b/kitty/options/types.py index eb27b0845..7ce63dc9f 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -1086,6 +1086,8 @@ defaults.mouse_map = [ MouseMapping(repeat_count=2, definition='mouse_selection word'), # select_line MouseMapping(repeat_count=3, definition='mouse_selection line'), + # select_line_from_begin + MouseMapping(mods=6, repeat_count=3, definition='mouse_selection line_from_begin'), # select_line_from_point MouseMapping(mods=6, repeat_count=3, definition='mouse_selection line_from_point'), # extend_selection @@ -1116,6 +1118,10 @@ defaults.mouse_map = [ MouseMapping(mods=7, repeat_count=3, grabbed=True, definition='mouse_selection line_from_point'), # select_line_from_point_grabbed MouseMapping(mods=7, repeat_count=3, definition='mouse_selection line_from_point'), + # select_line_from_begin_grabbed + MouseMapping(mods=7, repeat_count=3, grabbed=True, definition='mouse_selection line_from_begin'), + # select_line_from_begin_grabbed + MouseMapping(mods=7, repeat_count=3, definition='mouse_selection line_from_begin'), # extend_selection_grabbed MouseMapping(button=1, mods=1, grabbed=True, definition='mouse_selection extend'), # extend_selection_grabbed diff --git a/kitty/options/utils.py b/kitty/options/utils.py index 17ee94cc2..0fc010a12 100644 --- a/kitty/options/utils.py +++ b/kitty/options/utils.py @@ -444,6 +444,7 @@ def mouse_selection(func: str, rest: str) -> FuncArgsType: 'rectangle': defines.MOUSE_SELECTION_RECTANGLE, 'word': defines.MOUSE_SELECTION_WORD, 'line': defines.MOUSE_SELECTION_LINE, + 'line_from_begin': defines.MOUSE_SELECTION_LINE_FROM_BEGIN, 'line_from_point': defines.MOUSE_SELECTION_LINE_FROM_POINT, 'word_and_line_from_point': defines.MOUSE_SELECTION_WORD_AND_LINE_FROM_POINT, 'upto_surrounding_whitespace': defines.MOUSE_SELECTION_UPTO_SURROUNDING_WHITESPACE, diff --git a/kitty/screen.c b/kitty/screen.c index 165138b06..8ad15cea6 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -5353,7 +5353,7 @@ do_update_selection(Screen *self, Selection *s, index_type x, index_type y, bool 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 || self->selections.extend_mode == EXTEND_WORD_AND_LINE_FROM_POINT) { + if (self->selections.extend_mode == EXTEND_LINE || self->selections.extend_mode == EXTEND_LINE_FROM_BEGIN || 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); @@ -5418,6 +5418,7 @@ do_update_selection(Screen *self, Selection *s, index_type x, index_type y, bool } break; } + case EXTEND_LINE_FROM_BEGIN: case EXTEND_LINE_FROM_POINT: case EXTEND_WORD_AND_LINE_FROM_POINT: case EXTEND_LINE: { @@ -5436,7 +5437,9 @@ do_update_selection(Screen *self, Selection *s, index_type x, index_type y, bool s->start.x = up_start.x; s->end.x = bottom_line == top_line ? up_end.x : down_end.x; down_start = up_start; down_end = up_end; bottom_line = continue_line_downwards(self, bottom_line, &down_start, &down_end); - if (self->selections.extend_mode == EXTEND_LINE_FROM_POINT) { + if (self->selections.extend_mode == EXTEND_LINE_FROM_BEGIN) { + S; s->start.x = 0; + } else if (self->selections.extend_mode == EXTEND_LINE_FROM_POINT) { if (x <= up_end.x) { S; s->start.x = MAX(x, up_start.x); } diff --git a/kitty/screen.h b/kitty/screen.h index aa943d799..3a5645817 100644 --- a/kitty/screen.h +++ b/kitty/screen.h @@ -36,7 +36,7 @@ typedef struct { bool in_left_half_of_cell; } SelectionBoundary; -typedef enum SelectionExtendModes { EXTEND_CELL, EXTEND_WORD, EXTEND_LINE, EXTEND_LINE_FROM_POINT, EXTEND_WORD_AND_LINE_FROM_POINT } SelectionExtendMode; +typedef enum SelectionExtendModes { EXTEND_CELL, EXTEND_WORD, EXTEND_LINE, EXTEND_LINE_FROM_BEGIN, EXTEND_LINE_FROM_POINT, EXTEND_WORD_AND_LINE_FROM_POINT } SelectionExtendMode; typedef struct { index_type x, x_limit;