Start to split out initialization and registration (#21787)
Still TODO: * [x] Factor out `start_language_server` so we can call it on register (instead of on detect language) * [x] Only call register in singleton editors (or when editing/go-to-definition etc. in a multibuffer?) * [x] Refcount on register so we can unregister when no buffer remain * [ ] (maybe) Stop language servers that are no longer needed after some time Release Notes: - Fixed language servers starting when doing project search - Fixed high CPU usage when ignoring warnings in the diagnostics view --------- Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Co-authored-by: Cole <cole@zed.dev>
This commit is contained in:
parent
de89f8cf83
commit
13a81e454a
19 changed files with 2200 additions and 1848 deletions
|
@ -5113,9 +5113,11 @@ fn make_lsp_adapter_delegate(
|
|||
return Ok(None::<Arc<dyn LspAdapterDelegate>>);
|
||||
};
|
||||
let http_client = project.client().http_client().clone();
|
||||
project.lsp_store().update(cx, |lsp_store, cx| {
|
||||
project.lsp_store().update(cx, |_, cx| {
|
||||
Ok(Some(LocalLspAdapterDelegate::new(
|
||||
lsp_store,
|
||||
project.languages().clone(),
|
||||
project.environment(),
|
||||
cx.weak_model(),
|
||||
&worktree,
|
||||
http_client,
|
||||
project.fs().clone(),
|
||||
|
|
|
@ -310,6 +310,9 @@ impl Server {
|
|||
.add_request_handler(forward_read_only_project_request::<proto::OpenBufferByPath>)
|
||||
.add_request_handler(forward_read_only_project_request::<proto::GitBranches>)
|
||||
.add_request_handler(forward_read_only_project_request::<proto::GetStagedText>)
|
||||
.add_request_handler(
|
||||
forward_mutating_project_request::<proto::RegisterBufferWithLanguageServers>,
|
||||
)
|
||||
.add_request_handler(forward_mutating_project_request::<proto::UpdateGitBranch>)
|
||||
.add_request_handler(forward_mutating_project_request::<proto::GetCompletions>)
|
||||
.add_request_handler(
|
||||
|
|
|
@ -994,10 +994,12 @@ async fn test_language_server_statuses(cx_a: &mut TestAppContext, cx_b: &mut Tes
|
|||
}),
|
||||
)
|
||||
.await;
|
||||
let (project_a, worktree_id) = client_a.build_local_project("/dir", cx_a).await;
|
||||
let (project_a, _) = client_a.build_local_project("/dir", cx_a).await;
|
||||
|
||||
let _buffer_a = project_a
|
||||
.update(cx_a, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx))
|
||||
.update(cx_a, |p, cx| {
|
||||
p.open_local_buffer_with_lsp("/dir/main.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -1587,7 +1589,6 @@ async fn test_mutual_editor_inlay_hint_cache_update(
|
|||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let fake_language_server = fake_language_servers.next().await.unwrap();
|
||||
let editor_a = workspace_a
|
||||
.update(cx_a, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "main.rs"), None, true, cx)
|
||||
|
@ -1597,6 +1598,8 @@ async fn test_mutual_editor_inlay_hint_cache_update(
|
|||
.downcast::<Editor>()
|
||||
.unwrap();
|
||||
|
||||
let fake_language_server = fake_language_servers.next().await.unwrap();
|
||||
|
||||
// Set up the language server to return an additional inlay hint on each request.
|
||||
let edits_made = Arc::new(AtomicUsize::new(0));
|
||||
let closure_edits_made = Arc::clone(&edits_made);
|
||||
|
|
|
@ -3891,13 +3891,7 @@ async fn test_collaborating_with_diagnostics(
|
|||
// Cause the language server to start.
|
||||
let _buffer = project_a
|
||||
.update(cx_a, |project, cx| {
|
||||
project.open_buffer(
|
||||
ProjectPath {
|
||||
worktree_id,
|
||||
path: Path::new("other.rs").into(),
|
||||
},
|
||||
cx,
|
||||
)
|
||||
project.open_local_buffer_with_lsp("/a/other.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -4176,7 +4170,9 @@ async fn test_collaborating_with_lsp_progress_updates_and_diagnostics_ordering(
|
|||
// Join the project as client B and open all three files.
|
||||
let project_b = client_b.join_remote_project(project_id, cx_b).await;
|
||||
let guest_buffers = futures::future::try_join_all(file_names.iter().map(|file_name| {
|
||||
project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, file_name), cx))
|
||||
project_b.update(cx_b, |p, cx| {
|
||||
p.open_buffer_with_lsp((worktree_id, file_name), cx)
|
||||
})
|
||||
}))
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -4230,7 +4226,7 @@ async fn test_collaborating_with_lsp_progress_updates_and_diagnostics_ordering(
|
|||
cx.subscribe(&project_b, move |_, _, event, cx| {
|
||||
if let project::Event::DiskBasedDiagnosticsFinished { .. } = event {
|
||||
disk_based_diagnostics_finished.store(true, SeqCst);
|
||||
for buffer in &guest_buffers {
|
||||
for (buffer, _) in &guest_buffers {
|
||||
assert_eq!(
|
||||
buffer
|
||||
.read(cx)
|
||||
|
@ -4351,7 +4347,6 @@ async fn test_formatting_buffer(
|
|||
cx_a: &mut TestAppContext,
|
||||
cx_b: &mut TestAppContext,
|
||||
) {
|
||||
executor.allow_parking();
|
||||
let mut server = TestServer::start(executor.clone()).await;
|
||||
let client_a = server.create_client(cx_a, "user_a").await;
|
||||
let client_b = server.create_client(cx_b, "user_b").await;
|
||||
|
@ -4379,10 +4374,16 @@ async fn test_formatting_buffer(
|
|||
.await
|
||||
.unwrap();
|
||||
let project_b = client_b.join_remote_project(project_id, cx_b).await;
|
||||
let lsp_store_b = project_b.update(cx_b, |p, _| p.lsp_store());
|
||||
|
||||
let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx));
|
||||
let buffer_b = cx_b.executor().spawn(open_buffer).await.unwrap();
|
||||
let buffer_b = project_b
|
||||
.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let _handle = lsp_store_b.update(cx_b, |lsp_store, cx| {
|
||||
lsp_store.register_buffer_with_language_servers(&buffer_b, cx)
|
||||
});
|
||||
let fake_language_server = fake_language_servers.next().await.unwrap();
|
||||
fake_language_server.handle_request::<lsp::request::Formatting, _, _>(|_, _| async move {
|
||||
Ok(Some(vec![
|
||||
|
@ -4431,6 +4432,8 @@ async fn test_formatting_buffer(
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
executor.allow_parking();
|
||||
project_b
|
||||
.update(cx_b, |project, cx| {
|
||||
project.format(
|
||||
|
@ -4503,8 +4506,12 @@ async fn test_prettier_formatting_buffer(
|
|||
.await
|
||||
.unwrap();
|
||||
let project_b = client_b.join_remote_project(project_id, cx_b).await;
|
||||
let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.ts"), cx));
|
||||
let buffer_b = cx_b.executor().spawn(open_buffer).await.unwrap();
|
||||
let (buffer_b, _) = project_b
|
||||
.update(cx_b, |p, cx| {
|
||||
p.open_buffer_with_lsp((worktree_id, "a.ts"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
cx_a.update(|cx| {
|
||||
SettingsStore::update_global(cx, |store, cx| {
|
||||
|
@ -4620,8 +4627,12 @@ async fn test_definition(
|
|||
let project_b = client_b.join_remote_project(project_id, cx_b).await;
|
||||
|
||||
// Open the file on client B.
|
||||
let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx));
|
||||
let buffer_b = cx_b.executor().spawn(open_buffer).await.unwrap();
|
||||
let (buffer_b, _handle) = project_b
|
||||
.update(cx_b, |p, cx| {
|
||||
p.open_buffer_with_lsp((worktree_id, "a.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Request the definition of a symbol as the guest.
|
||||
let fake_language_server = fake_language_servers.next().await.unwrap();
|
||||
|
@ -4765,8 +4776,12 @@ async fn test_references(
|
|||
let project_b = client_b.join_remote_project(project_id, cx_b).await;
|
||||
|
||||
// Open the file on client B.
|
||||
let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "one.rs"), cx));
|
||||
let buffer_b = cx_b.executor().spawn(open_buffer).await.unwrap();
|
||||
let (buffer_b, _handle) = project_b
|
||||
.update(cx_b, |p, cx| {
|
||||
p.open_buffer_with_lsp((worktree_id, "one.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Request references to a symbol as the guest.
|
||||
let fake_language_server = fake_language_servers.next().await.unwrap();
|
||||
|
@ -5012,8 +5027,12 @@ async fn test_document_highlights(
|
|||
let project_b = client_b.join_remote_project(project_id, cx_b).await;
|
||||
|
||||
// Open the file on client B.
|
||||
let open_b = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx));
|
||||
let buffer_b = cx_b.executor().spawn(open_b).await.unwrap();
|
||||
let (buffer_b, _handle) = project_b
|
||||
.update(cx_b, |p, cx| {
|
||||
p.open_buffer_with_lsp((worktree_id, "main.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Request document highlights as the guest.
|
||||
let fake_language_server = fake_language_servers.next().await.unwrap();
|
||||
|
@ -5130,8 +5149,12 @@ async fn test_lsp_hover(
|
|||
let project_b = client_b.join_remote_project(project_id, cx_b).await;
|
||||
|
||||
// Open the file as the guest
|
||||
let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx));
|
||||
let buffer_b = cx_b.executor().spawn(open_buffer).await.unwrap();
|
||||
let (buffer_b, _handle) = project_b
|
||||
.update(cx_b, |p, cx| {
|
||||
p.open_buffer_with_lsp((worktree_id, "main.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut servers_with_hover_requests = HashMap::default();
|
||||
for i in 0..language_server_names.len() {
|
||||
|
@ -5306,9 +5329,12 @@ async fn test_project_symbols(
|
|||
let project_b = client_b.join_remote_project(project_id, cx_b).await;
|
||||
|
||||
// Cause the language server to start.
|
||||
let open_buffer_task =
|
||||
project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "one.rs"), cx));
|
||||
let _buffer = cx_b.executor().spawn(open_buffer_task).await.unwrap();
|
||||
let _buffer = project_b
|
||||
.update(cx_b, |p, cx| {
|
||||
p.open_buffer_with_lsp((worktree_id, "one.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let fake_language_server = fake_language_servers.next().await.unwrap();
|
||||
fake_language_server.handle_request::<lsp::WorkspaceSymbolRequest, _, _>(|_, _| async move {
|
||||
|
@ -5400,8 +5426,12 @@ async fn test_open_buffer_while_getting_definition_pointing_to_it(
|
|||
.unwrap();
|
||||
let project_b = client_b.join_remote_project(project_id, cx_b).await;
|
||||
|
||||
let open_buffer_task = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx));
|
||||
let buffer_b1 = cx_b.executor().spawn(open_buffer_task).await.unwrap();
|
||||
let (buffer_b1, _lsp) = project_b
|
||||
.update(cx_b, |p, cx| {
|
||||
p.open_buffer_with_lsp((worktree_id, "a.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let fake_language_server = fake_language_servers.next().await.unwrap();
|
||||
fake_language_server.handle_request::<lsp::request::GotoDefinition, _, _>(|_, _| async move {
|
||||
|
@ -5417,13 +5447,22 @@ async fn test_open_buffer_while_getting_definition_pointing_to_it(
|
|||
let buffer_b2;
|
||||
if rng.gen() {
|
||||
definitions = project_b.update(cx_b, |p, cx| p.definition(&buffer_b1, 23, cx));
|
||||
buffer_b2 = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "b.rs"), cx));
|
||||
(buffer_b2, _) = project_b
|
||||
.update(cx_b, |p, cx| {
|
||||
p.open_buffer_with_lsp((worktree_id, "b.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
} else {
|
||||
buffer_b2 = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "b.rs"), cx));
|
||||
(buffer_b2, _) = project_b
|
||||
.update(cx_b, |p, cx| {
|
||||
p.open_buffer_with_lsp((worktree_id, "b.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
definitions = project_b.update(cx_b, |p, cx| p.definition(&buffer_b1, 23, cx));
|
||||
}
|
||||
|
||||
let buffer_b2 = buffer_b2.await.unwrap();
|
||||
let definitions = definitions.await.unwrap();
|
||||
assert_eq!(definitions.len(), 1);
|
||||
assert_eq!(definitions[0].target.buffer, buffer_b2);
|
||||
|
|
|
@ -426,8 +426,10 @@ async fn test_ssh_collaboration_formatting_with_prettier(
|
|||
executor.run_until_parked();
|
||||
|
||||
// Opens the buffer and formats it
|
||||
let buffer_b = project_b
|
||||
.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.ts"), cx))
|
||||
let (buffer_b, _handle) = project_b
|
||||
.update(cx_b, |p, cx| {
|
||||
p.open_buffer_with_lsp((worktree_id, "a.ts"), cx)
|
||||
})
|
||||
.await
|
||||
.expect("user B opens buffer for formatting");
|
||||
|
||||
|
|
|
@ -129,10 +129,10 @@ use multi_buffer::{
|
|||
};
|
||||
use parking_lot::RwLock;
|
||||
use project::{
|
||||
lsp_store::{FormatTarget, FormatTrigger},
|
||||
lsp_store::{FormatTarget, FormatTrigger, OpenLspBufferHandle},
|
||||
project_settings::{GitGutterSetting, ProjectSettings},
|
||||
CodeAction, Completion, CompletionIntent, DocumentHighlight, InlayHint, Location, LocationLink,
|
||||
Project, ProjectItem, ProjectTransaction, TaskSourceKind,
|
||||
LspStore, Project, ProjectItem, ProjectTransaction, TaskSourceKind,
|
||||
};
|
||||
use rand::prelude::*;
|
||||
use rpc::{proto::*, ErrorExt};
|
||||
|
@ -663,6 +663,7 @@ pub struct Editor {
|
|||
focused_block: Option<FocusedBlock>,
|
||||
next_scroll_position: NextScrollCursorCenterTopBottom,
|
||||
addons: HashMap<TypeId, Box<dyn Addon>>,
|
||||
registered_buffers: HashMap<BufferId, OpenLspBufferHandle>,
|
||||
_scroll_cursor_center_top_bottom_task: Task<()>,
|
||||
}
|
||||
|
||||
|
@ -1308,6 +1309,7 @@ impl Editor {
|
|||
focused_block: None,
|
||||
next_scroll_position: NextScrollCursorCenterTopBottom::default(),
|
||||
addons: HashMap::default(),
|
||||
registered_buffers: HashMap::default(),
|
||||
_scroll_cursor_center_top_bottom_task: Task::ready(()),
|
||||
text_style_refinement: None,
|
||||
};
|
||||
|
@ -1325,6 +1327,17 @@ impl Editor {
|
|||
this.git_blame_inline_enabled = true;
|
||||
this.start_git_blame_inline(false, cx);
|
||||
}
|
||||
|
||||
if let Some(buffer) = buffer.read(cx).as_singleton() {
|
||||
if let Some(project) = this.project.as_ref() {
|
||||
let lsp_store = project.read(cx).lsp_store();
|
||||
let handle = lsp_store.update(cx, |lsp_store, cx| {
|
||||
lsp_store.register_buffer_with_language_servers(&buffer, cx)
|
||||
});
|
||||
this.registered_buffers
|
||||
.insert(buffer.read(cx).remote_id(), handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.report_editor_event("open", None, cx);
|
||||
|
@ -1635,6 +1648,22 @@ impl Editor {
|
|||
self.collapse_matches = collapse_matches;
|
||||
}
|
||||
|
||||
pub fn register_buffers_with_language_servers(&mut self, cx: &mut ViewContext<Self>) {
|
||||
let buffers = self.buffer.read(cx).all_buffers();
|
||||
let Some(lsp_store) = self.lsp_store(cx) else {
|
||||
return;
|
||||
};
|
||||
lsp_store.update(cx, |lsp_store, cx| {
|
||||
for buffer in buffers {
|
||||
self.registered_buffers
|
||||
.entry(buffer.read(cx).remote_id())
|
||||
.or_insert_with(|| {
|
||||
lsp_store.register_buffer_with_language_servers(&buffer, cx)
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn range_for_match<T: std::marker::Copy>(&self, range: &Range<T>) -> Range<T> {
|
||||
if self.collapse_matches {
|
||||
return range.start..range.start;
|
||||
|
@ -9642,6 +9671,7 @@ impl Editor {
|
|||
|theme| theme.editor_highlighted_line_background,
|
||||
cx,
|
||||
);
|
||||
editor.register_buffers_with_language_servers(cx);
|
||||
});
|
||||
|
||||
let item = Box::new(editor);
|
||||
|
@ -11838,6 +11868,12 @@ impl Editor {
|
|||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn lsp_store(&self, cx: &AppContext) -> Option<Model<LspStore>> {
|
||||
self.project
|
||||
.as_ref()
|
||||
.map(|project| project.read(cx).lsp_store())
|
||||
}
|
||||
|
||||
fn on_buffer_changed(&mut self, _: Model<MultiBuffer>, cx: &mut ViewContext<Self>) {
|
||||
cx.notify();
|
||||
}
|
||||
|
@ -11851,6 +11887,7 @@ impl Editor {
|
|||
match event {
|
||||
multi_buffer::Event::Edited {
|
||||
singleton_buffer_edited,
|
||||
edited_buffer: buffer_edited,
|
||||
} => {
|
||||
self.scrollbar_marker_state.dirty = true;
|
||||
self.active_indent_guides_state.dirty = true;
|
||||
|
@ -11859,6 +11896,19 @@ impl Editor {
|
|||
if self.has_active_inline_completion() {
|
||||
self.update_visible_inline_completion(cx);
|
||||
}
|
||||
if let Some(buffer) = buffer_edited {
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
if !self.registered_buffers.contains_key(&buffer_id) {
|
||||
if let Some(lsp_store) = self.lsp_store(cx) {
|
||||
lsp_store.update(cx, |lsp_store, cx| {
|
||||
self.registered_buffers.insert(
|
||||
buffer_id,
|
||||
lsp_store.register_buffer_with_language_servers(&buffer, cx),
|
||||
);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
cx.emit(EditorEvent::BufferEdited);
|
||||
cx.emit(SearchEvent::MatchesInvalidated);
|
||||
if *singleton_buffer_edited {
|
||||
|
@ -11925,6 +11975,9 @@ impl Editor {
|
|||
}
|
||||
multi_buffer::Event::ExcerptsRemoved { ids } => {
|
||||
self.refresh_inlay_hints(InlayHintRefreshReason::ExcerptsRemoved(ids.clone()), cx);
|
||||
let buffer = self.buffer.read(cx);
|
||||
self.registered_buffers
|
||||
.retain(|buffer_id, _| buffer.buffer(*buffer_id).is_some());
|
||||
cx.emit(EditorEvent::ExcerptsRemoved { ids: ids.clone() })
|
||||
}
|
||||
multi_buffer::Event::ExcerptsEdited { ids } => {
|
||||
|
|
|
@ -32,9 +32,12 @@ use project::{
|
|||
project_settings::{LspSettings, ProjectSettings},
|
||||
};
|
||||
use serde_json::{self, json};
|
||||
use std::sync::atomic::{self, AtomicUsize};
|
||||
use std::{cell::RefCell, future::Future, iter, rc::Rc, time::Instant};
|
||||
use test::editor_lsp_test_context::rust_lang;
|
||||
use std::{cell::RefCell, future::Future, rc::Rc, time::Instant};
|
||||
use std::{
|
||||
iter,
|
||||
sync::atomic::{self, AtomicUsize},
|
||||
};
|
||||
use test::{build_editor_with_project, editor_lsp_test_context::rust_lang};
|
||||
use unindent::Unindent;
|
||||
use util::{
|
||||
assert_set_eq,
|
||||
|
@ -6836,14 +6839,15 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
cx.executor().start_waiting();
|
||||
let fake_server = fake_servers.next().await.unwrap();
|
||||
|
||||
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
|
||||
let (editor, cx) =
|
||||
cx.add_window_view(|cx| build_editor_with_project(project.clone(), buffer, cx));
|
||||
editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
|
||||
assert!(cx.read(|cx| editor.is_dirty(cx)));
|
||||
|
||||
cx.executor().start_waiting();
|
||||
let fake_server = fake_servers.next().await.unwrap();
|
||||
|
||||
let save = editor
|
||||
.update(cx, |editor, cx| editor.save(true, project.clone(), cx))
|
||||
.unwrap();
|
||||
|
@ -7117,6 +7121,7 @@ async fn test_multibuffer_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
assert!(!buffer.is_dirty());
|
||||
assert_eq!(buffer.text(), sample_text_3,)
|
||||
});
|
||||
cx.executor().run_until_parked();
|
||||
|
||||
cx.executor().start_waiting();
|
||||
let save = multi_buffer_editor
|
||||
|
@ -7188,14 +7193,15 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
cx.executor().start_waiting();
|
||||
let fake_server = fake_servers.next().await.unwrap();
|
||||
|
||||
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
|
||||
let (editor, cx) =
|
||||
cx.add_window_view(|cx| build_editor_with_project(project.clone(), buffer, cx));
|
||||
editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
|
||||
assert!(cx.read(|cx| editor.is_dirty(cx)));
|
||||
|
||||
cx.executor().start_waiting();
|
||||
let fake_server = fake_servers.next().await.unwrap();
|
||||
|
||||
let save = editor
|
||||
.update(cx, |editor, cx| editor.save(true, project.clone(), cx))
|
||||
.unwrap();
|
||||
|
@ -7339,13 +7345,14 @@ async fn test_document_format_manual_trigger(cx: &mut gpui::TestAppContext) {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||
let (editor, cx) =
|
||||
cx.add_window_view(|cx| build_editor_with_project(project.clone(), buffer, cx));
|
||||
editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
|
||||
|
||||
cx.executor().start_waiting();
|
||||
let fake_server = fake_servers.next().await.unwrap();
|
||||
|
||||
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
|
||||
editor.update(cx, |editor, cx| editor.set_text("one\ntwo\nthree\n", cx));
|
||||
|
||||
let format = editor
|
||||
.update(cx, |editor, cx| {
|
||||
editor.perform_format(
|
||||
|
@ -10332,9 +10339,6 @@ async fn test_on_type_formatting_not_triggered(cx: &mut gpui::TestAppContext) {
|
|||
})
|
||||
.await
|
||||
.unwrap();
|
||||
cx.executor().run_until_parked();
|
||||
cx.executor().start_waiting();
|
||||
let fake_server = fake_servers.next().await.unwrap();
|
||||
let editor_handle = workspace
|
||||
.update(cx, |workspace, cx| {
|
||||
workspace.open_path((worktree_id, "main.rs"), None, true, cx)
|
||||
|
@ -10345,6 +10349,9 @@ async fn test_on_type_formatting_not_triggered(cx: &mut gpui::TestAppContext) {
|
|||
.downcast::<Editor>()
|
||||
.unwrap();
|
||||
|
||||
cx.executor().start_waiting();
|
||||
let fake_server = fake_servers.next().await.unwrap();
|
||||
|
||||
fake_server.handle_request::<lsp::request::OnTypeFormatting, _, _>(|params, _| async move {
|
||||
assert_eq!(
|
||||
params.text_document_position.text_document.uri,
|
||||
|
@ -10434,7 +10441,7 @@ async fn test_language_server_restart_due_to_settings_change(cx: &mut gpui::Test
|
|||
let _window = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||
let _buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/a/main.rs", cx)
|
||||
project.open_local_buffer_with_lsp("/a/main.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -623,9 +623,9 @@ async fn test_extension_store_with_test_extension(cx: &mut TestAppContext) {
|
|||
None,
|
||||
);
|
||||
|
||||
let buffer = project
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer(project_dir.join("test.gleam"), cx)
|
||||
project.open_local_buffer_with_lsp(project_dir.join("test.gleam"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
|
@ -57,7 +57,7 @@ async fn test_lsp_logs(cx: &mut TestAppContext) {
|
|||
|
||||
let _rust_buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/the-root/test.rs", cx)
|
||||
project.open_local_buffer_with_lsp("/the-root/test.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
|
@ -89,6 +89,7 @@ pub enum Event {
|
|||
},
|
||||
Edited {
|
||||
singleton_buffer_edited: bool,
|
||||
edited_buffer: Option<Model<Buffer>>,
|
||||
},
|
||||
TransactionUndone {
|
||||
transaction_id: TransactionId,
|
||||
|
@ -1485,6 +1486,7 @@ impl MultiBuffer {
|
|||
}]);
|
||||
cx.emit(Event::Edited {
|
||||
singleton_buffer_edited: false,
|
||||
edited_buffer: None,
|
||||
});
|
||||
cx.emit(Event::ExcerptsAdded {
|
||||
buffer,
|
||||
|
@ -1512,6 +1514,7 @@ impl MultiBuffer {
|
|||
}]);
|
||||
cx.emit(Event::Edited {
|
||||
singleton_buffer_edited: false,
|
||||
edited_buffer: None,
|
||||
});
|
||||
cx.emit(Event::ExcerptsRemoved { ids });
|
||||
cx.notify();
|
||||
|
@ -1753,6 +1756,7 @@ impl MultiBuffer {
|
|||
self.subscriptions.publish_mut(edits);
|
||||
cx.emit(Event::Edited {
|
||||
singleton_buffer_edited: false,
|
||||
edited_buffer: None,
|
||||
});
|
||||
cx.emit(Event::ExcerptsRemoved { ids });
|
||||
cx.notify();
|
||||
|
@ -1816,6 +1820,7 @@ impl MultiBuffer {
|
|||
cx.emit(match event {
|
||||
language::BufferEvent::Edited => Event::Edited {
|
||||
singleton_buffer_edited: true,
|
||||
edited_buffer: Some(buffer.clone()),
|
||||
},
|
||||
language::BufferEvent::DirtyChanged => Event::DirtyChanged,
|
||||
language::BufferEvent::Saved => Event::Saved,
|
||||
|
@ -1979,6 +1984,7 @@ impl MultiBuffer {
|
|||
self.subscriptions.publish_mut(edits);
|
||||
cx.emit(Event::Edited {
|
||||
singleton_buffer_edited: false,
|
||||
edited_buffer: None,
|
||||
});
|
||||
cx.emit(Event::ExcerptsExpanded { ids: vec![id] });
|
||||
cx.notify();
|
||||
|
@ -2076,6 +2082,7 @@ impl MultiBuffer {
|
|||
self.subscriptions.publish_mut(edits);
|
||||
cx.emit(Event::Edited {
|
||||
singleton_buffer_edited: false,
|
||||
edited_buffer: None,
|
||||
});
|
||||
cx.emit(Event::ExcerptsExpanded { ids });
|
||||
cx.notify();
|
||||
|
@ -5363,13 +5370,16 @@ mod tests {
|
|||
events.read().as_slice(),
|
||||
&[
|
||||
Event::Edited {
|
||||
singleton_buffer_edited: false
|
||||
singleton_buffer_edited: false,
|
||||
edited_buffer: None,
|
||||
},
|
||||
Event::Edited {
|
||||
singleton_buffer_edited: false
|
||||
singleton_buffer_edited: false,
|
||||
edited_buffer: None,
|
||||
},
|
||||
Event::Edited {
|
||||
singleton_buffer_edited: false
|
||||
singleton_buffer_edited: false,
|
||||
edited_buffer: None,
|
||||
}
|
||||
]
|
||||
);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{
|
||||
lsp_store::OpenLspBufferHandle,
|
||||
search::SearchQuery,
|
||||
worktree_store::{WorktreeStore, WorktreeStoreEvent},
|
||||
ProjectItem as _, ProjectPath,
|
||||
|
@ -47,6 +48,7 @@ pub struct BufferStore {
|
|||
struct SharedBuffer {
|
||||
buffer: Model<Buffer>,
|
||||
unstaged_changes: Option<Model<BufferChangeSet>>,
|
||||
lsp_handle: Option<OpenLspBufferHandle>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -1571,6 +1573,21 @@ impl BufferStore {
|
|||
})?
|
||||
}
|
||||
|
||||
pub fn register_shared_lsp_handle(
|
||||
&mut self,
|
||||
peer_id: proto::PeerId,
|
||||
buffer_id: BufferId,
|
||||
handle: OpenLspBufferHandle,
|
||||
) {
|
||||
if let Some(shared_buffers) = self.shared_buffers.get_mut(&peer_id) {
|
||||
if let Some(buffer) = shared_buffers.get_mut(&buffer_id) {
|
||||
buffer.lsp_handle = Some(handle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
debug_panic!("tried to register shared lsp handle, but buffer was not shared")
|
||||
}
|
||||
|
||||
pub fn handle_synchronize_buffers(
|
||||
&mut self,
|
||||
envelope: TypedEnvelope<proto::SynchronizeBuffers>,
|
||||
|
@ -1597,6 +1614,7 @@ impl BufferStore {
|
|||
.or_insert_with(|| SharedBuffer {
|
||||
buffer: buffer.clone(),
|
||||
unstaged_changes: None,
|
||||
lsp_handle: None,
|
||||
});
|
||||
|
||||
let buffer = buffer.read(cx);
|
||||
|
@ -2017,6 +2035,7 @@ impl BufferStore {
|
|||
SharedBuffer {
|
||||
buffer: buffer.clone(),
|
||||
unstaged_changes: None,
|
||||
lsp_handle: None,
|
||||
},
|
||||
);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1254,6 +1254,10 @@ impl Project {
|
|||
self.buffer_store.read(cx).buffers().collect()
|
||||
}
|
||||
|
||||
pub fn environment(&self) -> &Model<ProjectEnvironment> {
|
||||
&self.environment
|
||||
}
|
||||
|
||||
pub fn cli_environment(&self, cx: &AppContext) -> Option<HashMap<String, String>> {
|
||||
self.environment.read(cx).get_cli_environment()
|
||||
}
|
||||
|
@ -1843,6 +1847,19 @@ impl Project {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn open_local_buffer_with_lsp(
|
||||
&mut self,
|
||||
abs_path: impl AsRef<Path>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<(Model<Buffer>, lsp_store::OpenLspBufferHandle)>> {
|
||||
if let Some((worktree, relative_path)) = self.find_worktree(abs_path.as_ref(), cx) {
|
||||
self.open_buffer_with_lsp((worktree.read(cx).id(), relative_path), cx)
|
||||
} else {
|
||||
Task::ready(Err(anyhow!("no such path")))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open_buffer(
|
||||
&mut self,
|
||||
path: impl Into<ProjectPath>,
|
||||
|
@ -1857,6 +1874,23 @@ impl Project {
|
|||
})
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn open_buffer_with_lsp(
|
||||
&mut self,
|
||||
path: impl Into<ProjectPath>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<(Model<Buffer>, lsp_store::OpenLspBufferHandle)>> {
|
||||
let buffer = self.open_buffer(path, cx);
|
||||
let lsp_store = self.lsp_store().clone();
|
||||
cx.spawn(|_, mut cx| async move {
|
||||
let buffer = buffer.await?;
|
||||
let handle = lsp_store.update(&mut cx, |lsp_store, cx| {
|
||||
lsp_store.register_buffer_with_language_servers(&buffer, cx)
|
||||
})?;
|
||||
Ok((buffer, handle))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn open_unstaged_changes(
|
||||
&mut self,
|
||||
buffer: Model<Buffer>,
|
||||
|
|
|
@ -442,17 +442,17 @@ async fn test_managing_language_servers(cx: &mut gpui::TestAppContext) {
|
|||
);
|
||||
|
||||
// Open a buffer without an associated language server.
|
||||
let toml_buffer = project
|
||||
let (toml_buffer, _handle) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/the-root/Cargo.toml", cx)
|
||||
project.open_local_buffer_with_lsp("/the-root/Cargo.toml", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Open a buffer with an associated language server before the language for it has been loaded.
|
||||
let rust_buffer = project
|
||||
let (rust_buffer, _handle2) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/the-root/test.rs", cx)
|
||||
project.open_local_buffer_with_lsp("/the-root/test.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -513,9 +513,9 @@ async fn test_managing_language_servers(cx: &mut gpui::TestAppContext) {
|
|||
);
|
||||
|
||||
// Open a third buffer with a different associated language server.
|
||||
let json_buffer = project
|
||||
let (json_buffer, _json_handle) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/the-root/package.json", cx)
|
||||
project.open_local_buffer_with_lsp("/the-root/package.json", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -550,9 +550,9 @@ async fn test_managing_language_servers(cx: &mut gpui::TestAppContext) {
|
|||
|
||||
// When opening another buffer whose language server is already running,
|
||||
// it is also configured based on the existing language server's capabilities.
|
||||
let rust_buffer2 = project
|
||||
let (rust_buffer2, _handle4) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/the-root/test2.rs", cx)
|
||||
project.open_local_buffer_with_lsp("/the-root/test2.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -765,7 +765,7 @@ async fn test_managing_language_servers(cx: &mut gpui::TestAppContext) {
|
|||
);
|
||||
|
||||
// Close notifications are reported only to servers matching the buffer's language.
|
||||
cx.update(|_| drop(json_buffer));
|
||||
cx.update(|_| drop(_json_handle));
|
||||
let close_message = lsp::DidCloseTextDocumentParams {
|
||||
text_document: lsp::TextDocumentIdentifier::new(
|
||||
lsp::Url::from_file_path("/the-root/package.json").unwrap(),
|
||||
|
@ -827,9 +827,9 @@ async fn test_reporting_fs_changes_to_language_servers(cx: &mut gpui::TestAppCon
|
|||
cx.executor().run_until_parked();
|
||||
|
||||
// Start the language server by opening a buffer with a compatible file extension.
|
||||
let _buffer = project
|
||||
let _ = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/the-root/src/a.rs", cx)
|
||||
project.open_local_buffer_with_lsp("/the-root/src/a.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -1239,8 +1239,10 @@ async fn test_disk_based_diagnostics_progress(cx: &mut gpui::TestAppContext) {
|
|||
let worktree_id = project.update(cx, |p, cx| p.worktrees(cx).next().unwrap().read(cx).id());
|
||||
|
||||
// Cause worktree to start the fake language server
|
||||
let _buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/dir/b.rs", cx))
|
||||
let _ = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/dir/b.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -1259,6 +1261,7 @@ async fn test_disk_based_diagnostics_progress(cx: &mut gpui::TestAppContext) {
|
|||
fake_server
|
||||
.start_progress(format!("{}/0", progress_token))
|
||||
.await;
|
||||
assert_eq!(events.next().await.unwrap(), Event::RefreshInlayHints);
|
||||
assert_eq!(
|
||||
events.next().await.unwrap(),
|
||||
Event::DiskBasedDiagnosticsStarted {
|
||||
|
@ -1365,8 +1368,10 @@ async fn test_restarting_server_with_diagnostics_running(cx: &mut gpui::TestAppC
|
|||
|
||||
let worktree_id = project.update(cx, |p, cx| p.worktrees(cx).next().unwrap().read(cx).id());
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/dir/a.rs", cx))
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/dir/a.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -1390,6 +1395,7 @@ async fn test_restarting_server_with_diagnostics_running(cx: &mut gpui::TestAppC
|
|||
Some(worktree_id)
|
||||
)
|
||||
);
|
||||
assert_eq!(events.next().await.unwrap(), Event::RefreshInlayHints);
|
||||
fake_server.start_progress(progress_token).await;
|
||||
assert_eq!(
|
||||
events.next().await.unwrap(),
|
||||
|
@ -1438,8 +1444,10 @@ async fn test_restarting_server_with_diagnostics_published(cx: &mut gpui::TestAp
|
|||
language_registry.add(rust_lang());
|
||||
let mut fake_servers = language_registry.register_fake_lsp("Rust", FakeLspAdapter::default());
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/dir/a.rs", cx))
|
||||
let (buffer, _) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/dir/a.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -1517,8 +1525,10 @@ async fn test_restarted_server_reporting_invalid_buffer_version(cx: &mut gpui::T
|
|||
language_registry.add(rust_lang());
|
||||
let mut fake_servers = language_registry.register_fake_lsp("Rust", FakeLspAdapter::default());
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/dir/a.rs", cx))
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/dir/a.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -1565,8 +1575,10 @@ async fn test_cancel_language_server_work(cx: &mut gpui::TestAppContext) {
|
|||
},
|
||||
);
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/dir/a.rs", cx))
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/dir/a.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -1634,11 +1646,15 @@ async fn test_toggling_enable_language_server(cx: &mut gpui::TestAppContext) {
|
|||
language_registry.add(js_lang());
|
||||
|
||||
let _rs_buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/dir/a.rs", cx))
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/dir/a.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let _js_buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/dir/b.js", cx))
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/dir/b.js", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -1734,6 +1750,7 @@ async fn test_transforming_diagnostics(cx: &mut gpui::TestAppContext) {
|
|||
fs.insert_tree("/dir", json!({ "a.rs": text })).await;
|
||||
|
||||
let project = Project::test(fs, ["/dir".as_ref()], cx).await;
|
||||
let lsp_store = project.read_with(cx, |project, _| project.lsp_store());
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
|
||||
language_registry.add(rust_lang());
|
||||
|
@ -1750,6 +1767,10 @@ async fn test_transforming_diagnostics(cx: &mut gpui::TestAppContext) {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
let _handle = lsp_store.update(cx, |lsp_store, cx| {
|
||||
lsp_store.register_buffer_with_language_servers(&buffer, cx)
|
||||
});
|
||||
|
||||
let mut fake_server = fake_servers.next().await.unwrap();
|
||||
let open_notification = fake_server
|
||||
.receive_notification::<lsp::notification::DidOpenTextDocument>()
|
||||
|
@ -2162,8 +2183,10 @@ async fn test_edits_from_lsp2_with_past_version(cx: &mut gpui::TestAppContext) {
|
|||
language_registry.add(rust_lang());
|
||||
let mut fake_servers = language_registry.register_fake_lsp("Rust", FakeLspAdapter::default());
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/dir/a.rs", cx))
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/dir/a.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -2533,8 +2556,10 @@ async fn test_definition(cx: &mut gpui::TestAppContext) {
|
|||
language_registry.add(rust_lang());
|
||||
let mut fake_servers = language_registry.register_fake_lsp("Rust", FakeLspAdapter::default());
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/dir/b.rs", cx))
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp("/dir/b.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -2638,8 +2663,8 @@ async fn test_completions_without_edit_ranges(cx: &mut gpui::TestAppContext) {
|
|||
},
|
||||
);
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |p, cx| p.open_local_buffer("/dir/a.ts", cx))
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |p, cx| p.open_local_buffer_with_lsp("/dir/a.ts", cx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -2730,8 +2755,8 @@ async fn test_completions_with_carriage_returns(cx: &mut gpui::TestAppContext) {
|
|||
},
|
||||
);
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |p, cx| p.open_local_buffer("/dir/a.ts", cx))
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |p, cx| p.open_local_buffer_with_lsp("/dir/a.ts", cx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -2793,8 +2818,8 @@ async fn test_apply_code_actions_with_commands(cx: &mut gpui::TestAppContext) {
|
|||
},
|
||||
);
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |p, cx| p.open_local_buffer("/dir/a.ts", cx))
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |p, cx| p.open_local_buffer_with_lsp("/dir/a.ts", cx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
@ -3984,7 +4009,7 @@ async fn test_lsp_rename_notifications(cx: &mut gpui::TestAppContext) {
|
|||
|
||||
let _ = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/dir/one.rs", cx)
|
||||
project.open_local_buffer_with_lsp("/dir/one.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -4086,9 +4111,9 @@ async fn test_rename(cx: &mut gpui::TestAppContext) {
|
|||
},
|
||||
);
|
||||
|
||||
let buffer = project
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/dir/one.rs", cx)
|
||||
project.open_local_buffer_with_lsp("/dir/one.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -4951,8 +4976,8 @@ async fn test_multiple_language_server_hovers(cx: &mut gpui::TestAppContext) {
|
|||
),
|
||||
];
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |p, cx| p.open_local_buffer("/dir/a.tsx", cx))
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |p, cx| p.open_local_buffer_with_lsp("/dir/a.tsx", cx))
|
||||
.await
|
||||
.unwrap();
|
||||
cx.executor().run_until_parked();
|
||||
|
@ -5060,8 +5085,8 @@ async fn test_hovers_with_empty_parts(cx: &mut gpui::TestAppContext) {
|
|||
},
|
||||
);
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |p, cx| p.open_local_buffer("/dir/a.ts", cx))
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |p, cx| p.open_local_buffer_with_lsp("/dir/a.ts", cx))
|
||||
.await
|
||||
.unwrap();
|
||||
cx.executor().run_until_parked();
|
||||
|
@ -5130,8 +5155,8 @@ async fn test_code_actions_only_kinds(cx: &mut gpui::TestAppContext) {
|
|||
},
|
||||
);
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |p, cx| p.open_local_buffer("/dir/a.ts", cx))
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |p, cx| p.open_local_buffer_with_lsp("/dir/a.ts", cx))
|
||||
.await
|
||||
.unwrap();
|
||||
cx.executor().run_until_parked();
|
||||
|
@ -5251,8 +5276,8 @@ async fn test_multiple_language_server_actions(cx: &mut gpui::TestAppContext) {
|
|||
),
|
||||
];
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |p, cx| p.open_local_buffer("/dir/a.tsx", cx))
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |p, cx| p.open_local_buffer_with_lsp("/dir/a.tsx", cx))
|
||||
.await
|
||||
.unwrap();
|
||||
cx.executor().run_until_parked();
|
||||
|
|
|
@ -292,7 +292,7 @@ mod tests {
|
|||
|
||||
let _buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/dir/test.rs", cx)
|
||||
project.open_local_buffer_with_lsp("/dir/test.rs", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
|
@ -304,7 +304,9 @@ message Envelope {
|
|||
InstallExtension install_extension = 287;
|
||||
|
||||
GetStagedText get_staged_text = 288;
|
||||
GetStagedTextResponse get_staged_text_response = 289; // current max
|
||||
GetStagedTextResponse get_staged_text_response = 289;
|
||||
|
||||
RegisterBufferWithLanguageServers register_buffer_with_language_servers = 290;
|
||||
}
|
||||
|
||||
reserved 87 to 88;
|
||||
|
@ -2537,7 +2539,6 @@ message UpdateGitBranch {
|
|||
string branch_name = 2;
|
||||
ProjectPath repository = 3;
|
||||
}
|
||||
|
||||
message GetPanicFiles {
|
||||
}
|
||||
|
||||
|
@ -2582,3 +2583,8 @@ message InstallExtension {
|
|||
Extension extension = 1;
|
||||
string tmp_dir = 2;
|
||||
}
|
||||
|
||||
message RegisterBufferWithLanguageServers{
|
||||
uint64 project_id = 1;
|
||||
uint64 buffer_id = 2;
|
||||
}
|
||||
|
|
|
@ -373,6 +373,7 @@ messages!(
|
|||
(SyncExtensions, Background),
|
||||
(SyncExtensionsResponse, Background),
|
||||
(InstallExtension, Background),
|
||||
(RegisterBufferWithLanguageServers, Background),
|
||||
);
|
||||
|
||||
request_messages!(
|
||||
|
@ -499,6 +500,7 @@ request_messages!(
|
|||
(CancelLanguageServerWork, Ack),
|
||||
(SyncExtensions, SyncExtensionsResponse),
|
||||
(InstallExtension, Ack),
|
||||
(RegisterBufferWithLanguageServers, Ack),
|
||||
);
|
||||
|
||||
entity_messages!(
|
||||
|
@ -584,6 +586,7 @@ entity_messages!(
|
|||
ActiveToolchain,
|
||||
GetPathMetadata,
|
||||
CancelLanguageServerWork,
|
||||
RegisterBufferWithLanguageServers,
|
||||
);
|
||||
|
||||
entity_messages!(
|
||||
|
|
|
@ -440,9 +440,9 @@ async fn test_remote_lsp(cx: &mut TestAppContext, server_cx: &mut TestAppContext
|
|||
// Wait for the settings to synchronize
|
||||
cx.run_until_parked();
|
||||
|
||||
let buffer = project
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_buffer((worktree_id, Path::new("src/lib.rs")), cx)
|
||||
project.open_buffer_with_lsp((worktree_id, Path::new("src/lib.rs")), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -616,9 +616,9 @@ async fn test_remote_cancel_language_server_work(
|
|||
|
||||
cx.run_until_parked();
|
||||
|
||||
let buffer = project
|
||||
let (buffer, _handle) = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_buffer((worktree_id, Path::new("src/lib.rs")), cx)
|
||||
project.open_buffer_with_lsp((worktree_id, Path::new("src/lib.rs")), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue