Cargo.lock 🔗
@@ -9122,6 +9122,7 @@ dependencies = [
"gpui",
"http_client",
"language",
+ "languages",
"log",
"lsp",
"node_runtime",
Conrad Irwin and Mikayla created
Release Notes:
- ssh remoting: run LSP Adapters on host
---------
Co-authored-by: Mikayla <mikayla@zed.dev>
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(-)
@@ -9122,6 +9122,7 @@ dependencies = [
"gpui",
"http_client",
"language",
+ "languages",
"log",
"lsp",
"node_runtime",
@@ -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"] }
@@ -31,6 +31,7 @@ mod yaml;
struct LanguageDir;
pub fn init(languages: Arc<LanguageRegistry>, 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 {
@@ -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<LanguageServerName, LspSettings>,
-}
+// pub struct SshLspStore {
+// upstream_client: AnyProtoClient,
+// current_lsp_settings: HashMap<LanguageServerName, LspSettings>,
+// }
#[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<LanguageServerName, LspSettings>,
) -> Option<HashMap<LanguageServerName, LspSettings>> {
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<BufferStore>,
- worktree_store: Model<WorktreeStore>,
- languages: Arc<LanguageRegistry>,
- upstream_client: AnyProtoClient,
- cx: &mut ModelContext<Self>,
- ) -> Self {
- cx.subscribe(&buffer_store, Self::on_buffer_store_event)
- .detach();
- cx.subscribe(&worktree_store, Self::on_worktree_store_event)
- .detach();
- cx.observe_global::<SettingsStore>(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<BufferStore>,
worktree_store: Model<WorktreeStore>,
@@ -3697,11 +3641,11 @@ impl LspStore {
mut cx: AsyncAppContext,
) -> Result<proto::MultiLspQueryResponse> {
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<Self>,
- envelope: TypedEnvelope<proto::CreateLanguageServer>,
- mut cx: AsyncAppContext,
- ) -> Result<proto::Ack> {
- 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<Self>,
- envelope: TypedEnvelope<proto::WhichCommand>,
- mut cx: AsyncAppContext,
- ) -> Result<proto::WhichCommandResponse> {
- 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<Self>,
- envelope: TypedEnvelope<proto::ShellEnv>,
- mut cx: AsyncAppContext,
- ) -> Result<proto::ShellEnvResponse> {
- 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<Self>,
- envelope: TypedEnvelope<proto::TryExec>,
- mut cx: AsyncAppContext,
- ) -> Result<proto::Ack> {
- 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<Self>,
- envelope: TypedEnvelope<proto::ReadTextFile>,
- mut cx: AsyncAppContext,
- ) -> Result<proto::ReadTextFileResponse> {
- 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<Self>,
envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
@@ -5388,89 +5173,6 @@ impl LspStore {
.reorder_language_servers(&language, enabled_lsp_adapters);
}
- fn start_language_server_on_ssh_host(
- &mut self,
- worktree: &Model<Worktree>,
- adapter: Arc<CachedLspAdapter>,
- language: LanguageName,
- cx: &mut ModelContext<Self>,
- ) {
- 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<dyn LspAdapterDelegate>;
-
- 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<CachedLspAdapter>,
@@ -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<LspStore>,
- worktree: worktree::Snapshot,
- upstream_client: AnyProtoClient,
- language_registry: Arc<LanguageRegistry>,
-}
-
-#[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<Option<(PathBuf, String)>> {
- Ok(None)
- }
-
- fn http_client(&self) -> Arc<dyn HttpClient> {
- 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<String, String> {
- 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<PathBuf> {
- 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<Arc<Path>> {
- 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<String> {
- 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<CoreSymbol>,
language_registry: &Arc<LanguageRegistry>,
@@ -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,
)
});
@@ -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<string, string> 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<string, string> 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;
@@ -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,
);
@@ -39,6 +39,7 @@ shellexpand.workspace = true
smol.workspace = true
worktree.workspace = true
language.workspace = true
+languages.workspace = true
util.workspace = true
[dev-dependencies]
@@ -44,6 +44,10 @@ impl HeadlessProject {
pub fn new(session: Arc<SshSession>, fs: Arc<dyn Fs>, cx: &mut ModelContext<Self>) -> 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);
@@ -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