From 64532e94e456dd4595897c96a0d06a7e22379add Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Wed, 25 Sep 2024 16:29:04 -0600 Subject: [PATCH] Move adapters to remote (#18359) Release Notes: - ssh remoting: run LSP Adapters on host --------- Co-authored-by: Mikayla --- Cargo.lock | 1 + crates/languages/Cargo.toml | 54 ++- crates/languages/src/lib.rs | 17 +- crates/project/src/lsp_store.rs | 442 +------------------ crates/project/src/project.rs | 3 +- crates/proto/proto/zed.proto | 74 +--- crates/proto/src/proto.rs | 18 - crates/remote_server/Cargo.toml | 1 + crates/remote_server/src/headless_project.rs | 12 +- crates/zed/Cargo.toml | 2 +- 10 files changed, 76 insertions(+), 548 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 26b979ccf7..0b3ee53e9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9122,6 +9122,7 @@ dependencies = [ "gpui", "http_client", "language", + "languages", "log", "lsp", "node_runtime", diff --git a/crates/languages/Cargo.toml b/crates/languages/Cargo.toml index 33be1a9809..5cb5455dd1 100644 --- a/crates/languages/Cargo.toml +++ b/crates/languages/Cargo.toml @@ -10,6 +10,25 @@ workspace = true [features] test-support = [] +load-grammars = [ + "tree-sitter-bash", + "tree-sitter-c", + "tree-sitter-cpp", + "tree-sitter-css", + "tree-sitter-go", + "tree-sitter-go-mod", + "tree-sitter-gowork", + "tree-sitter-jsdoc", + "tree-sitter-json", + "tree-sitter-md", + "protols-tree-sitter-proto", + "tree-sitter-python", + "tree-sitter-regex", + "tree-sitter-rust", + "tree-sitter-typescript", + "tree-sitter-yaml", + "tree-sitter" +] [dependencies] anyhow.workspace = true @@ -36,25 +55,26 @@ settings.workspace = true smol.workspace = true task.workspace = true toml.workspace = true -tree-sitter-bash.workspace = true -tree-sitter-c.workspace = true -tree-sitter-cpp.workspace = true -tree-sitter-css.workspace = true -tree-sitter-go.workspace = true -tree-sitter-go-mod.workspace = true -tree-sitter-gowork.workspace = true -tree-sitter-jsdoc.workspace = true -tree-sitter-json.workspace = true -tree-sitter-md.workspace = true -protols-tree-sitter-proto.workspace = true -tree-sitter-python.workspace = true -tree-sitter-regex.workspace = true -tree-sitter-rust.workspace = true -tree-sitter-typescript.workspace = true -tree-sitter-yaml.workspace = true -tree-sitter.workspace = true util.workspace = true +tree-sitter-bash = {workspace = true, optional = true} +tree-sitter-c = {workspace = true, optional = true} +tree-sitter-cpp = {workspace = true, optional = true} +tree-sitter-css = {workspace = true, optional = true} +tree-sitter-go = {workspace = true, optional = true} +tree-sitter-go-mod = {workspace = true, optional = true} +tree-sitter-gowork = {workspace = true, optional = true} +tree-sitter-jsdoc = {workspace = true, optional = true} +tree-sitter-json = {workspace = true, optional = true} +tree-sitter-md = {workspace = true, optional = true} +protols-tree-sitter-proto = {workspace = true, optional = true} +tree-sitter-python = {workspace = true, optional = true} +tree-sitter-regex = {workspace = true, optional = true} +tree-sitter-rust = {workspace = true, optional = true} +tree-sitter-typescript = {workspace = true, optional = true} +tree-sitter-yaml = {workspace = true, optional = true} +tree-sitter = {workspace = true, optional = true} + [dev-dependencies] text.workspace = true theme = { workspace = true, features = ["test-support"] } diff --git a/crates/languages/src/lib.rs b/crates/languages/src/lib.rs index 7435ddb131..295df6e419 100644 --- a/crates/languages/src/lib.rs +++ b/crates/languages/src/lib.rs @@ -31,6 +31,7 @@ mod yaml; struct LanguageDir; pub fn init(languages: Arc, node_runtime: NodeRuntime, cx: &mut AppContext) { + #[cfg(feature = "load-grammars")] languages.register_native_grammars([ ("bash", tree_sitter_bash::LANGUAGE), ("c", tree_sitter_c::LANGUAGE), @@ -282,9 +283,21 @@ fn load_config(name: &str) -> LanguageConfig { ) .unwrap(); - ::toml::from_str(&config_toml) + #[allow(unused_mut)] + let mut config: LanguageConfig = ::toml::from_str(&config_toml) .with_context(|| format!("failed to load config.toml for language {name:?}")) - .unwrap() + .unwrap(); + + #[cfg(not(feature = "load-grammars"))] + { + config = LanguageConfig { + name: config.name, + matcher: config.matcher, + ..Default::default() + } + } + + config } fn load_queries(name: &str) -> LanguageQueries { diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index bef57bafb4..a4a13b296e 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -36,10 +36,10 @@ use language::{ markdown, point_to_lsp, prepare_completion_documentation, proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version}, range_from_lsp, Bias, Buffer, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic, - DiagnosticEntry, DiagnosticSet, Diff, Documentation, File as _, Language, LanguageConfig, - LanguageMatcher, LanguageName, LanguageRegistry, LanguageServerBinaryStatus, - LanguageServerName, LocalFile, LspAdapter, LspAdapterDelegate, Patch, PointUtf16, - TextBufferSnapshot, ToOffset, ToPointUtf16, Transaction, Unclipped, + DiagnosticEntry, DiagnosticSet, Diff, Documentation, File as _, Language, LanguageName, + LanguageRegistry, LanguageServerBinaryStatus, LanguageServerName, LocalFile, LspAdapter, + LspAdapterDelegate, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Transaction, + Unclipped, }; use lsp::{ CodeActionKind, CompletionContext, DiagnosticSeverity, DiagnosticTag, @@ -53,7 +53,7 @@ use parking_lot::{Mutex, RwLock}; use postage::watch; use rand::prelude::*; -use rpc::{proto::SSH_PROJECT_ID, AnyProtoClient}; +use rpc::AnyProtoClient; use serde::Serialize; use settings::{Settings, SettingsLocation, SettingsStore}; use sha2::{Digest, Sha256}; @@ -644,16 +644,15 @@ pub struct RemoteLspStore { impl RemoteLspStore {} -pub struct SshLspStore { - upstream_client: AnyProtoClient, - current_lsp_settings: HashMap, -} +// pub struct SshLspStore { +// upstream_client: AnyProtoClient, +// current_lsp_settings: HashMap, +// } #[allow(clippy::large_enum_variant)] pub enum LspStoreMode { Local(LocalLspStore), // ssh host and collab host Remote(RemoteLspStore), // collab guest - Ssh(SshLspStore), // ssh client } impl LspStoreMode { @@ -661,10 +660,6 @@ impl LspStoreMode { matches!(self, LspStoreMode::Local(_)) } - fn is_ssh(&self) -> bool { - matches!(self, LspStoreMode::Ssh(_)) - } - fn is_remote(&self) -> bool { matches!(self, LspStoreMode::Remote(_)) } @@ -787,13 +782,6 @@ impl LspStore { } } - pub fn as_ssh(&self) -> Option<&SshLspStore> { - match &self.mode { - LspStoreMode::Ssh(ssh_lsp_store) => Some(ssh_lsp_store), - _ => None, - } - } - pub fn as_local(&self) -> Option<&LocalLspStore> { match &self.mode { LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store), @@ -810,9 +798,6 @@ impl LspStore { pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> { match &self.mode { - LspStoreMode::Ssh(SshLspStore { - upstream_client, .. - }) => Some((upstream_client.clone(), SSH_PROJECT_ID)), LspStoreMode::Remote(RemoteLspStore { upstream_client, upstream_project_id, @@ -827,11 +812,7 @@ impl LspStore { new_settings: HashMap, ) -> Option> { match &mut self.mode { - LspStoreMode::Ssh(SshLspStore { - current_lsp_settings, - .. - }) - | LspStoreMode::Local(LocalLspStore { + LspStoreMode::Local(LocalLspStore { current_lsp_settings, .. }) => { @@ -919,43 +900,6 @@ impl LspStore { }) } - pub fn new_ssh( - buffer_store: Model, - worktree_store: Model, - languages: Arc, - upstream_client: AnyProtoClient, - cx: &mut ModelContext, - ) -> Self { - cx.subscribe(&buffer_store, Self::on_buffer_store_event) - .detach(); - cx.subscribe(&worktree_store, Self::on_worktree_store_event) - .detach(); - cx.observe_global::(Self::on_settings_changed) - .detach(); - - Self { - mode: LspStoreMode::Ssh(SshLspStore { - upstream_client, - current_lsp_settings: Default::default(), - }), - downstream_client: None, - buffer_store, - worktree_store, - languages: languages.clone(), - language_server_ids: Default::default(), - language_server_statuses: Default::default(), - nonce: StdRng::from_entropy().gen(), - buffer_snapshots: Default::default(), - next_diagnostic_group_id: Default::default(), - diagnostic_summaries: Default::default(), - - diagnostics: Default::default(), - active_entry: None, - _maintain_workspace_config: Self::maintain_workspace_config(cx), - _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx), - } - } - pub fn new_remote( buffer_store: Model, worktree_store: Model, @@ -3697,11 +3641,11 @@ impl LspStore { mut cx: AsyncAppContext, ) -> Result { let response_from_ssh = this.update(&mut cx, |this, _| { - let ssh = this.as_ssh()?; + let (upstream_client, project_id) = this.upstream_client()?; let mut payload = envelope.payload.clone(); - payload.project_id = SSH_PROJECT_ID; + payload.project_id = project_id; - Some(ssh.upstream_client.request(payload)) + Some(upstream_client.request(payload)) })?; if let Some(response_from_ssh) = response_from_ssh { return response_from_ssh.await; @@ -5009,165 +4953,6 @@ impl LspStore { Ok(proto::Ack {}) } - pub async fn handle_create_language_server( - this: Model, - envelope: TypedEnvelope, - mut cx: AsyncAppContext, - ) -> Result { - let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id); - let server_name = LanguageServerName::from_proto(envelope.payload.name); - - let binary = envelope - .payload - .binary - .ok_or_else(|| anyhow!("missing binary"))?; - let binary = LanguageServerBinary { - path: PathBuf::from(binary.path), - env: None, - arguments: binary.arguments.into_iter().map(Into::into).collect(), - }; - let language = envelope - .payload - .language - .ok_or_else(|| anyhow!("missing language"))?; - let language_name = LanguageName::from_proto(language.name); - let matcher: LanguageMatcher = serde_json::from_str(&language.matcher)?; - - this.update(&mut cx, |this, cx| { - let Some(worktree) = this - .worktree_store - .read(cx) - .worktree_for_id(worktree_id, cx) - else { - return Err(anyhow!("worktree not found")); - }; - - this.languages - .register_language(language_name.clone(), None, matcher.clone(), { - let language_name = language_name.clone(); - move || { - Ok(( - LanguageConfig { - name: language_name.clone(), - matcher: matcher.clone(), - ..Default::default() - }, - Default::default(), - Default::default(), - )) - } - }); - cx.background_executor() - .spawn(this.languages.language_for_name(language_name.0.as_ref())) - .detach(); - - // host - let adapter = this.languages.get_or_register_lsp_adapter( - language_name.clone(), - server_name.clone(), - || { - Arc::new(SshLspAdapter::new( - server_name, - binary, - envelope.payload.initialization_options, - envelope.payload.code_action_kinds, - )) - }, - ); - - this.start_language_server(&worktree, adapter, language_name, cx); - Ok(()) - })??; - Ok(proto::Ack {}) - } - - pub async fn handle_which_command( - this: Model, - envelope: TypedEnvelope, - mut cx: AsyncAppContext, - ) -> Result { - let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id); - let command = PathBuf::from(envelope.payload.command); - let response = this - .update(&mut cx, |this, cx| { - let worktree = this.worktree_for_id(worktree_id, cx)?; - let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx); - anyhow::Ok( - cx.spawn(|_, _| async move { delegate.which(command.as_os_str()).await }), - ) - })?? - .await; - - Ok(proto::WhichCommandResponse { - path: response.map(|path| path.to_string_lossy().to_string()), - }) - } - - pub async fn handle_shell_env( - this: Model, - envelope: TypedEnvelope, - mut cx: AsyncAppContext, - ) -> Result { - let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id); - let response = this - .update(&mut cx, |this, cx| { - let worktree = this.worktree_for_id(worktree_id, cx)?; - let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx); - anyhow::Ok(cx.spawn(|_, _| async move { delegate.shell_env().await })) - })?? - .await; - - Ok(proto::ShellEnvResponse { - env: response.into_iter().collect(), - }) - } - pub async fn handle_try_exec( - this: Model, - envelope: TypedEnvelope, - mut cx: AsyncAppContext, - ) -> Result { - let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id); - let binary = envelope - .payload - .binary - .ok_or_else(|| anyhow!("missing binary"))?; - let binary = LanguageServerBinary { - path: PathBuf::from(binary.path), - env: None, - arguments: binary.arguments.into_iter().map(Into::into).collect(), - }; - this.update(&mut cx, |this, cx| { - let worktree = this.worktree_for_id(worktree_id, cx)?; - let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx); - anyhow::Ok(cx.spawn(|_, _| async move { delegate.try_exec(binary).await })) - })?? - .await?; - - Ok(proto::Ack {}) - } - - pub async fn handle_read_text_file( - this: Model, - envelope: TypedEnvelope, - mut cx: AsyncAppContext, - ) -> Result { - let path = envelope - .payload - .path - .ok_or_else(|| anyhow!("missing path"))?; - let worktree_id = WorktreeId::from_proto(path.worktree_id); - let path = PathBuf::from(path.path); - let response = this - .update(&mut cx, |this, cx| { - let worktree = this.worktree_for_id(worktree_id, cx)?; - let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx); - anyhow::Ok(cx.spawn(|_, _| async move { delegate.read_text_file(path).await })) - })?? - .await?; - - Ok(proto::ReadTextFileResponse { text: response }) - } - async fn handle_apply_additional_edits_for_completion( this: Model, envelope: TypedEnvelope, @@ -5388,89 +5173,6 @@ impl LspStore { .reorder_language_servers(&language, enabled_lsp_adapters); } - fn start_language_server_on_ssh_host( - &mut self, - worktree: &Model, - adapter: Arc, - language: LanguageName, - cx: &mut ModelContext, - ) { - let ssh = self.as_ssh().unwrap(); - - let delegate = Arc::new(SshLspAdapterDelegate { - lsp_store: cx.handle().downgrade(), - worktree: worktree.read(cx).snapshot(), - upstream_client: ssh.upstream_client.clone(), - language_registry: self.languages.clone(), - }) as Arc; - - let Some((upstream_client, project_id)) = self.upstream_client() else { - return; - }; - let worktree_id = worktree.read(cx).id().to_proto(); - let name = adapter.name().to_string(); - - let Some(available_language) = self.languages.available_language_for_name(&language) else { - log::error!("failed to find available language {language}"); - return; - }; - - let user_binary_task = - self.get_language_server_binary(adapter.clone(), delegate.clone(), false, cx); - - let task = cx.spawn(|_, _| async move { - let binary = user_binary_task.await?; - let name = adapter.name(); - let code_action_kinds = adapter - .adapter - .code_action_kinds() - .map(|kinds| serde_json::to_string(&kinds)) - .transpose()?; - let get_options = adapter.adapter.clone().initialization_options(&delegate); - let initialization_options = get_options - .await? - .map(|options| serde_json::to_string(&options)) - .transpose()?; - - let language_server_command = proto::LanguageServerCommand { - path: binary.path.to_string_lossy().to_string(), - arguments: binary - .arguments - .iter() - .map(|args| args.to_string_lossy().to_string()) - .collect(), - env: binary.env.unwrap_or_default().into_iter().collect(), - }; - - upstream_client - .request(proto::CreateLanguageServer { - project_id, - worktree_id, - name: name.0.to_string(), - binary: Some(language_server_command), - initialization_options, - code_action_kinds, - language: Some(proto::AvailableLanguage { - name: language.to_proto(), - matcher: serde_json::to_string(&available_language.matcher())?, - }), - }) - .await - }); - cx.spawn(|this, mut cx| async move { - if let Err(e) = task.await { - this.update(&mut cx, |_this, cx| { - cx.emit(LspStoreEvent::Notification(format!( - "failed to start {}: {}", - name, e - ))) - }) - .ok(); - } - }) - .detach(); - } - fn get_language_server_binary( &self, adapter: Arc, @@ -5558,11 +5260,6 @@ impl LspStore { return; } - if self.mode.is_ssh() { - self.start_language_server_on_ssh_host(worktree_handle, adapter, language, cx); - return; - } - let project_settings = ProjectSettings::get( Some(SettingsLocation { worktree_id, @@ -5852,9 +5549,6 @@ impl LspStore { } else { Task::ready(Vec::new()) } - } else if self.mode.is_ssh() { - // TODO ssh - Task::ready(Vec::new()) } else { Task::ready(Vec::new()) } @@ -7905,116 +7599,6 @@ impl LspAdapterDelegate for LocalLspAdapterDelegate { } } -struct SshLspAdapterDelegate { - lsp_store: WeakModel, - worktree: worktree::Snapshot, - upstream_client: AnyProtoClient, - language_registry: Arc, -} - -#[async_trait] -impl LspAdapterDelegate for SshLspAdapterDelegate { - fn show_notification(&self, message: &str, cx: &mut AppContext) { - self.lsp_store - .update(cx, |_, cx| { - cx.emit(LspStoreEvent::Notification(message.to_owned())) - }) - .ok(); - } - - async fn npm_package_installed_version( - &self, - _package_name: &str, - ) -> Result> { - Ok(None) - } - - fn http_client(&self) -> Arc { - Arc::new(BlockedHttpClient) - } - - fn worktree_id(&self) -> WorktreeId { - self.worktree.id() - } - - fn worktree_root_path(&self) -> &Path { - self.worktree.abs_path().as_ref() - } - - async fn shell_env(&self) -> HashMap { - use rpc::proto::SSH_PROJECT_ID; - - self.upstream_client - .request(proto::ShellEnv { - project_id: SSH_PROJECT_ID, - worktree_id: self.worktree_id().to_proto(), - }) - .await - .map(|response| response.env.into_iter().collect()) - .unwrap_or_default() - } - - async fn which(&self, command: &OsStr) -> Option { - use rpc::proto::SSH_PROJECT_ID; - - self.upstream_client - .request(proto::WhichCommand { - project_id: SSH_PROJECT_ID, - worktree_id: self.worktree_id().to_proto(), - command: command.to_string_lossy().to_string(), - }) - .await - .log_err() - .and_then(|response| response.path) - .map(PathBuf::from) - } - - async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> { - self.upstream_client - .request(proto::TryExec { - project_id: rpc::proto::SSH_PROJECT_ID, - worktree_id: self.worktree.id().to_proto(), - binary: Some(proto::LanguageServerCommand { - path: command.path.to_string_lossy().to_string(), - arguments: command - .arguments - .into_iter() - .map(|s| s.to_string_lossy().to_string()) - .collect(), - env: command.env.unwrap_or_default().into_iter().collect(), - }), - }) - .await?; - Ok(()) - } - - async fn language_server_download_dir(&self, _: &LanguageServerName) -> Option> { - None - } - - fn update_status( - &self, - server_name: LanguageServerName, - status: language::LanguageServerBinaryStatus, - ) { - self.language_registry - .update_lsp_status(server_name, status); - } - - async fn read_text_file(&self, path: PathBuf) -> Result { - self.upstream_client - .request(proto::ReadTextFile { - project_id: rpc::proto::SSH_PROJECT_ID, - path: Some(proto::ProjectPath { - worktree_id: self.worktree.id().to_proto(), - path: path.to_string_lossy().to_string(), - }), - }) - .await - .map(|r| r.text) - } -} - async fn populate_labels_for_symbols( symbols: Vec, language_registry: &Arc, diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 10fd88f286..c3b3c383c1 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -706,11 +706,12 @@ impl Project { let environment = ProjectEnvironment::new(&worktree_store, None, cx); let lsp_store = cx.new_model(|cx| { - LspStore::new_ssh( + LspStore::new_remote( buffer_store.clone(), worktree_store.clone(), languages.clone(), ssh.clone().into(), + SSH_PROJECT_ID, cx, ) }); diff --git a/crates/proto/proto/zed.proto b/crates/proto/proto/zed.proto index 475ed139ed..d81ef35f6b 100644 --- a/crates/proto/proto/zed.proto +++ b/crates/proto/proto/zed.proto @@ -283,18 +283,6 @@ message Envelope { CloseBuffer close_buffer = 245; UpdateUserSettings update_user_settings = 246; - CreateLanguageServer create_language_server = 247; - - WhichCommand which_command = 248; - WhichCommandResponse which_command_response = 249; - - ShellEnv shell_env = 250; - ShellEnvResponse shell_env_response = 251; - - TryExec try_exec = 252; - ReadTextFile read_text_file = 253; - ReadTextFileResponse read_text_file_response = 254; - CheckFileExists check_file_exists = 255; CheckFileExistsResponse check_file_exists_response = 256; // current max } @@ -302,6 +290,7 @@ message Envelope { reserved 158 to 161; reserved 166 to 169; reserved 224 to 229; + reserved 247 to 254; } // Messages @@ -2517,67 +2506,6 @@ message UpdateUserSettings { string content = 2; } -message LanguageServerCommand { - string path = 1; - repeated string arguments = 2; - map env = 3; -} - -message AvailableLanguage { - string name = 7; - string matcher = 8; -} - -message CreateLanguageServer { - uint64 project_id = 1; - uint64 worktree_id = 2; - string name = 3; - - LanguageServerCommand binary = 4; - optional string initialization_options = 5; - optional string code_action_kinds = 6; - - AvailableLanguage language = 7; -} - -message WhichCommand { - uint64 project_id = 1; - uint64 worktree_id = 2; - string command = 3; -} - -message WhichCommandResponse { - optional string path = 1; -} - -message ShellEnv { - uint64 project_id = 1; - uint64 worktree_id = 2; -} - -message ShellEnvResponse { - map env = 1; -} - -message ReadTextFile { - uint64 project_id = 1; - ProjectPath path = 2; -} - -message ReadTextFileResponse { - string text = 1; -} - -message TryExec { - uint64 project_id = 1; - uint64 worktree_id = 2; - LanguageServerCommand binary = 3; -} - -message TryExecResponse { - string text = 1; -} - message CheckFileExists { uint64 project_id = 1; string path = 2; diff --git a/crates/proto/src/proto.rs b/crates/proto/src/proto.rs index 4146a47409..799d51defe 100644 --- a/crates/proto/src/proto.rs +++ b/crates/proto/src/proto.rs @@ -365,14 +365,6 @@ messages!( (FindSearchCandidatesResponse, Background), (CloseBuffer, Foreground), (UpdateUserSettings, Foreground), - (CreateLanguageServer, Foreground), - (WhichCommand, Foreground), - (WhichCommandResponse, Foreground), - (ShellEnv, Foreground), - (ShellEnvResponse, Foreground), - (TryExec, Foreground), - (ReadTextFile, Foreground), - (ReadTextFileResponse, Foreground), (CheckFileExists, Background), (CheckFileExistsResponse, Background) ); @@ -498,11 +490,6 @@ request_messages!( (SynchronizeContexts, SynchronizeContextsResponse), (LspExtSwitchSourceHeader, LspExtSwitchSourceHeaderResponse), (AddWorktree, AddWorktreeResponse), - (CreateLanguageServer, Ack), - (WhichCommand, WhichCommandResponse), - (ShellEnv, ShellEnvResponse), - (ReadTextFile, ReadTextFileResponse), - (TryExec, Ack), (CheckFileExists, CheckFileExistsResponse) ); @@ -577,11 +564,6 @@ entity_messages!( SynchronizeContexts, LspExtSwitchSourceHeader, UpdateUserSettings, - CreateLanguageServer, - WhichCommand, - ShellEnv, - TryExec, - ReadTextFile, CheckFileExists, ); diff --git a/crates/remote_server/Cargo.toml b/crates/remote_server/Cargo.toml index 64db2616e9..b15970042d 100644 --- a/crates/remote_server/Cargo.toml +++ b/crates/remote_server/Cargo.toml @@ -39,6 +39,7 @@ shellexpand.workspace = true smol.workspace = true worktree.workspace = true language.workspace = true +languages.workspace = true util.workspace = true [dev-dependencies] diff --git a/crates/remote_server/src/headless_project.rs b/crates/remote_server/src/headless_project.rs index 84fb22b282..4b13938d8c 100644 --- a/crates/remote_server/src/headless_project.rs +++ b/crates/remote_server/src/headless_project.rs @@ -44,6 +44,10 @@ impl HeadlessProject { pub fn new(session: Arc, fs: Arc, cx: &mut ModelContext) -> Self { let languages = Arc::new(LanguageRegistry::new(cx.background_executor().clone())); + let node_runtime = NodeRuntime::unavailable(); + + languages::init(languages.clone(), node_runtime.clone(), cx); + let worktree_store = cx.new_model(|cx| { let mut store = WorktreeStore::local(true, fs.clone()); store.shared(SSH_PROJECT_ID, session.clone().into(), cx); @@ -56,7 +60,7 @@ impl HeadlessProject { }); let prettier_store = cx.new_model(|cx| { PrettierStore::new( - NodeRuntime::unavailable(), + node_runtime, fs.clone(), languages.clone(), worktree_store.clone(), @@ -116,12 +120,6 @@ impl HeadlessProject { client.add_model_request_handler(BufferStore::handle_update_buffer); client.add_model_message_handler(BufferStore::handle_close_buffer); - client.add_model_request_handler(LspStore::handle_create_language_server); - client.add_model_request_handler(LspStore::handle_which_command); - client.add_model_request_handler(LspStore::handle_shell_env); - client.add_model_request_handler(LspStore::handle_try_exec); - client.add_model_request_handler(LspStore::handle_read_text_file); - BufferStore::init(&client); WorktreeStore::init(&client); SettingsObserver::init(&client); diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index eb8f45d92e..897e0e9a28 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -64,7 +64,7 @@ language.workspace = true language_model.workspace = true language_selector.workspace = true language_tools.workspace = true -languages.workspace = true +languages = {workspace = true, features = ["load-grammars"] } libc.workspace = true log.workspace = true markdown_preview.workspace = true