Properly open worktrees when cmd-clicking in terminal or on inlay hints (#19280)

* uses the state that's synced, to fetch the language server name
* uses proper, canonicalized path when creating a remote ssh worktree,
otherwise `~/foo/something` stays unexpanded

Release Notes:

- N/A
This commit is contained in:
Kirill Bulatov 2024-10-16 18:12:36 +03:00 committed by GitHub
parent bcdb10b3cb
commit 834d50f0db
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 43 additions and 47 deletions

View file

@ -96,7 +96,9 @@ use language::{
CursorShape, Diagnostic, Documentation, IndentKind, IndentSize, Language, OffsetRangeExt, CursorShape, Diagnostic, Documentation, IndentKind, IndentSize, Language, OffsetRangeExt,
Point, Selection, SelectionGoal, TransactionId, Point, Selection, SelectionGoal, TransactionId,
}; };
use language::{point_to_lsp, BufferRow, CharClassifier, Runnable, RunnableRange}; use language::{
point_to_lsp, BufferRow, CharClassifier, LanguageServerName, Runnable, RunnableRange,
};
use linked_editing_ranges::refresh_linked_ranges; use linked_editing_ranges::refresh_linked_ranges;
pub use proposed_changes_editor::{ pub use proposed_changes_editor::{
ProposedChangesBuffer, ProposedChangesEditor, ProposedChangesEditorToolbar, ProposedChangesBuffer, ProposedChangesEditor, ProposedChangesEditorToolbar,
@ -9893,21 +9895,19 @@ impl Editor {
&self, &self,
lsp_location: lsp::Location, lsp_location: lsp::Location,
server_id: LanguageServerId, server_id: LanguageServerId,
cx: &mut ViewContext<Editor>, cx: &mut ViewContext<Self>,
) -> Task<anyhow::Result<Option<Location>>> { ) -> Task<anyhow::Result<Option<Location>>> {
let Some(project) = self.project.clone() else { let Some(project) = self.project.clone() else {
return Task::Ready(Some(Ok(None))); return Task::Ready(Some(Ok(None)));
}; };
cx.spawn(move |editor, mut cx| async move { cx.spawn(move |editor, mut cx| async move {
let location_task = editor.update(&mut cx, |editor, cx| { let location_task = editor.update(&mut cx, |_, cx| {
project.update(cx, |project, cx| { project.update(cx, |project, cx| {
let language_server_name = let language_server_name = project
editor.buffer.read(cx).as_singleton().and_then(|buffer| { .language_server_statuses(cx)
project .find(|(id, _)| server_id == *id)
.language_server_for_buffer(buffer.read(cx), server_id, cx) .map(|(_, status)| LanguageServerName::from(status.name.as_str()));
.map(|(lsp_adapter, _)| lsp_adapter.name.clone())
});
language_server_name.map(|language_server_name| { language_server_name.map(|language_server_name| {
project.open_local_buffer_via_lsp( project.open_local_buffer_via_lsp(
lsp_location.uri.clone(), lsp_location.uri.clone(),

View file

@ -3503,7 +3503,7 @@ impl LspStore {
language_server_name: LanguageServerName, language_server_name: LanguageServerName,
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) -> Task<Result<Model<Buffer>>> { ) -> Task<Result<Model<Buffer>>> {
cx.spawn(move |this, mut cx| async move { cx.spawn(move |lsp_store, mut cx| async move {
// Escape percent-encoded string. // Escape percent-encoded string.
let current_scheme = abs_path.scheme().to_owned(); let current_scheme = abs_path.scheme().to_owned();
let _ = abs_path.set_scheme("file"); let _ = abs_path.set_scheme("file");
@ -3512,9 +3512,9 @@ impl LspStore {
.to_file_path() .to_file_path()
.map_err(|_| anyhow!("can't convert URI to path"))?; .map_err(|_| anyhow!("can't convert URI to path"))?;
let p = abs_path.clone(); let p = abs_path.clone();
let yarn_worktree = this let yarn_worktree = lsp_store
.update(&mut cx, move |this, cx| { .update(&mut cx, move |lsp_store, cx| match lsp_store.as_local() {
this.as_local().unwrap().yarn.update(cx, |_, cx| { Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
cx.spawn(|this, mut cx| async move { cx.spawn(|this, mut cx| async move {
let t = this let t = this
.update(&mut cx, |this, cx| { .update(&mut cx, |this, cx| {
@ -3523,7 +3523,8 @@ impl LspStore {
.ok()?; .ok()?;
t.await t.await
}) })
}) }),
None => Task::ready(None),
})? })?
.await; .await;
let (worktree_root_target, known_relative_path) = let (worktree_root_target, known_relative_path) =
@ -3533,8 +3534,8 @@ impl LspStore {
(Arc::<Path>::from(abs_path.as_path()), None) (Arc::<Path>::from(abs_path.as_path()), None)
}; };
let (worktree, relative_path) = if let Some(result) = let (worktree, relative_path) = if let Some(result) =
this.update(&mut cx, |this, cx| { lsp_store.update(&mut cx, |lsp_store, cx| {
this.worktree_store.update(cx, |worktree_store, cx| { lsp_store.worktree_store.update(cx, |worktree_store, cx| {
worktree_store.find_worktree(&worktree_root_target, cx) worktree_store.find_worktree(&worktree_root_target, cx)
}) })
})? { })? {
@ -3542,22 +3543,25 @@ impl LspStore {
known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1)); known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
(result.0, relative_path) (result.0, relative_path)
} else { } else {
let worktree = this let worktree = lsp_store
.update(&mut cx, |this, cx| { .update(&mut cx, |lsp_store, cx| {
this.worktree_store.update(cx, |worktree_store, cx| { lsp_store.worktree_store.update(cx, |worktree_store, cx| {
worktree_store.create_worktree(&worktree_root_target, false, cx) worktree_store.create_worktree(&worktree_root_target, false, cx)
}) })
})? })?
.await?; .await?;
this.update(&mut cx, |this, cx| { if worktree.update(&mut cx, |worktree, _| worktree.is_local())? {
this.register_language_server( lsp_store
worktree.read(cx).id(), .update(&mut cx, |lsp_store, cx| {
language_server_name, lsp_store.register_language_server(
language_server_id, worktree.read(cx).id(),
) language_server_name,
}) language_server_id,
.ok(); )
let worktree_root = worktree.update(&mut cx, |this, _| this.abs_path())?; })
.ok();
}
let worktree_root = worktree.update(&mut cx, |worktree, _| worktree.abs_path())?;
let relative_path = if let Some(known_path) = known_relative_path { let relative_path = if let Some(known_path) = known_relative_path {
known_path known_path
} else { } else {
@ -3569,12 +3573,13 @@ impl LspStore {
worktree_id: worktree.update(&mut cx, |worktree, _| worktree.id())?, worktree_id: worktree.update(&mut cx, |worktree, _| worktree.id())?,
path: relative_path, path: relative_path,
}; };
this.update(&mut cx, |this, cx| { lsp_store
this.buffer_store().update(cx, |buffer_store, cx| { .update(&mut cx, |lsp_store, cx| {
buffer_store.open_buffer(project_path, cx) lsp_store.buffer_store().update(cx, |buffer_store, cx| {
}) buffer_store.open_buffer(project_path, cx)
})? })
.await })?
.await
}) })
} }

View file

@ -3979,17 +3979,6 @@ impl Project {
.read(cx) .read(cx)
.language_servers_for_buffer(buffer, cx) .language_servers_for_buffer(buffer, cx)
} }
pub fn language_server_for_buffer<'a>(
&'a self,
buffer: &'a Buffer,
server_id: LanguageServerId,
cx: &'a AppContext,
) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
self.lsp_store
.read(cx)
.language_server_for_buffer(buffer, server_id, cx)
}
} }
fn deserialize_code_actions(code_actions: &HashMap<String, bool>) -> Vec<lsp::CodeActionKind> { fn deserialize_code_actions(code_actions: &HashMap<String, bool>) -> Vec<lsp::CodeActionKind> {

View file

@ -280,7 +280,7 @@ impl WorktreeStore {
id: response.worktree_id, id: response.worktree_id,
root_name, root_name,
visible, visible,
abs_path, abs_path: response.canonicalized_path,
}, },
client, client,
cx, cx,

View file

@ -2464,6 +2464,7 @@ message AddWorktree {
message AddWorktreeResponse { message AddWorktreeResponse {
uint64 worktree_id = 1; uint64 worktree_id = 1;
string canonicalized_path = 2;
} }
message UpdateUserSettings { message UpdateUserSettings {

View file

@ -275,7 +275,7 @@ impl HeadlessProject {
let worktree = this let worktree = this
.update(&mut cx.clone(), |this, _| { .update(&mut cx.clone(), |this, _| {
Worktree::local( Worktree::local(
Arc::from(canonicalized), Arc::from(canonicalized.as_path()),
message.payload.visible, message.payload.visible,
this.fs.clone(), this.fs.clone(),
this.next_entry_id.clone(), this.next_entry_id.clone(),
@ -287,6 +287,7 @@ impl HeadlessProject {
let response = this.update(&mut cx, |_, cx| { let response = this.update(&mut cx, |_, cx| {
worktree.update(cx, |worktree, _| proto::AddWorktreeResponse { worktree.update(cx, |worktree, _| proto::AddWorktreeResponse {
worktree_id: worktree.id().to_proto(), worktree_id: worktree.id().to_proto(),
canonicalized_path: canonicalized.to_string_lossy().to_string(),
}) })
})?; })?;