logiguard fork: GPUI xdg-activation keyboard-focus serial fix
Some checks failed
Update All Top Ranking Issues / update_top_ranking_issues (push) Has been cancelled
Triage Project Sync (#84) / Sync triage project (push) Has been cancelled
release_nightly / notify_on_failure (push) Has been cancelled
release_nightly / check_style (push) Has been cancelled
release_nightly / run_tests_windows (push) Has been cancelled
release_nightly / clippy_windows (push) Has been cancelled
release_nightly / bundle_linux_aarch64 (push) Has been cancelled
release_nightly / bundle_linux_x86_64 (push) Has been cancelled
release_nightly / bundle_mac_aarch64 (push) Has been cancelled
release_nightly / bundle_mac_x86_64 (push) Has been cancelled
release_nightly / bundle_windows_aarch64 (push) Has been cancelled
release_nightly / bundle_windows_x86_64 (push) Has been cancelled
release_nightly / build_nix_linux_x86_64 (push) Has been cancelled
release_nightly / build_nix_mac_aarch64 (push) Has been cancelled
release_nightly / update_nightly_tag (push) Has been cancelled
Hotfix Review Monitor / check-hotfix-reviews (push) Has been cancelled
Stale PR Review Reminder / check-stale-prs (push) Has been cancelled
Update Weekly Top Ranking Issues / update_top_ranking_issues (push) Has been cancelled
Bump collab-staging Tag / update-collab-staging-tag (push) Has been cancelled
compliance_check / scheduled_compliance_check (push) Has been cancelled

Single-commit orphan branch: full zed-industries/zed @ 8c74db0 source tree
with a 3-file patch applied (no upstream history).

Patch (crates/gpui_linux/src/linux/wayland/):
  - serial.rs: add SerialKind::KeyboardEnter
  - client.rs: store wl_keyboard.enter serial; add latest_serial_of()
  - window.rs: activate() uses keyboard-enter serial (Mutter focus gate)

Mutter honors window activation only when the token carries the keyboard-
focus serial from wl_keyboard.enter; GPUI used a stale mouse-press serial.
See docs/tray-window-focus-wayland.md in logiguard.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Mohamad Khani
2026-07-14 02:22:17 +03:30
commit b72a46db68
3984 changed files with 1583326 additions and 0 deletions

View File

@@ -0,0 +1,685 @@
use std::{path::Path, sync::Arc};
use collections::BTreeMap;
use gpui::{Entity, TestAppContext};
use language::Buffer;
use project::{Project, bookmark_store::SerializedBookmark};
use serde_json::json;
use util::path;
mod integration {
use super::*;
use fs::Fs as _;
fn init_test(cx: &mut TestAppContext) {
cx.update(|cx| {
let settings_store = settings::SettingsStore::test(cx);
cx.set_global(settings_store);
release_channel::init(semver::Version::new(0, 0, 0), cx);
});
}
fn project_path(path: &str) -> Arc<Path> {
Arc::from(Path::new(path))
}
async fn open_buffer(
project: &Entity<Project>,
path: &str,
cx: &mut TestAppContext,
) -> Entity<Buffer> {
project
.update(cx, |project, cx| {
project.open_local_buffer(Path::new(path), cx)
})
.await
.unwrap()
}
fn add_bookmarks(
project: &Entity<Project>,
buffer: &Entity<Buffer>,
rows: &[u32],
cx: &mut TestAppContext,
) {
let buffer = buffer.clone();
project.update(cx, |project, cx| {
let bookmark_store = project.bookmark_store();
let snapshot = buffer.read(cx).snapshot();
for &row in rows {
let anchor = snapshot.anchor_after(text::Point::new(row, 0));
bookmark_store.update(cx, |store, cx| {
store.toggle_bookmark(buffer.clone(), anchor, cx);
});
}
});
}
fn get_all_bookmarks(
project: &Entity<Project>,
cx: &mut TestAppContext,
) -> BTreeMap<Arc<Path>, Vec<SerializedBookmark>> {
project.read_with(cx, |project, cx| {
project
.bookmark_store()
.read(cx)
.all_serialized_bookmarks(cx)
})
}
fn build_serialized(
entries: &[(&str, &[u32])],
) -> BTreeMap<Arc<Path>, Vec<SerializedBookmark>> {
let mut map = BTreeMap::new();
for &(path_str, rows) in entries {
let path = project_path(path_str);
map.insert(
path.clone(),
rows.iter().map(|&row| SerializedBookmark(row)).collect(),
);
}
map
}
async fn restore_bookmarks(
project: &Entity<Project>,
serialized: BTreeMap<Arc<Path>, Vec<SerializedBookmark>>,
cx: &mut TestAppContext,
) {
project
.update(cx, |project, cx| {
project.bookmark_store().update(cx, |store, cx| {
store.load_serialized_bookmarks(serialized, cx)
})
})
.await
.expect("with_serialized_bookmarks should succeed");
}
fn clear_bookmarks(project: &Entity<Project>, cx: &mut TestAppContext) {
project.update(cx, |project, cx| {
project.bookmark_store().update(cx, |store, cx| {
store.clear_bookmarks(cx);
});
});
}
fn assert_bookmark_rows(
bookmarks: &BTreeMap<Arc<Path>, Vec<SerializedBookmark>>,
path: &str,
expected_rows: &[u32],
) {
let path = project_path(path);
let file_bookmarks = bookmarks
.get(&path)
.unwrap_or_else(|| panic!("Expected bookmarks for {}", path.display()));
let rows: Vec<u32> = file_bookmarks.iter().map(|b| b.0).collect();
assert_eq!(rows, expected_rows, "Bookmark rows for {}", path.display());
}
#[gpui::test]
async fn test_all_serialized_bookmarks_empty(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(path!("/project"), json!({"file1.rs": "line1\nline2\n"}))
.await;
let project = Project::test(fs, [path!("/project").as_ref()], cx).await;
assert!(get_all_bookmarks(&project, cx).is_empty());
}
#[gpui::test]
async fn test_all_serialized_bookmarks_single_file(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(
path!("/project"),
json!({"file1.rs": "line1\nline2\nline3\nline4\nline5\n"}),
)
.await;
let project = Project::test(fs, [path!("/project").as_ref()], cx).await;
let buffer = open_buffer(&project, path!("/project/file1.rs"), cx).await;
add_bookmarks(&project, &buffer, &[0, 2], cx);
let bookmarks = get_all_bookmarks(&project, cx);
assert_eq!(bookmarks.len(), 1);
assert_bookmark_rows(&bookmarks, path!("/project/file1.rs"), &[0, 2]);
}
#[gpui::test]
async fn test_all_serialized_bookmarks_multiple_files(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(
path!("/project"),
json!({
"file1.rs": "line1\nline2\nline3\n",
"file2.rs": "lineA\nlineB\nlineC\nlineD\n",
"file3.rs": "single line"
}),
)
.await;
let project = Project::test(fs, [path!("/project").as_ref()], cx).await;
let buffer1 = open_buffer(&project, path!("/project/file1.rs"), cx).await;
let buffer2 = open_buffer(&project, path!("/project/file2.rs"), cx).await;
let _buffer3 = open_buffer(&project, path!("/project/file3.rs"), cx).await;
add_bookmarks(&project, &buffer1, &[1], cx);
add_bookmarks(&project, &buffer2, &[0, 3], cx);
let bookmarks = get_all_bookmarks(&project, cx);
assert_eq!(bookmarks.len(), 2);
assert_bookmark_rows(&bookmarks, path!("/project/file1.rs"), &[1]);
assert_bookmark_rows(&bookmarks, path!("/project/file2.rs"), &[0, 3]);
assert!(
!bookmarks.contains_key(&project_path(path!("/project/file3.rs"))),
"file3.rs should have no bookmarks"
);
}
#[gpui::test]
async fn test_all_serialized_bookmarks_after_toggle_off(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(
path!("/project"),
json!({"file1.rs": "line1\nline2\nline3\n"}),
)
.await;
let project = Project::test(fs, [path!("/project").as_ref()], cx).await;
let buffer = open_buffer(&project, path!("/project/file1.rs"), cx).await;
add_bookmarks(&project, &buffer, &[1], cx);
assert_eq!(get_all_bookmarks(&project, cx).len(), 1);
// Toggle same row again to remove it
add_bookmarks(&project, &buffer, &[1], cx);
assert!(get_all_bookmarks(&project, cx).is_empty());
}
#[gpui::test]
async fn test_all_serialized_bookmarks_with_clear(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(
path!("/project"),
json!({
"file1.rs": "line1\nline2\nline3\n",
"file2.rs": "lineA\nlineB\n"
}),
)
.await;
let project = Project::test(fs, [path!("/project").as_ref()], cx).await;
let buffer1 = open_buffer(&project, path!("/project/file1.rs"), cx).await;
let buffer2 = open_buffer(&project, path!("/project/file2.rs"), cx).await;
add_bookmarks(&project, &buffer1, &[0], cx);
add_bookmarks(&project, &buffer2, &[1], cx);
assert_eq!(get_all_bookmarks(&project, cx).len(), 2);
clear_bookmarks(&project, cx);
assert!(get_all_bookmarks(&project, cx).is_empty());
}
#[gpui::test]
async fn test_all_serialized_bookmarks_returns_sorted_by_path(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(
path!("/project"),
json!({"b.rs": "line1\n", "a.rs": "line1\n", "c.rs": "line1\n"}),
)
.await;
let project = Project::test(fs, [path!("/project").as_ref()], cx).await;
let buffer_b = open_buffer(&project, path!("/project/b.rs"), cx).await;
let buffer_a = open_buffer(&project, path!("/project/a.rs"), cx).await;
let buffer_c = open_buffer(&project, path!("/project/c.rs"), cx).await;
add_bookmarks(&project, &buffer_b, &[0], cx);
add_bookmarks(&project, &buffer_a, &[0], cx);
add_bookmarks(&project, &buffer_c, &[0], cx);
let paths: Vec<_> = get_all_bookmarks(&project, cx).keys().cloned().collect();
assert_eq!(
paths,
[
project_path(path!("/project/a.rs")),
project_path(path!("/project/b.rs")),
project_path(path!("/project/c.rs")),
]
);
}
#[gpui::test]
async fn test_all_serialized_bookmarks_deduplicates_same_row(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(
path!("/project"),
json!({"file1.rs": "line1\nline2\nline3\nline4\n"}),
)
.await;
let project = Project::test(fs, [path!("/project").as_ref()], cx).await;
let buffer = open_buffer(&project, path!("/project/file1.rs"), cx).await;
add_bookmarks(&project, &buffer, &[1, 2], cx);
let bookmarks = get_all_bookmarks(&project, cx);
assert_bookmark_rows(&bookmarks, path!("/project/file1.rs"), &[1, 2]);
// Verify no duplicates
let rows: Vec<u32> = bookmarks
.get(&project_path(path!("/project/file1.rs")))
.unwrap()
.iter()
.map(|b| b.0)
.collect();
let mut deduped = rows.clone();
deduped.dedup();
assert_eq!(rows, deduped);
}
#[gpui::test]
async fn test_with_serialized_bookmarks_restores_bookmarks(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(
path!("/project"),
json!({
"file1.rs": "line1\nline2\nline3\nline4\nline5\n",
"file2.rs": "aaa\nbbb\nccc\n"
}),
)
.await;
let project = Project::test(fs, [path!("/project").as_ref()], cx).await;
let serialized = build_serialized(&[
(path!("/project/file1.rs"), &[0, 3]),
(path!("/project/file2.rs"), &[1]),
]);
restore_bookmarks(&project, serialized, cx).await;
let restored = get_all_bookmarks(&project, cx);
assert_eq!(restored.len(), 2);
assert_bookmark_rows(&restored, path!("/project/file1.rs"), &[0, 3]);
assert_bookmark_rows(&restored, path!("/project/file2.rs"), &[1]);
}
#[gpui::test]
async fn test_with_serialized_bookmarks_skips_out_of_range_rows(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
// 3 lines: rows 0, 1, 2
fs.insert_tree(
path!("/project"),
json!({"file1.rs": "line1\nline2\nline3"}),
)
.await;
let project = Project::test(fs, [path!("/project").as_ref()], cx).await;
let serialized = build_serialized(&[(path!("/project/file1.rs"), &[1, 100, 2])]);
restore_bookmarks(&project, serialized, cx).await;
// Before resolution, unloaded bookmarks are stored as-is
let unresolved = get_all_bookmarks(&project, cx);
assert_bookmark_rows(&unresolved, path!("/project/file1.rs"), &[1, 2, 100]);
// Open the buffer to trigger lazy resolution
let buffer = open_buffer(&project, path!("/project/file1.rs"), cx).await;
project.update(cx, |project, cx| {
let buffer_snapshot = buffer.read(cx).snapshot();
project.bookmark_store().update(cx, |store, cx| {
store.bookmarks_for_buffer(
buffer.clone(),
buffer_snapshot.anchor_before(0)
..buffer_snapshot.anchor_after(buffer_snapshot.len()),
&buffer_snapshot,
cx,
);
});
});
// After resolution, out-of-range rows are filtered
let restored = get_all_bookmarks(&project, cx);
assert_bookmark_rows(&restored, path!("/project/file1.rs"), &[1, 2]);
}
#[gpui::test]
async fn test_with_serialized_bookmarks_skips_empty_entries(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(
path!("/project"),
json!({"file1.rs": "line1\nline2\n", "file2.rs": "aaa\nbbb\n"}),
)
.await;
let project = Project::test(fs, [path!("/project").as_ref()], cx).await;
let mut serialized = build_serialized(&[(path!("/project/file1.rs"), &[0])]);
serialized.insert(project_path(path!("/project/file2.rs")), vec![]);
restore_bookmarks(&project, serialized, cx).await;
let restored = get_all_bookmarks(&project, cx);
assert_eq!(restored.len(), 1);
assert!(restored.contains_key(&project_path(path!("/project/file1.rs"))));
assert!(!restored.contains_key(&project_path(path!("/project/file2.rs"))));
}
#[gpui::test]
async fn test_with_serialized_bookmarks_all_out_of_range_produces_no_entry(
cx: &mut TestAppContext,
) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(path!("/project"), json!({"tiny.rs": "x"}))
.await;
let project = Project::test(fs, [path!("/project").as_ref()], cx).await;
let serialized = build_serialized(&[(path!("/project/tiny.rs"), &[5, 10])]);
restore_bookmarks(&project, serialized, cx).await;
// Before resolution, unloaded bookmarks are stored as-is
let unresolved = get_all_bookmarks(&project, cx);
assert_eq!(unresolved.len(), 1);
// Open the buffer to trigger lazy resolution
let buffer = open_buffer(&project, path!("/project/tiny.rs"), cx).await;
project.update(cx, |project, cx| {
let buffer_snapshot = buffer.read(cx).snapshot();
project.bookmark_store().update(cx, |store, cx| {
store.bookmarks_for_buffer(
buffer.clone(),
buffer_snapshot.anchor_before(0)
..buffer_snapshot.anchor_after(buffer_snapshot.len()),
&buffer_snapshot,
cx,
);
});
});
// After resolution, all out-of-range rows are filtered away
assert!(get_all_bookmarks(&project, cx).is_empty());
}
#[gpui::test]
async fn test_with_serialized_bookmarks_replaces_existing(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(
path!("/project"),
json!({"file1.rs": "aaa\nbbb\nccc\nddd\n"}),
)
.await;
let project = Project::test(fs, [path!("/project").as_ref()], cx).await;
let buffer = open_buffer(&project, path!("/project/file1.rs"), cx).await;
add_bookmarks(&project, &buffer, &[0], cx);
assert_bookmark_rows(
&get_all_bookmarks(&project, cx),
path!("/project/file1.rs"),
&[0],
);
// Restoring different bookmarks should replace, not merge
let serialized = build_serialized(&[(path!("/project/file1.rs"), &[2, 3])]);
restore_bookmarks(&project, serialized, cx).await;
let after = get_all_bookmarks(&project, cx);
assert_eq!(after.len(), 1);
assert_bookmark_rows(&after, path!("/project/file1.rs"), &[2, 3]);
}
#[gpui::test]
async fn test_serialize_deserialize_round_trip(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(
path!("/project"),
json!({
"alpha.rs": "fn main() {\n println!(\"hello\");\n return;\n}\n",
"beta.rs": "use std::io;\nfn read() {}\nfn write() {}\n"
}),
)
.await;
let project = Project::test(fs, [path!("/project").as_ref()], cx).await;
let buffer_alpha = open_buffer(&project, path!("/project/alpha.rs"), cx).await;
let buffer_beta = open_buffer(&project, path!("/project/beta.rs"), cx).await;
add_bookmarks(&project, &buffer_alpha, &[0, 2, 3], cx);
add_bookmarks(&project, &buffer_beta, &[1], cx);
// Serialize
let serialized = get_all_bookmarks(&project, cx);
assert_eq!(serialized.len(), 2);
assert_bookmark_rows(&serialized, path!("/project/alpha.rs"), &[0, 2, 3]);
assert_bookmark_rows(&serialized, path!("/project/beta.rs"), &[1]);
// Clear and restore
clear_bookmarks(&project, cx);
assert!(get_all_bookmarks(&project, cx).is_empty());
restore_bookmarks(&project, serialized, cx).await;
let restored = get_all_bookmarks(&project, cx);
assert_eq!(restored.len(), 2);
assert_bookmark_rows(&restored, path!("/project/alpha.rs"), &[0, 2, 3]);
assert_bookmark_rows(&restored, path!("/project/beta.rs"), &[1]);
}
#[gpui::test]
async fn test_round_trip_preserves_bookmarks_after_file_edit(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(
path!("/project"),
json!({"file.rs": "aaa\nbbb\nccc\nddd\neee\n"}),
)
.await;
let project = Project::test(fs, [path!("/project").as_ref()], cx).await;
let buffer = open_buffer(&project, path!("/project/file.rs"), cx).await;
add_bookmarks(&project, &buffer, &[1, 3], cx);
// Insert a line at the beginning, shifting bookmarks down by 1
buffer.update(cx, |buffer, cx| {
buffer.edit([(0..0, "new_first_line\n")], None, cx);
});
let serialized = get_all_bookmarks(&project, cx);
assert_bookmark_rows(&serialized, path!("/project/file.rs"), &[2, 4]);
// Clear and restore
clear_bookmarks(&project, cx);
restore_bookmarks(&project, serialized, cx).await;
let restored = get_all_bookmarks(&project, cx);
assert_bookmark_rows(&restored, path!("/project/file.rs"), &[2, 4]);
}
#[gpui::test]
async fn test_file_deletion_removes_bookmarks(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(
path!("/project"),
json!({
"file1.rs": "aaa\nbbb\nccc\n",
"file2.rs": "ddd\neee\nfff\n"
}),
)
.await;
let project = Project::test(fs.clone(), [path!("/project").as_ref()], cx).await;
let buffer1 = open_buffer(&project, path!("/project/file1.rs"), cx).await;
let buffer2 = open_buffer(&project, path!("/project/file2.rs"), cx).await;
add_bookmarks(&project, &buffer1, &[0, 2], cx);
add_bookmarks(&project, &buffer2, &[1], cx);
assert_eq!(get_all_bookmarks(&project, cx).len(), 2);
// Delete file1.rs
fs.remove_file(path!("/project/file1.rs").as_ref(), Default::default())
.await
.unwrap();
cx.executor().run_until_parked();
// file1.rs bookmarks should be gone, file2.rs bookmarks preserved
let bookmarks = get_all_bookmarks(&project, cx);
assert_eq!(bookmarks.len(), 1);
assert!(!bookmarks.contains_key(&project_path(path!("/project/file1.rs"))));
assert_bookmark_rows(&bookmarks, path!("/project/file2.rs"), &[1]);
}
#[gpui::test]
async fn test_deleting_all_bookmarked_files_clears_store(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(
path!("/project"),
json!({
"file1.rs": "aaa\nbbb\n",
"file2.rs": "ccc\nddd\n"
}),
)
.await;
let project = Project::test(fs.clone(), [path!("/project").as_ref()], cx).await;
let buffer1 = open_buffer(&project, path!("/project/file1.rs"), cx).await;
let buffer2 = open_buffer(&project, path!("/project/file2.rs"), cx).await;
add_bookmarks(&project, &buffer1, &[0], cx);
add_bookmarks(&project, &buffer2, &[1], cx);
assert_eq!(get_all_bookmarks(&project, cx).len(), 2);
// Delete both files
fs.remove_file(path!("/project/file1.rs").as_ref(), Default::default())
.await
.unwrap();
fs.remove_file(path!("/project/file2.rs").as_ref(), Default::default())
.await
.unwrap();
cx.executor().run_until_parked();
assert!(get_all_bookmarks(&project, cx).is_empty());
}
#[gpui::test]
async fn test_file_rename_re_keys_bookmarks(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(path!("/project"), json!({"old_name.rs": "aaa\nbbb\nccc\n"}))
.await;
let project = Project::test(fs.clone(), [path!("/project").as_ref()], cx).await;
let buffer = open_buffer(&project, path!("/project/old_name.rs"), cx).await;
add_bookmarks(&project, &buffer, &[0, 2], cx);
assert_bookmark_rows(
&get_all_bookmarks(&project, cx),
path!("/project/old_name.rs"),
&[0, 2],
);
// Rename the file
fs.rename(
path!("/project/old_name.rs").as_ref(),
path!("/project/new_name.rs").as_ref(),
Default::default(),
)
.await
.unwrap();
cx.executor().run_until_parked();
let bookmarks = get_all_bookmarks(&project, cx);
assert_eq!(bookmarks.len(), 1);
assert!(!bookmarks.contains_key(&project_path(path!("/project/old_name.rs"))));
assert_bookmark_rows(&bookmarks, path!("/project/new_name.rs"), &[0, 2]);
}
#[gpui::test]
async fn test_file_rename_preserves_other_bookmarks(cx: &mut TestAppContext) {
init_test(cx);
cx.executor().allow_parking();
let fs = fs::FakeFs::new(cx.executor());
fs.insert_tree(
path!("/project"),
json!({
"rename_me.rs": "aaa\nbbb\n",
"untouched.rs": "ccc\nddd\neee\n"
}),
)
.await;
let project = Project::test(fs.clone(), [path!("/project").as_ref()], cx).await;
let buffer_rename = open_buffer(&project, path!("/project/rename_me.rs"), cx).await;
let buffer_other = open_buffer(&project, path!("/project/untouched.rs"), cx).await;
add_bookmarks(&project, &buffer_rename, &[1], cx);
add_bookmarks(&project, &buffer_other, &[0, 2], cx);
fs.rename(
path!("/project/rename_me.rs").as_ref(),
path!("/project/renamed.rs").as_ref(),
Default::default(),
)
.await
.unwrap();
cx.executor().run_until_parked();
let bookmarks = get_all_bookmarks(&project, cx);
assert_eq!(bookmarks.len(), 2);
assert_bookmark_rows(&bookmarks, path!("/project/renamed.rs"), &[1]);
assert_bookmark_rows(&bookmarks, path!("/project/untouched.rs"), &[0, 2]);
}
}