use ssh lsp store (#17655)

Release Notes:

- ssh remoting: Added support for booting langauge servers (in limited
circumstances)

---------

Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
Conrad Irwin 2024-09-10 15:51:01 -04:00 committed by GitHub
parent 130f19d8f9
commit 36eb1c15ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
45 changed files with 1553 additions and 671 deletions

View file

@ -107,7 +107,7 @@ pub use buffer_store::ProjectTransaction;
pub use lsp_store::{
DiagnosticSummary, LanguageServerLogType, LanguageServerProgress, LanguageServerPromptRequest,
LanguageServerStatus, LanguageServerToQuery, LspStore, LspStoreEvent,
ProjectLspAdapterDelegate, SERVER_PROGRESS_THROTTLE_TIMEOUT,
SERVER_PROGRESS_THROTTLE_TIMEOUT,
};
const MAX_PROJECT_SEARCH_HISTORY_SIZE: usize = 500;
@ -643,16 +643,13 @@ impl Project {
let environment = ProjectEnvironment::new(&worktree_store, env, cx);
let lsp_store = cx.new_model(|cx| {
LspStore::new(
LspStore::new_local(
buffer_store.clone(),
worktree_store.clone(),
Some(environment.clone()),
environment.clone(),
languages.clone(),
Some(client.http_client()),
fs.clone(),
None,
None,
None,
cx,
)
});
@ -712,17 +709,90 @@ impl Project {
fs: Arc<dyn Fs>,
cx: &mut AppContext,
) -> Model<Self> {
let this = Self::local(client, node, user_store, languages, fs, None, cx);
this.update(cx, |this, cx| {
let client: AnyProtoClient = ssh.clone().into();
cx.new_model(|cx: &mut ModelContext<Self>| {
let (tx, rx) = mpsc::unbounded();
cx.spawn(move |this, cx| Self::send_buffer_ordered_messages(this, rx, cx))
.detach();
let tasks = Inventory::new(cx);
let global_snippets_dir = paths::config_dir().join("snippets");
let snippets =
SnippetProvider::new(fs.clone(), BTreeSet::from_iter([global_snippets_dir]), cx);
this.worktree_store.update(cx, |store, _cx| {
store.set_upstream_client(client.clone());
let worktree_store = cx.new_model(|_| {
let mut worktree_store = WorktreeStore::new(false, fs.clone());
worktree_store.set_upstream_client(ssh.clone().into());
worktree_store
});
this.settings_observer = cx.new_model(|cx| {
SettingsObserver::new_ssh(ssh.clone().into(), this.worktree_store.clone(), cx)
cx.subscribe(&worktree_store, Self::on_worktree_store_event)
.detach();
let buffer_store =
cx.new_model(|cx| BufferStore::new(worktree_store.clone(), None, cx));
cx.subscribe(&buffer_store, Self::on_buffer_store_event)
.detach();
let settings_observer = cx.new_model(|cx| {
SettingsObserver::new_ssh(ssh.clone().into(), worktree_store.clone(), cx)
});
let environment = ProjectEnvironment::new(&worktree_store, None, cx);
let lsp_store = cx.new_model(|cx| {
LspStore::new_ssh(
buffer_store.clone(),
worktree_store.clone(),
languages.clone(),
ssh.clone().into(),
0,
cx,
)
});
cx.subscribe(&lsp_store, Self::on_lsp_store_event).detach();
let this = Self {
buffer_ordered_messages_tx: tx,
collaborators: Default::default(),
worktree_store,
buffer_store,
lsp_store,
current_lsp_settings: ProjectSettings::get_global(cx).lsp.clone(),
join_project_response_message_id: 0,
client_state: ProjectClientState::Local,
client_subscriptions: Vec::new(),
_subscriptions: vec![
cx.observe_global::<SettingsStore>(Self::on_settings_changed),
cx.on_release(Self::release),
],
active_entry: None,
snippets,
languages,
client,
user_store,
settings_observer,
fs,
ssh_session: Some(ssh.clone()),
buffers_needing_diff: Default::default(),
git_diff_debouncer: DebouncedDelay::new(),
terminals: Terminals {
local_handles: Vec::new(),
},
node: Some(node),
default_prettier: DefaultPrettier::default(),
prettiers_per_worktree: HashMap::default(),
prettier_instances: HashMap::default(),
tasks,
hosted_project_id: None,
dev_server_project_id: None,
search_history: Self::new_search_history(),
environment,
remotely_created_buffers: Default::default(),
last_formatting_failure: None,
buffers_being_formatted: Default::default(),
search_included_history: Self::new_search_history(),
search_excluded_history: Self::new_search_history(),
};
let client: AnyProtoClient = ssh.clone().into();
ssh.subscribe_to_entity(SSH_PROJECT_ID, &cx.handle());
ssh.subscribe_to_entity(SSH_PROJECT_ID, &this.buffer_store);
ssh.subscribe_to_entity(SSH_PROJECT_ID, &this.worktree_store);
@ -735,9 +805,8 @@ impl Project {
LspStore::init(&client);
SettingsObserver::init(&client);
this.ssh_session = Some(ssh);
});
this
this
})
}
pub async fn remote(
@ -820,16 +889,12 @@ impl Project {
cx.new_model(|cx| BufferStore::new(worktree_store.clone(), Some(remote_id), cx))?;
let lsp_store = cx.new_model(|cx| {
let mut lsp_store = LspStore::new(
let mut lsp_store = LspStore::new_remote(
buffer_store.clone(),
worktree_store.clone(),
None,
languages.clone(),
Some(client.http_client()),
fs.clone(),
None,
Some(client.clone().into()),
Some(remote_id),
client.clone().into(),
remote_id,
cx,
);
lsp_store.set_language_server_statuses_from_proto(response.payload.language_servers);
@ -1125,8 +1190,7 @@ impl Project {
if let Some(language) = buffer_language {
if settings.enable_language_server {
if let Some(file) = buffer_file {
language_servers_to_start
.push((file.worktree.clone(), Arc::clone(language)));
language_servers_to_start.push((file.worktree.clone(), language.name()));
}
}
language_formatters_to_check
@ -1144,7 +1208,7 @@ impl Project {
let language = languages.iter().find_map(|l| {
let adapter = self
.languages
.lsp_adapters(l)
.lsp_adapters(&l.name())
.iter()
.find(|adapter| adapter.name == started_lsp_name)?
.clone();
@ -1165,11 +1229,11 @@ impl Project {
) {
(None, None) => {}
(Some(_), None) | (None, Some(_)) => {
language_servers_to_restart.push((worktree, Arc::clone(language)));
language_servers_to_restart.push((worktree, language.name()));
}
(Some(current_lsp_settings), Some(new_lsp_settings)) => {
if current_lsp_settings != new_lsp_settings {
language_servers_to_restart.push((worktree, Arc::clone(language)));
language_servers_to_restart.push((worktree, language.name()));
}
}
}
@ -4777,7 +4841,7 @@ impl Project {
pub fn supplementary_language_servers<'a>(
&'a self,
cx: &'a AppContext,
) -> impl '_ + Iterator<Item = (&'a LanguageServerId, &'a LanguageServerName)> {
) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
self.lsp_store.read(cx).supplementary_language_servers()
}