Make the existing bookmark action add an unnamed bookmark again (#60185)

Zed don't surface the fact that bookmarks can have labels/names now
anywhere except opening the bookmark name editor every time you place
one. This keeps the label/name mechanism but makes the default add
bookmark action add an unnamed one.

Next step is probably to enable holding shift (or some other modifier)
to place a named bookmark, or even a setting to switch between default
named vs unnamed.

Release Notes:

- N/A
This commit is contained in:
Yara 🏳️‍⚧️ 2026-07-01 11:34:33 +02:00 committed by GitHub
parent 7b128f9263
commit 914cc66103
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 75 additions and 37 deletions

View file

@ -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.

View file

@ -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>,
) {
self.toggle_bookmark_impl(false, window, cx);
}
pub fn toggle_bookmark_with_label(
&mut self,
_: &ToggleBookmarkWithLabel,
window: &mut Window,
cx: &mut Context<Self>,
) {
self.toggle_bookmark_impl(true, window, cx);
}
fn toggle_bookmark_impl(
&mut self,
with_label: bool,
window: &mut Window,
cx: &mut Context<Self>,
) {
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<Self>,
) {
pub fn toggle_bookmark_at_row(&mut self, row: DisplayRow, cx: &mut Context<Self>) {
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<Self>,
) {
pub fn toggle_bookmark_at_anchor(&mut self, anchor: Anchor, cx: &mut Context<Self>) {
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();
}

View file

@ -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(),

View file

@ -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);

View file

@ -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);