editor: Fix copy file actions not working in remote environments (#43362)
Closes #42500 Release Notes: - Fixed all three editor actions not working in remote environments - `editor: copy file name` - `editor: copy file location` - `editor: copy file name without extension` Here's the before/after: https://github.com/user-attachments/assets/bfb03e99-2e1a-47a2-bd26-280180154fe3
This commit is contained in:
@@ -7,8 +7,9 @@ use editor::{
|
||||
DocumentColorsRenderMode, Editor, FETCH_COLORS_DEBOUNCE_TIMEOUT, MultiBufferOffset, RowInfo,
|
||||
SelectionEffects,
|
||||
actions::{
|
||||
ConfirmCodeAction, ConfirmCompletion, ConfirmRename, ContextMenuFirst,
|
||||
ExpandMacroRecursively, MoveToEnd, Redo, Rename, SelectAll, ToggleCodeActions, Undo,
|
||||
ConfirmCodeAction, ConfirmCompletion, ConfirmRename, ContextMenuFirst, CopyFileLocation,
|
||||
CopyFileName, CopyFileNameWithoutExtension, ExpandMacroRecursively, MoveToEnd, Redo,
|
||||
Rename, SelectAll, ToggleCodeActions, Undo,
|
||||
},
|
||||
test::{
|
||||
editor_test_context::{AssertionContextManager, EditorTestContext},
|
||||
@@ -4269,6 +4270,288 @@ async fn test_client_can_query_lsp_ext(cx_a: &mut TestAppContext, cx_b: &mut Tes
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_copy_file_name_without_extension(
|
||||
cx_a: &mut TestAppContext,
|
||||
cx_b: &mut TestAppContext,
|
||||
) {
|
||||
let mut server = TestServer::start(cx_a.executor()).await;
|
||||
let client_a = server.create_client(cx_a, "user_a").await;
|
||||
let client_b = server.create_client(cx_b, "user_b").await;
|
||||
server
|
||||
.create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
|
||||
.await;
|
||||
|
||||
cx_b.update(editor::init);
|
||||
|
||||
client_a
|
||||
.fs()
|
||||
.insert_tree(
|
||||
path!("/root"),
|
||||
json!({
|
||||
"src": {
|
||||
"main.rs": indoc! {"
|
||||
fn main() {
|
||||
println!(\"Hello, world!\");
|
||||
}
|
||||
"},
|
||||
}
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let (project_a, worktree_id) = client_a.build_local_project(path!("/root"), cx_a).await;
|
||||
let active_call_a = cx_a.read(ActiveCall::global);
|
||||
let project_id = active_call_a
|
||||
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let project_b = client_b.join_remote_project(project_id, cx_b).await;
|
||||
|
||||
let (workspace_a, cx_a) = client_a.build_workspace(&project_a, cx_a);
|
||||
let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b);
|
||||
|
||||
let editor_a = workspace_a
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.open_path(
|
||||
(worktree_id, rel_path("src/main.rs")),
|
||||
None,
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.downcast::<Editor>()
|
||||
.unwrap();
|
||||
|
||||
let editor_b = workspace_b
|
||||
.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.open_path(
|
||||
(worktree_id, rel_path("src/main.rs")),
|
||||
None,
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.downcast::<Editor>()
|
||||
.unwrap();
|
||||
|
||||
cx_a.run_until_parked();
|
||||
cx_b.run_until_parked();
|
||||
|
||||
editor_a.update_in(cx_a, |editor, window, cx| {
|
||||
editor.copy_file_name_without_extension(&CopyFileNameWithoutExtension, window, cx);
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
cx_a.read_from_clipboard().and_then(|item| item.text()),
|
||||
Some("main".to_string())
|
||||
);
|
||||
|
||||
editor_b.update_in(cx_b, |editor, window, cx| {
|
||||
editor.copy_file_name_without_extension(&CopyFileNameWithoutExtension, window, cx);
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
cx_b.read_from_clipboard().and_then(|item| item.text()),
|
||||
Some("main".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_copy_file_name(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
|
||||
let mut server = TestServer::start(cx_a.executor()).await;
|
||||
let client_a = server.create_client(cx_a, "user_a").await;
|
||||
let client_b = server.create_client(cx_b, "user_b").await;
|
||||
server
|
||||
.create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
|
||||
.await;
|
||||
|
||||
cx_b.update(editor::init);
|
||||
|
||||
client_a
|
||||
.fs()
|
||||
.insert_tree(
|
||||
path!("/root"),
|
||||
json!({
|
||||
"src": {
|
||||
"main.rs": indoc! {"
|
||||
fn main() {
|
||||
println!(\"Hello, world!\");
|
||||
}
|
||||
"},
|
||||
}
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let (project_a, worktree_id) = client_a.build_local_project(path!("/root"), cx_a).await;
|
||||
let active_call_a = cx_a.read(ActiveCall::global);
|
||||
let project_id = active_call_a
|
||||
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let project_b = client_b.join_remote_project(project_id, cx_b).await;
|
||||
|
||||
let (workspace_a, cx_a) = client_a.build_workspace(&project_a, cx_a);
|
||||
let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b);
|
||||
|
||||
let editor_a = workspace_a
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.open_path(
|
||||
(worktree_id, rel_path("src/main.rs")),
|
||||
None,
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.downcast::<Editor>()
|
||||
.unwrap();
|
||||
|
||||
let editor_b = workspace_b
|
||||
.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.open_path(
|
||||
(worktree_id, rel_path("src/main.rs")),
|
||||
None,
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.downcast::<Editor>()
|
||||
.unwrap();
|
||||
|
||||
cx_a.run_until_parked();
|
||||
cx_b.run_until_parked();
|
||||
|
||||
editor_a.update_in(cx_a, |editor, window, cx| {
|
||||
editor.copy_file_name(&CopyFileName, window, cx);
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
cx_a.read_from_clipboard().and_then(|item| item.text()),
|
||||
Some("main.rs".to_string())
|
||||
);
|
||||
|
||||
editor_b.update_in(cx_b, |editor, window, cx| {
|
||||
editor.copy_file_name(&CopyFileName, window, cx);
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
cx_b.read_from_clipboard().and_then(|item| item.text()),
|
||||
Some("main.rs".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_copy_file_location(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
|
||||
let mut server = TestServer::start(cx_a.executor()).await;
|
||||
let client_a = server.create_client(cx_a, "user_a").await;
|
||||
let client_b = server.create_client(cx_b, "user_b").await;
|
||||
server
|
||||
.create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
|
||||
.await;
|
||||
|
||||
cx_b.update(editor::init);
|
||||
|
||||
client_a
|
||||
.fs()
|
||||
.insert_tree(
|
||||
path!("/root"),
|
||||
json!({
|
||||
"src": {
|
||||
"main.rs": indoc! {"
|
||||
fn main() {
|
||||
println!(\"Hello, world!\");
|
||||
}
|
||||
"},
|
||||
}
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let (project_a, worktree_id) = client_a.build_local_project(path!("/root"), cx_a).await;
|
||||
let active_call_a = cx_a.read(ActiveCall::global);
|
||||
let project_id = active_call_a
|
||||
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let project_b = client_b.join_remote_project(project_id, cx_b).await;
|
||||
|
||||
let (workspace_a, cx_a) = client_a.build_workspace(&project_a, cx_a);
|
||||
let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b);
|
||||
|
||||
let editor_a = workspace_a
|
||||
.update_in(cx_a, |workspace, window, cx| {
|
||||
workspace.open_path(
|
||||
(worktree_id, rel_path("src/main.rs")),
|
||||
None,
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.downcast::<Editor>()
|
||||
.unwrap();
|
||||
|
||||
let editor_b = workspace_b
|
||||
.update_in(cx_b, |workspace, window, cx| {
|
||||
workspace.open_path(
|
||||
(worktree_id, rel_path("src/main.rs")),
|
||||
None,
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.downcast::<Editor>()
|
||||
.unwrap();
|
||||
|
||||
cx_a.run_until_parked();
|
||||
cx_b.run_until_parked();
|
||||
|
||||
editor_a.update_in(cx_a, |editor, window, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.select_ranges([MultiBufferOffset(16)..MultiBufferOffset(16)]);
|
||||
});
|
||||
editor.copy_file_location(&CopyFileLocation, window, cx);
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
cx_a.read_from_clipboard().and_then(|item| item.text()),
|
||||
Some(format!("{}:2", path!("src/main.rs")))
|
||||
);
|
||||
|
||||
editor_b.update_in(cx_b, |editor, window, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| {
|
||||
s.select_ranges([MultiBufferOffset(16)..MultiBufferOffset(16)]);
|
||||
});
|
||||
editor.copy_file_location(&CopyFileLocation, window, cx);
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
cx_b.read_from_clipboard().and_then(|item| item.text()),
|
||||
Some(format!("{}:2", path!("src/main.rs")))
|
||||
);
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn tab_undo_assert(
|
||||
cx_a: &mut EditorTestContext,
|
||||
|
||||
+17
-10
@@ -20234,18 +20234,20 @@ impl Editor {
|
||||
_: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if let Some(file) = self.target_file(cx)
|
||||
&& let Some(file_stem) = file.path().file_stem()
|
||||
{
|
||||
if let Some(file_stem) = self.active_excerpt(cx).and_then(|(_, buffer, _)| {
|
||||
let file = buffer.read(cx).file()?;
|
||||
file.path().file_stem()
|
||||
}) {
|
||||
cx.write_to_clipboard(ClipboardItem::new_string(file_stem.to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copy_file_name(&mut self, _: &CopyFileName, _: &mut Window, cx: &mut Context<Self>) {
|
||||
if let Some(file) = self.target_file(cx)
|
||||
&& let Some(name) = file.path().file_name()
|
||||
{
|
||||
cx.write_to_clipboard(ClipboardItem::new_string(name.to_string()));
|
||||
if let Some(file_name) = self.active_excerpt(cx).and_then(|(_, buffer, _)| {
|
||||
let file = buffer.read(cx).file()?;
|
||||
Some(file.file_name(cx))
|
||||
}) {
|
||||
cx.write_to_clipboard(ClipboardItem::new_string(file_name.to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20519,9 +20521,14 @@ impl Editor {
|
||||
.start
|
||||
.row
|
||||
+ 1;
|
||||
if let Some(file) = self.target_file(cx) {
|
||||
let path = file.path().display(file.path_style(cx));
|
||||
cx.write_to_clipboard(ClipboardItem::new_string(format!("{path}:{selection}")));
|
||||
if let Some(file_location) = self.active_excerpt(cx).and_then(|(_, buffer, _)| {
|
||||
let project = self.project()?.read(cx);
|
||||
let file = buffer.read(cx).file()?;
|
||||
let path = file.path().display(project.path_style(cx));
|
||||
|
||||
Some(format!("{path}:{selection}"))
|
||||
}) {
|
||||
cx.write_to_clipboard(ClipboardItem::new_string(file_location));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user