From b19bb010033c241a6e7e76d3d07436ad7d00cdbf Mon Sep 17 00:00:00 2001 From: reya <123083837+reyamir@users.noreply.github.com> Date: Mon, 25 Aug 2025 12:37:20 +0700 Subject: [PATCH] feat: support triple-click to select entire line --- crates/ui/src/input/state.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/crates/ui/src/input/state.rs b/crates/ui/src/input/state.rs index a2b5d75..78358c1 100644 --- a/crates/ui/src/input/state.rs +++ b/crates/ui/src/input/state.rs @@ -1077,6 +1077,7 @@ impl InputState { } let offset = self.next_boundary(self.cursor_offset()); + // ignore if offset is "\n" if self .text_for_range( @@ -1251,6 +1252,7 @@ impl InputState { } self.selecting = true; + let offset = self.index_for_mouse_position(event.position, window, cx); // Double click to select word @@ -1259,6 +1261,12 @@ impl InputState { return; } + // Triple click to select line + if event.button == MouseButton::Left && event.click_count == 3 { + self.select_line(window, cx); + return; + } + if event.modifiers.shift { self.select_to(offset, window, cx); } else { @@ -1414,7 +1422,7 @@ impl InputState { /// The offset is the UTF-8 offset. /// /// Ensure the offset use self.next_boundary or self.previous_boundary to get the correct offset. - fn move_to(&mut self, offset: usize, _: &mut Window, cx: &mut Context) { + fn move_to(&mut self, offset: usize, _window: &mut Window, cx: &mut Context) { let offset = offset.clamp(0, self.text.len()); self.selected_range = offset..offset; self.pause_blink_cursor(cx); @@ -1541,8 +1549,9 @@ impl InputState { /// The offset is the UTF-8 offset. /// /// Ensure the offset use self.next_boundary or self.previous_boundary to get the correct offset. - fn select_to(&mut self, offset: usize, _: &mut Window, cx: &mut Context) { + fn select_to(&mut self, offset: usize, _window: &mut Window, cx: &mut Context) { let offset = offset.clamp(0, self.text.len()); + if self.selection_reversed { self.selected_range.start = offset } else { @@ -1563,9 +1572,11 @@ impl InputState { self.selected_range.end = word_range.end; } } + if self.selected_range.is_empty() { self.update_preferred_x_offset(cx); } + cx.notify() } @@ -1579,9 +1590,11 @@ impl InputState { let mut start = self.offset_to_utf16(offset); let mut end = start; + let prev_text = self .text_for_range(self.range_to_utf16(&(0..start)), &mut None, window, cx) .unwrap_or_default(); + let next_text = self .text_for_range( self.range_to_utf16(&(end..self.text.len())), @@ -1619,9 +1632,18 @@ impl InputState { self.selected_range = start..end; self.selected_word_range = Some(self.selected_range.clone()); + cx.notify() } + /// Selects the entire line containing the cursor. + fn select_line(&mut self, window: &mut Window, cx: &mut Context) { + let offset = self.start_of_line(window, cx); + let end = self.end_of_line(window, cx); + self.move_to(end, window, cx); + self.select_to(offset, window, cx); + } + fn unselect(&mut self, _: &mut Window, cx: &mut Context) { let offset = self.next_boundary(self.cursor_offset()); self.selected_range = offset..offset;