diff --git a/crates/editor/src/actions.rs b/crates/editor/src/actions.rs index 270edbed1d1..f0b9cfb4f5d 100644 --- a/crates/editor/src/actions.rs +++ b/crates/editor/src/actions.rs @@ -856,6 +856,8 @@ actions!( Backtab, /// Toggles a bookmark at the current line. ToggleBookmark, + /// Toggles a bookmark at the current line, prompting for a label when adding one. + ToggleBookmarkWithLabel, /// Edits the bookmark's label at the current line. EditBookmark, /// Toggles a breakpoint at the current line. diff --git a/crates/editor/src/bookmarks.rs b/crates/editor/src/bookmarks.rs index e2d1c570d4e..12a899f398f 100644 --- a/crates/editor/src/bookmarks.rs +++ b/crates/editor/src/bookmarks.rs @@ -13,7 +13,7 @@ use workspace::{Workspace, searchable::Direction}; use crate::display_map::DisplayRow; use crate::{ EditBookmark, Editor, GoToNextBookmark, GoToPreviousBookmark, MultibufferSelectionMode, - SelectionEffects, ToggleBookmark, ViewBookmarks, scroll::Autoscroll, + SelectionEffects, ToggleBookmark, ToggleBookmarkWithLabel, ViewBookmarks, scroll::Autoscroll, }; #[derive(Clone, Debug)] @@ -46,6 +46,24 @@ impl Editor { _: &ToggleBookmark, window: &mut Window, cx: &mut Context, + ) { + self.toggle_bookmark_impl(false, window, cx); + } + + pub fn toggle_bookmark_with_label( + &mut self, + _: &ToggleBookmarkWithLabel, + window: &mut Window, + cx: &mut Context, + ) { + self.toggle_bookmark_impl(true, window, cx); + } + + fn toggle_bookmark_impl( + &mut self, + with_label: bool, + window: &mut Window, + cx: &mut Context, ) { let Some(bookmark_store) = self.bookmark_store.clone() else { return; @@ -91,34 +109,27 @@ impl Editor { if absent_targets.is_empty() { // All cursors are on existing bookmarks, remove all bookmarks. self.toggle_bookmarks(exist_targets, String::new(), cx); - } else { - // Only add new ones and leave existing ones unchanged. + } else if with_label { + // Only add new ones (prompting for a label) and leave existing ones unchanged. self.add_toggle_bookmark_blocks(absent_targets, bookmark_store, window, cx); + } else { + // Only add new (unnamed) bookmarks and leave existing ones unchanged. + self.toggle_bookmarks(absent_targets, String::new(), cx); } cx.notify(); } - pub fn toggle_bookmark_at_row( - &mut self, - row: DisplayRow, - window: &mut Window, - cx: &mut Context, - ) { + pub fn toggle_bookmark_at_row(&mut self, row: DisplayRow, cx: &mut Context) { let display_snapshot = self.display_snapshot(cx); let point = display_snapshot.display_point_to_point(row.as_display_point(), Bias::Left); let buffer_snapshot = self.buffer.read(cx).snapshot(cx); let anchor = buffer_snapshot.anchor_before(point); - self.toggle_bookmark_at_anchor(anchor, window, cx); + self.toggle_bookmark_at_anchor(anchor, cx); } - pub fn toggle_bookmark_at_anchor( - &mut self, - anchor: Anchor, - window: &mut Window, - cx: &mut Context, - ) { + pub fn toggle_bookmark_at_anchor(&mut self, anchor: Anchor, cx: &mut Context) { let buffer_snapshot = self.buffer.read(cx).snapshot(cx); let Some((position, _)) = buffer_snapshot.anchor_to_buffer_anchor(anchor) else { return; @@ -131,18 +142,9 @@ impl Editor { return; }; - let target = BookmarkTarget { - buffer, - anchor, - buffer_anchor: position, - }; - if Self::bookmark_exists_for_target(&bookmark_store, &target, cx) { - bookmark_store.update(cx, |bookmark_store, cx| { - bookmark_store.toggle_bookmark(target.buffer, position, String::new(), cx); - }); - } else { - self.add_toggle_bookmark_blocks(vec![target], bookmark_store, window, cx) - } + bookmark_store.update(cx, |bookmark_store, cx| { + bookmark_store.toggle_bookmark(buffer, position, String::new(), cx); + }); cx.notify(); } diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 9437b8899b7..12138cb7f92 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -3990,8 +3990,8 @@ impl Editor { .size(ui::ButtonSize::None) .icon_color(Color::Info) .style(ButtonStyle::Transparent) - .on_click(cx.listener(move |editor, _, window, cx| { - editor.toggle_bookmark_at_row(row, window, cx); + .on_click(cx.listener(move |editor, _, _window, cx| { + editor.toggle_bookmark_at_row(row, cx); })) .on_right_click(cx.listener(move |editor, event: &ClickEvent, window, cx| { editor.set_gutter_context_menu(row, None, event.position(), window, cx); @@ -4282,10 +4282,10 @@ impl Editor { .separator() .entry(set_bookmark_msg, Some(ToggleBookmark.boxed_clone()), { let weak_editor = weak_editor.clone(); - move |window, cx| { + move |_window, cx| { weak_editor .update(cx, |this, cx| { - this.toggle_bookmark_at_anchor(anchor, window, cx); + this.toggle_bookmark_at_anchor(anchor, cx); }) .log_err(); } @@ -4481,7 +4481,7 @@ impl Editor { }; match intent { - Intent::SetBookmark => editor.toggle_bookmark_at_row(row, window, cx), + Intent::SetBookmark => editor.toggle_bookmark_at_row(row, cx), Intent::SetBreakpoint => editor.edit_breakpoint_at_anchor( position, Breakpoint::new_standard(), diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 6b43dff2cc9..de1d6905205 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -29140,6 +29140,13 @@ impl BookmarkTestContext { }); } + fn toggle_bookmark_with_label(&mut self) { + self.editor + .update_in(&mut self.cx, |editor: &mut Editor, window, cx| { + editor.toggle_bookmark_with_label(&actions::ToggleBookmarkWithLabel, window, cx); + }); + } + fn confirm_bookmark_prompt(&mut self, label: &str) { if !label.is_empty() { self.cx.simulate_input(label); @@ -29149,7 +29156,7 @@ impl BookmarkTestContext { } fn add_bookmark_with_label(&mut self, label: &str) { - self.toggle_bookmark(); + self.toggle_bookmark_with_label(); self.confirm_bookmark_prompt(label); } @@ -29204,13 +29211,39 @@ async fn test_bookmark_toggling(cx: &mut TestAppContext) { } #[gpui::test] -async fn test_bookmark_toggling_with_multiple_selections(cx: &mut TestAppContext) { +async fn test_bookmark_toggling_unnamed_with_multiple_selections(cx: &mut TestAppContext) { let mut ctx = BookmarkTestContext::new("First line\nSecond line\nThird line\nFourth line", cx).await; ctx.select_rows(&[0, 1, 2]); ctx.toggle_bookmark(); + ctx.assert_prompt_block_count(0); + ctx.assert_bookmarked_file_count(1); + ctx.assert_bookmark_labels(vec![(0, ""), (1, ""), (2, "")]); + + ctx.select_rows(&[0, 1, 2, 3]); + ctx.toggle_bookmark(); + + ctx.assert_prompt_block_count(0); + ctx.assert_bookmark_rows(vec![0, 1, 2, 3]); + + ctx.select_rows(&[0, 1, 2, 3]); + ctx.toggle_bookmark(); + + ctx.assert_prompt_block_count(0); + ctx.assert_bookmarked_file_count(0); + ctx.assert_bookmark_rows(vec![]); +} + +#[gpui::test] +async fn test_bookmark_toggling_with_label_with_multiple_selections(cx: &mut TestAppContext) { + let mut ctx = + BookmarkTestContext::new("First line\nSecond line\nThird line\nFourth line", cx).await; + + ctx.select_rows(&[0, 1, 2]); + ctx.toggle_bookmark_with_label(); + ctx.assert_prompt_block_count(3); ctx.assert_bookmarked_file_count(0); @@ -29229,7 +29262,7 @@ async fn test_bookmark_toggling_with_multiple_selections(cx: &mut TestAppContext ]); ctx.select_rows(&[0, 1, 2, 3]); - ctx.toggle_bookmark(); + ctx.toggle_bookmark_with_label(); ctx.assert_prompt_block_count(1); ctx.assert_bookmark_labels(vec![ @@ -29249,7 +29282,7 @@ async fn test_bookmark_toggling_with_multiple_selections(cx: &mut TestAppContext ]); ctx.select_rows(&[0, 1, 2, 3]); - ctx.toggle_bookmark(); + ctx.toggle_bookmark_with_label(); ctx.assert_prompt_block_count(0); ctx.assert_bookmarked_file_count(0); diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 81ef8b6a9d8..0e4cb930dcb 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -538,6 +538,7 @@ impl EditorElement { register_action(editor, window, Editor::spawn_nearest_task); register_action(editor, window, Editor::open_selections_in_multibuffer); register_action(editor, window, Editor::toggle_bookmark); + register_action(editor, window, Editor::toggle_bookmark_with_label); register_action(editor, window, Editor::edit_bookmark); register_action(editor, window, Editor::go_to_next_bookmark); register_action(editor, window, Editor::go_to_previous_bookmark);