Remove server_args from LspAdapter

Prepare to remove concept of a runtime from greater server startup code,
which is important for future language server extensibility

Co-Authored-By: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
Julia 2023-03-24 10:40:50 -04:00
parent ed442cfc8c
commit 1a2e509e35
14 changed files with 204 additions and 146 deletions

View file

@ -43,7 +43,7 @@ impl super::LspAdapter for CLspAdapter {
version: Box<dyn 'static + Send + Any>,
http: Arc<dyn HttpClient>,
container_dir: PathBuf,
) -> Result<PathBuf> {
) -> Result<LanguageServerBinary> {
let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
let zip_path = container_dir.join(format!("clangd_{}.zip", version.name));
let version_dir = container_dir.join(format!("clangd_{}", version.name));
@ -85,10 +85,13 @@ impl super::LspAdapter for CLspAdapter {
}
}
Ok(binary_path)
Ok(LanguageServerBinary {
path: binary_path,
arguments: vec![],
})
}
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<PathBuf> {
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
(|| async move {
let mut last_clangd_dir = None;
let mut entries = fs::read_dir(&container_dir).await?;
@ -101,7 +104,10 @@ impl super::LspAdapter for CLspAdapter {
let clangd_dir = last_clangd_dir.ok_or_else(|| anyhow!("no cached binary"))?;
let clangd_bin = clangd_dir.join("bin/clangd");
if clangd_bin.exists() {
Ok(clangd_bin)
Ok(LanguageServerBinary {
path: clangd_bin,
arguments: vec![],
})
} else {
Err(anyhow!(
"missing clangd binary in directory {:?}",

View file

@ -44,7 +44,7 @@ impl LspAdapter for ElixirLspAdapter {
version: Box<dyn 'static + Send + Any>,
http: Arc<dyn HttpClient>,
container_dir: PathBuf,
) -> Result<PathBuf> {
) -> Result<LanguageServerBinary> {
let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
let zip_path = container_dir.join(format!("elixir-ls_{}.zip", version.name));
let version_dir = container_dir.join(format!("elixir-ls_{}", version.name));
@ -98,17 +98,24 @@ impl LspAdapter for ElixirLspAdapter {
}
}
Ok(binary_path)
Ok(LanguageServerBinary {
path: binary_path,
arguments: vec![],
})
}
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<PathBuf> {
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
(|| async move {
let mut last = None;
let mut entries = fs::read_dir(&container_dir).await?;
while let Some(entry) = entries.next().await {
last = Some(entry?.path());
}
last.ok_or_else(|| anyhow!("no cached binary"))
last.map(|path| LanguageServerBinary {
path,
arguments: vec![],
})
.ok_or_else(|| anyhow!("no cached binary"))
})()
.await
.log_err()

View file

@ -10,6 +10,10 @@ use smol::{fs, process};
use std::{any::Any, ops::Range, path::PathBuf, str, sync::Arc};
use util::ResultExt;
fn server_binary_arguments() -> Vec<String> {
vec!["-mode=stdio".into()]
}
#[derive(Copy, Clone)]
pub struct GoLspAdapter;
@ -27,10 +31,6 @@ impl super::LspAdapter for GoLspAdapter {
ServerExecutionKind::Launch
}
async fn server_args(&self) -> Vec<String> {
vec!["-mode=stdio".into()]
}
async fn fetch_latest_server_version(
&self,
http: Arc<dyn HttpClient>,
@ -51,7 +51,7 @@ impl super::LspAdapter for GoLspAdapter {
version: Box<dyn 'static + Send + Any>,
_: Arc<dyn HttpClient>,
container_dir: PathBuf,
) -> Result<PathBuf> {
) -> Result<LanguageServerBinary> {
let version = version.downcast::<Option<String>>().unwrap();
let this = *self;
@ -72,7 +72,10 @@ impl super::LspAdapter for GoLspAdapter {
}
}
return Ok(binary_path.to_path_buf());
return Ok(LanguageServerBinary {
path: binary_path.to_path_buf(),
arguments: server_binary_arguments(),
});
}
}
} else if let Some(path) = this.cached_server_binary(container_dir.clone()).await {
@ -106,10 +109,13 @@ impl super::LspAdapter for GoLspAdapter {
let binary_path = container_dir.join(&format!("gopls_{version}"));
fs::rename(&installed_binary_path, &binary_path).await?;
Ok(binary_path.to_path_buf())
Ok(LanguageServerBinary {
path: binary_path.to_path_buf(),
arguments: server_binary_arguments(),
})
}
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<PathBuf> {
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
(|| async move {
let mut last_binary_path = None;
let mut entries = fs::read_dir(&container_dir).await?;
@ -126,7 +132,10 @@ impl super::LspAdapter for GoLspAdapter {
}
if let Some(path) = last_binary_path {
Ok(path)
Ok(LanguageServerBinary {
path,
arguments: server_binary_arguments(),
})
} else {
Err(anyhow!("no cached binary"))
}

View file

@ -3,12 +3,16 @@ use anyhow::{anyhow, Context, Result};
use async_trait::async_trait;
use client::http::HttpClient;
use futures::StreamExt;
use language::{LanguageServerName, LspAdapter, ServerExecutionKind};
use language::{LanguageServerBinary, LanguageServerName, LspAdapter, ServerExecutionKind};
use serde_json::json;
use smol::fs;
use std::{any::Any, path::PathBuf, sync::Arc};
use util::ResultExt;
fn server_binary_arguments() -> Vec<String> {
vec!["--stdio".into()]
}
pub struct HtmlLspAdapter;
impl HtmlLspAdapter {
@ -26,10 +30,6 @@ impl LspAdapter for HtmlLspAdapter {
ServerExecutionKind::Node
}
async fn server_args(&self) -> Vec<String> {
vec!["--stdio".into()]
}
async fn fetch_latest_server_version(
&self,
http: Arc<dyn HttpClient>,
@ -45,7 +45,7 @@ impl LspAdapter for HtmlLspAdapter {
version: Box<dyn 'static + Send + Any>,
http: Arc<dyn HttpClient>,
container_dir: PathBuf,
) -> Result<PathBuf> {
) -> Result<LanguageServerBinary> {
let version = version.downcast::<String>().unwrap();
let version_dir = container_dir.join(version.as_str());
fs::create_dir_all(&version_dir)
@ -73,10 +73,13 @@ impl LspAdapter for HtmlLspAdapter {
}
}
Ok(binary_path)
Ok(LanguageServerBinary {
path: binary_path,
arguments: server_binary_arguments(),
})
}
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<PathBuf> {
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
(|| async move {
let mut last_version_dir = None;
let mut entries = fs::read_dir(&container_dir).await?;
@ -89,7 +92,10 @@ impl LspAdapter for HtmlLspAdapter {
let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?;
let bin_path = last_version_dir.join(Self::BIN_PATH);
if bin_path.exists() {
Ok(bin_path)
Ok(LanguageServerBinary {
path: bin_path,
arguments: server_binary_arguments(),
})
} else {
Err(anyhow!(
"missing executable in directory {:?}",

View file

@ -48,8 +48,8 @@ pub async fn ensure_node_installation_dir(http: Arc<dyn HttpClient>) -> Result<P
let arch = "arm64";
let folder_name = format!("node-{version}-darwin-{arch}");
let node_containing_dir = dbg!(util::paths::SUPPORT_DIR.join("node"));
let node_dir = dbg!(node_containing_dir.join(folder_name));
let node_containing_dir = util::paths::SUPPORT_DIR.join("node");
let node_dir = node_containing_dir.join(folder_name);
let node_binary = node_dir.join("bin/node");
if fs::metadata(&node_binary).await.is_err() {
@ -59,7 +59,6 @@ pub async fn ensure_node_installation_dir(http: Arc<dyn HttpClient>) -> Result<P
.context("error creating node containing dir")?;
let url = format!("https://nodejs.org/dist/{version}/node-{version}-darwin-{arch}.tar.gz");
dbg!(&url);
let mut response = http
.get(&url, Default::default(), true)
.await
@ -71,8 +70,7 @@ pub async fn ensure_node_installation_dir(http: Arc<dyn HttpClient>) -> Result<P
eprintln!("unpacked");
}
eprintln!("returning");
Ok(dbg!(node_dir))
Ok(node_dir)
}
pub async fn npm_package_latest_version(http: Arc<dyn HttpClient>, name: &str) -> Result<String> {

View file

@ -6,7 +6,9 @@ use client::http::HttpClient;
use collections::HashMap;
use futures::{future::BoxFuture, io::BufReader, FutureExt, StreamExt};
use gpui::MutableAppContext;
use language::{LanguageRegistry, LanguageServerName, LspAdapter, ServerExecutionKind};
use language::{
LanguageRegistry, LanguageServerBinary, LanguageServerName, LspAdapter, ServerExecutionKind,
};
use serde_json::json;
use settings::{keymap_file_json_schema, settings_file_json_schema};
use smol::fs::{self, File};
@ -20,6 +22,10 @@ use std::{
use theme::ThemeRegistry;
use util::{paths, ResultExt, StaffMode};
fn server_binary_arguments() -> Vec<String> {
vec!["--stdio".into()]
}
pub struct JsonLspAdapter {
languages: Arc<LanguageRegistry>,
themes: Arc<ThemeRegistry>,
@ -41,10 +47,6 @@ impl LspAdapter for JsonLspAdapter {
ServerExecutionKind::Node
}
async fn server_args(&self) -> Vec<String> {
vec!["--stdio".into()]
}
async fn fetch_latest_server_version(
&self,
http: Arc<dyn HttpClient>,
@ -68,7 +70,7 @@ impl LspAdapter for JsonLspAdapter {
version: Box<dyn 'static + Send + Any>,
http: Arc<dyn HttpClient>,
container_dir: PathBuf,
) -> Result<PathBuf> {
) -> Result<LanguageServerBinary> {
let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
let destination_path = container_dir.join(format!(
"json-language-server-{}-{}",
@ -102,17 +104,23 @@ impl LspAdapter for JsonLspAdapter {
}
}
Ok(destination_path)
Ok(LanguageServerBinary {
path: destination_path,
arguments: server_binary_arguments(),
})
}
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<PathBuf> {
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
(|| async move {
let mut last = None;
let mut entries = fs::read_dir(&container_dir).await?;
while let Some(entry) = entries.next().await {
last = Some(entry?.path());
}
last.ok_or_else(|| anyhow!("no cached binary"))
anyhow::Ok(LanguageServerBinary {
path: last.ok_or_else(|| anyhow!("no cached binary"))?,
arguments: server_binary_arguments(),
})
})()
.await
.log_err()

View file

@ -4,7 +4,7 @@ use client::http::HttpClient;
use collections::HashMap;
use futures::lock::Mutex;
use gpui::executor::Background;
use language::{LanguageServerName, LspAdapter, ServerExecutionKind};
use language::{LanguageServerBinary, LanguageServerName, LspAdapter, ServerExecutionKind};
use plugin_runtime::{Plugin, PluginBinary, PluginBuilder, WasiFn};
use std::{any::Any, path::PathBuf, sync::Arc};
use util::ResultExt;
@ -33,10 +33,9 @@ pub async fn new_json(executor: Arc<Background>) -> Result<PluginLspAdapter> {
pub struct PluginLspAdapter {
name: WasiFn<(), String>,
server_execution_kind: WasiFn<(), ServerExecutionKind>,
server_args: WasiFn<(), Vec<String>>,
fetch_latest_server_version: WasiFn<(), Option<String>>,
fetch_server_binary: WasiFn<(PathBuf, String), Result<PathBuf, String>>,
cached_server_binary: WasiFn<PathBuf, Option<PathBuf>>,
fetch_server_binary: WasiFn<(PathBuf, String), Result<LanguageServerBinary, String>>,
cached_server_binary: WasiFn<PathBuf, Option<LanguageServerBinary>>,
initialization_options: WasiFn<(), String>,
language_ids: WasiFn<(), Vec<(String, String)>>,
executor: Arc<Background>,
@ -49,7 +48,6 @@ impl PluginLspAdapter {
Ok(Self {
name: plugin.function("name")?,
server_execution_kind: plugin.function("server_execution_kind")?,
server_args: plugin.function("server_args")?,
fetch_latest_server_version: plugin.function("fetch_latest_server_version")?,
fetch_server_binary: plugin.function("fetch_server_binary")?,
cached_server_binary: plugin.function("cached_server_binary")?,
@ -83,15 +81,6 @@ impl LspAdapter for PluginLspAdapter {
.unwrap()
}
async fn server_args<'a>(&'a self) -> Vec<String> {
self.runtime
.lock()
.await
.call(&self.server_args, ())
.await
.unwrap()
}
async fn fetch_latest_server_version(
&self,
_: Arc<dyn HttpClient>,
@ -116,7 +105,7 @@ impl LspAdapter for PluginLspAdapter {
version: Box<dyn 'static + Send + Any>,
_: Arc<dyn HttpClient>,
container_dir: PathBuf,
) -> Result<PathBuf> {
) -> Result<LanguageServerBinary> {
let version = *version.downcast::<String>().unwrap();
let runtime = self.runtime.clone();
let function = self.fetch_server_binary;
@ -124,7 +113,7 @@ impl LspAdapter for PluginLspAdapter {
.spawn(async move {
let mut runtime = runtime.lock().await;
let handle = runtime.attach_path(&container_dir)?;
let result: Result<PathBuf, String> =
let result: Result<LanguageServerBinary, String> =
runtime.call(&function, (container_dir, version)).await?;
runtime.remove_resource(handle)?;
result.map_err(|e| anyhow!("{}", e))
@ -132,7 +121,7 @@ impl LspAdapter for PluginLspAdapter {
.await
}
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<PathBuf> {
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
let runtime = self.runtime.clone();
let function = self.cached_server_binary;
@ -140,7 +129,8 @@ impl LspAdapter for PluginLspAdapter {
.spawn(async move {
let mut runtime = runtime.lock().await;
let handle = runtime.attach_path(&container_dir).ok()?;
let result: Option<PathBuf> = runtime.call(&function, container_dir).await.ok()?;
let result: Option<LanguageServerBinary> =
runtime.call(&function, container_dir).await.ok()?;
runtime.remove_resource(handle).ok()?;
result
})

View file

@ -6,7 +6,7 @@ use async_tar::Archive;
use async_trait::async_trait;
use client::http::HttpClient;
use futures::{io::BufReader, StreamExt};
use language::{LanguageServerName, ServerExecutionKind};
use language::{LanguageServerBinary, LanguageServerName, ServerExecutionKind};
use smol::fs;
use util::{async_iife, ResultExt};
@ -15,6 +15,13 @@ use super::installation::{latest_github_release, GitHubLspBinaryVersion};
#[derive(Copy, Clone)]
pub struct LuaLspAdapter;
fn server_binary_arguments() -> Vec<String> {
vec![
"--logpath=~/lua-language-server.log".into(),
"--loglevel=trace".into(),
]
}
#[async_trait]
impl super::LspAdapter for LuaLspAdapter {
async fn name(&self) -> LanguageServerName {
@ -25,13 +32,6 @@ impl super::LspAdapter for LuaLspAdapter {
ServerExecutionKind::Launch
}
async fn server_args(&self) -> Vec<String> {
vec![
"--logpath=~/lua-language-server.log".into(),
"--loglevel=trace".into(),
]
}
async fn fetch_latest_server_version(
&self,
http: Arc<dyn HttpClient>,
@ -61,7 +61,7 @@ impl super::LspAdapter for LuaLspAdapter {
version: Box<dyn 'static + Send + Any>,
http: Arc<dyn HttpClient>,
container_dir: PathBuf,
) -> Result<PathBuf> {
) -> Result<LanguageServerBinary> {
let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
let binary_path = container_dir.join("bin/lua-language-server");
@ -81,10 +81,13 @@ impl super::LspAdapter for LuaLspAdapter {
<fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
)
.await?;
Ok(binary_path)
Ok(LanguageServerBinary {
path: binary_path,
arguments: server_binary_arguments(),
})
}
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<PathBuf> {
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
async_iife!({
let mut last_binary_path = None;
let mut entries = fs::read_dir(&container_dir).await?;
@ -101,7 +104,10 @@ impl super::LspAdapter for LuaLspAdapter {
}
if let Some(path) = last_binary_path {
Ok(path)
Ok(LanguageServerBinary {
path,
arguments: server_binary_arguments(),
})
} else {
Err(anyhow!("no cached binary"))
}

View file

@ -3,13 +3,17 @@ use anyhow::{anyhow, Context, Result};
use async_trait::async_trait;
use client::http::HttpClient;
use futures::StreamExt;
use language::{LanguageServerName, LspAdapter, ServerExecutionKind};
use language::{LanguageServerBinary, LanguageServerName, LspAdapter, ServerExecutionKind};
use smol::fs;
use std::{any::Any, path::PathBuf, sync::Arc};
use util::ResultExt;
pub struct PythonLspAdapter;
fn server_binary_arguments() -> Vec<String> {
vec!["--stdio".into()]
}
impl PythonLspAdapter {
const BIN_PATH: &'static str = "node_modules/pyright/langserver.index.js";
}
@ -24,10 +28,6 @@ impl LspAdapter for PythonLspAdapter {
ServerExecutionKind::Node
}
async fn server_args(&self) -> Vec<String> {
vec!["--stdio".into()]
}
async fn fetch_latest_server_version(
&self,
http: Arc<dyn HttpClient>,
@ -40,7 +40,7 @@ impl LspAdapter for PythonLspAdapter {
version: Box<dyn 'static + Send + Any>,
http: Arc<dyn HttpClient>,
container_dir: PathBuf,
) -> Result<PathBuf> {
) -> Result<LanguageServerBinary> {
let version = version.downcast::<String>().unwrap();
let version_dir = container_dir.join(version.as_str());
fs::create_dir_all(&version_dir)
@ -63,10 +63,13 @@ impl LspAdapter for PythonLspAdapter {
}
}
Ok(binary_path)
Ok(LanguageServerBinary {
path: binary_path,
arguments: server_binary_arguments(),
})
}
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<PathBuf> {
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
(|| async move {
let mut last_version_dir = None;
let mut entries = fs::read_dir(&container_dir).await?;
@ -79,7 +82,10 @@ impl LspAdapter for PythonLspAdapter {
let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?;
let bin_path = last_version_dir.join(Self::BIN_PATH);
if bin_path.exists() {
Ok(bin_path)
Ok(LanguageServerBinary {
path: bin_path,
arguments: server_binary_arguments(),
})
} else {
Err(anyhow!(
"missing executable in directory {:?}",

View file

@ -1,7 +1,7 @@
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use client::http::HttpClient;
use language::{LanguageServerName, LspAdapter, ServerExecutionKind};
use language::{LanguageServerBinary, LanguageServerName, LspAdapter, ServerExecutionKind};
use std::{any::Any, path::PathBuf, sync::Arc};
pub struct RubyLanguageServer;
@ -16,10 +16,6 @@ impl LspAdapter for RubyLanguageServer {
ServerExecutionKind::Launch
}
async fn server_args(&self) -> Vec<String> {
vec!["stdio".into()]
}
async fn fetch_latest_server_version(
&self,
_: Arc<dyn HttpClient>,
@ -32,12 +28,15 @@ impl LspAdapter for RubyLanguageServer {
_version: Box<dyn 'static + Send + Any>,
_: Arc<dyn HttpClient>,
_container_dir: PathBuf,
) -> Result<PathBuf> {
) -> Result<LanguageServerBinary> {
Err(anyhow!("solargraph must be installed manually"))
}
async fn cached_server_binary(&self, _container_dir: PathBuf) -> Option<PathBuf> {
Some("solargraph".into())
async fn cached_server_binary(&self, _container_dir: PathBuf) -> Option<LanguageServerBinary> {
Some(LanguageServerBinary {
path: "solargraph".into(),
arguments: vec!["stdio".into()],
})
}
async fn label_for_completion(

View file

@ -46,7 +46,7 @@ impl LspAdapter for RustLspAdapter {
version: Box<dyn 'static + Send + Any>,
http: Arc<dyn HttpClient>,
container_dir: PathBuf,
) -> Result<PathBuf> {
) -> Result<LanguageServerBinary> {
let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
let destination_path = container_dir.join(format!("rust-analyzer-{}", version.name));
@ -76,17 +76,23 @@ impl LspAdapter for RustLspAdapter {
}
}
Ok(destination_path)
Ok(LanguageServerBinary {
path: destination_path,
arguments: Default::default(),
})
}
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<PathBuf> {
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
(|| async move {
let mut last = None;
let mut entries = fs::read_dir(&container_dir).await?;
while let Some(entry) = entries.next().await {
last = Some(entry?.path());
}
last.ok_or_else(|| anyhow!("no cached binary"))
anyhow::Ok(LanguageServerBinary {
path: last.ok_or_else(|| anyhow!("no cached binary"))?,
arguments: Default::default(),
})
})()
.await
.log_err()

View file

@ -3,12 +3,19 @@ use anyhow::{anyhow, Context, Result};
use async_trait::async_trait;
use client::http::HttpClient;
use futures::StreamExt;
use language::{LanguageServerName, LspAdapter, ServerExecutionKind};
use language::{LanguageServerBinary, LanguageServerName, LspAdapter, ServerExecutionKind};
use serde_json::json;
use smol::fs;
use std::{any::Any, path::PathBuf, sync::Arc};
use util::ResultExt;
fn server_binary_arguments() -> Vec<String> {
["--stdio", "--tsserver-path", "node_modules/typescript/lib"]
.into_iter()
.map(Into::into)
.collect()
}
pub struct TypeScriptLspAdapter;
impl TypeScriptLspAdapter {
@ -31,13 +38,6 @@ impl LspAdapter for TypeScriptLspAdapter {
ServerExecutionKind::Node
}
async fn server_args(&self) -> Vec<String> {
["--stdio", "--tsserver-path", "node_modules/typescript/lib"]
.into_iter()
.map(str::to_string)
.collect()
}
async fn fetch_latest_server_version(
&self,
http: Arc<dyn HttpClient>,
@ -53,7 +53,7 @@ impl LspAdapter for TypeScriptLspAdapter {
versions: Box<dyn 'static + Send + Any>,
http: Arc<dyn HttpClient>,
container_dir: PathBuf,
) -> Result<PathBuf> {
) -> Result<LanguageServerBinary> {
let versions = versions.downcast::<Versions>().unwrap();
let version_dir = container_dir.join(&format!(
"typescript-{}:server-{}",
@ -90,10 +90,13 @@ impl LspAdapter for TypeScriptLspAdapter {
}
}
Ok(binary_path)
Ok(LanguageServerBinary {
path: binary_path,
arguments: server_binary_arguments(),
})
}
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<PathBuf> {
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
(|| async move {
let mut last_version_dir = None;
let mut entries = fs::read_dir(&container_dir).await?;
@ -107,9 +110,15 @@ impl LspAdapter for TypeScriptLspAdapter {
let old_bin_path = last_version_dir.join(Self::OLD_BIN_PATH);
let new_bin_path = last_version_dir.join(Self::NEW_BIN_PATH);
if new_bin_path.exists() {
Ok(new_bin_path)
Ok(LanguageServerBinary {
path: new_bin_path,
arguments: server_binary_arguments(),
})
} else if old_bin_path.exists() {
Ok(old_bin_path)
Ok(LanguageServerBinary {
path: old_bin_path,
arguments: server_binary_arguments(),
})
} else {
Err(anyhow!(
"missing executable in directory {:?}",

View file

@ -3,7 +3,7 @@ use async_trait::async_trait;
use client::http::HttpClient;
use futures::{future::BoxFuture, FutureExt, StreamExt};
use gpui::MutableAppContext;
use language::{LanguageServerName, LspAdapter, ServerExecutionKind};
use language::{LanguageServerBinary, LanguageServerName, LspAdapter, ServerExecutionKind};
use serde_json::Value;
use settings::Settings;
use smol::fs;
@ -12,6 +12,10 @@ use util::ResultExt;
use super::installation::{npm_install_packages, npm_package_latest_version};
fn server_binary_arguments() -> Vec<String> {
vec!["--stdio".into()]
}
pub struct YamlLspAdapter;
impl YamlLspAdapter {
@ -28,10 +32,6 @@ impl LspAdapter for YamlLspAdapter {
ServerExecutionKind::Node
}
async fn server_args(&self) -> Vec<String> {
vec!["--stdio".into()]
}
async fn fetch_latest_server_version(
&self,
http: Arc<dyn HttpClient>,
@ -44,7 +44,7 @@ impl LspAdapter for YamlLspAdapter {
version: Box<dyn 'static + Send + Any>,
http: Arc<dyn HttpClient>,
container_dir: PathBuf,
) -> Result<PathBuf> {
) -> Result<LanguageServerBinary> {
let version = version.downcast::<String>().unwrap();
let version_dir = container_dir.join(version.as_str());
fs::create_dir_all(&version_dir)
@ -72,10 +72,13 @@ impl LspAdapter for YamlLspAdapter {
}
}
Ok(binary_path)
Ok(LanguageServerBinary {
path: binary_path,
arguments: server_binary_arguments(),
})
}
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<PathBuf> {
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary> {
(|| async move {
let mut last_version_dir = None;
let mut entries = fs::read_dir(&container_dir).await?;
@ -88,7 +91,10 @@ impl LspAdapter for YamlLspAdapter {
let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?;
let bin_path = last_version_dir.join(Self::BIN_PATH);
if bin_path.exists() {
Ok(bin_path)
Ok(LanguageServerBinary {
path: bin_path,
arguments: server_binary_arguments(),
})
} else {
Err(anyhow!(
"missing executable in directory {:?}",