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:
parent
ed442cfc8c
commit
1a2e509e35
14 changed files with 204 additions and 146 deletions
|
@ -83,12 +83,17 @@ pub enum ServerExecutionKind {
|
|||
Node,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct LanguageServerBinary {
|
||||
pub path: PathBuf,
|
||||
pub arguments: Vec<String>,
|
||||
}
|
||||
|
||||
/// Represents a Language Server, with certain cached sync properties.
|
||||
/// Uses [`LspAdapter`] under the hood, but calls all 'static' methods
|
||||
/// once at startup, and caches the results.
|
||||
pub struct CachedLspAdapter {
|
||||
pub name: LanguageServerName,
|
||||
pub server_args: Vec<String>,
|
||||
pub initialization_options: Option<Value>,
|
||||
pub disk_based_diagnostic_sources: Vec<String>,
|
||||
pub disk_based_diagnostics_progress_token: Option<String>,
|
||||
|
@ -99,7 +104,6 @@ pub struct CachedLspAdapter {
|
|||
impl CachedLspAdapter {
|
||||
pub async fn new(adapter: Arc<dyn LspAdapter>) -> Arc<Self> {
|
||||
let name = adapter.name().await;
|
||||
let server_args = adapter.server_args().await;
|
||||
let initialization_options = adapter.initialization_options().await;
|
||||
let disk_based_diagnostic_sources = adapter.disk_based_diagnostic_sources().await;
|
||||
let disk_based_diagnostics_progress_token =
|
||||
|
@ -108,7 +112,6 @@ impl CachedLspAdapter {
|
|||
|
||||
Arc::new(CachedLspAdapter {
|
||||
name,
|
||||
server_args,
|
||||
initialization_options,
|
||||
disk_based_diagnostic_sources,
|
||||
disk_based_diagnostics_progress_token,
|
||||
|
@ -129,13 +132,16 @@ impl CachedLspAdapter {
|
|||
version: Box<dyn 'static + Send + Any>,
|
||||
http: Arc<dyn HttpClient>,
|
||||
container_dir: PathBuf,
|
||||
) -> Result<PathBuf> {
|
||||
) -> Result<LanguageServerBinary> {
|
||||
self.adapter
|
||||
.fetch_server_binary(version, http, container_dir)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<PathBuf> {
|
||||
pub async fn cached_server_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
self.adapter.cached_server_binary(container_dir).await
|
||||
}
|
||||
|
||||
|
@ -190,9 +196,9 @@ pub trait LspAdapter: 'static + Send + Sync {
|
|||
version: Box<dyn 'static + Send + Any>,
|
||||
http: Arc<dyn HttpClient>,
|
||||
container_dir: PathBuf,
|
||||
) -> Result<PathBuf>;
|
||||
) -> Result<LanguageServerBinary>;
|
||||
|
||||
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<PathBuf>;
|
||||
async fn cached_server_binary(&self, container_dir: PathBuf) -> Option<LanguageServerBinary>;
|
||||
|
||||
async fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {}
|
||||
|
||||
|
@ -215,10 +221,6 @@ pub trait LspAdapter: 'static + Send + Sync {
|
|||
None
|
||||
}
|
||||
|
||||
async fn server_args(&self) -> Vec<String> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
async fn initialization_options(&self) -> Option<Value> {
|
||||
None
|
||||
}
|
||||
|
@ -497,7 +499,7 @@ pub struct LanguageRegistry {
|
|||
lsp_binary_paths: Mutex<
|
||||
HashMap<
|
||||
LanguageServerName,
|
||||
Shared<BoxFuture<'static, Result<PathBuf, Arc<anyhow::Error>>>>,
|
||||
Shared<BoxFuture<'static, Result<LanguageServerBinary, Arc<anyhow::Error>>>>,
|
||||
>,
|
||||
>,
|
||||
executor: Option<Arc<Background>>,
|
||||
|
@ -810,12 +812,12 @@ impl LanguageRegistry {
|
|||
login_shell_env_loaded.await;
|
||||
let node_path = node_path.await;
|
||||
|
||||
let server_binary_path = this
|
||||
let server_binary = this
|
||||
.lsp_binary_paths
|
||||
.lock()
|
||||
.entry(adapter.name.clone())
|
||||
.or_insert_with(|| {
|
||||
get_server_binary_path(
|
||||
get_server_binary(
|
||||
adapter.clone(),
|
||||
language.clone(),
|
||||
http_client,
|
||||
|
@ -829,8 +831,9 @@ impl LanguageRegistry {
|
|||
.clone()
|
||||
.map_err(|e| anyhow!(e));
|
||||
|
||||
let server_binary_path = server_binary_path.await?;
|
||||
let server_name = server_binary_path
|
||||
let server_binary = server_binary.await?;
|
||||
let server_name = server_binary
|
||||
.path
|
||||
.file_name()
|
||||
.map(|name| name.to_string_lossy().to_string());
|
||||
|
||||
|
@ -839,16 +842,15 @@ impl LanguageRegistry {
|
|||
let node_path = node_path
|
||||
.ok_or(anyhow!("Missing Node path for Node based language server"))?;
|
||||
let node_binary = node_path.join("bin/node");
|
||||
dbg!(&node_binary);
|
||||
let mut command = smol::process::Command::new(node_binary);
|
||||
command.arg(dbg!(server_binary_path));
|
||||
command.arg(dbg!(server_binary.path));
|
||||
command
|
||||
}
|
||||
|
||||
ServerExecutionKind::Launch => smol::process::Command::new(server_binary_path),
|
||||
ServerExecutionKind::Launch => smol::process::Command::new(server_binary.path),
|
||||
};
|
||||
|
||||
command.args(&adapter.server_args);
|
||||
command.args(dbg!(&server_binary.arguments));
|
||||
let server = lsp::LanguageServer::new(server_id, server_name, command, &root_path, cx)?;
|
||||
|
||||
Ok(server)
|
||||
|
@ -880,13 +882,13 @@ impl Default for LanguageRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
async fn get_server_binary_path(
|
||||
async fn get_server_binary(
|
||||
adapter: Arc<CachedLspAdapter>,
|
||||
language: Arc<Language>,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
download_dir: Arc<Path>,
|
||||
statuses: async_broadcast::Sender<(Arc<Language>, LanguageServerBinaryStatus)>,
|
||||
) -> Result<PathBuf> {
|
||||
) -> Result<LanguageServerBinary> {
|
||||
let container_dir = download_dir.join(adapter.name.0.as_ref());
|
||||
if !container_dir.exists() {
|
||||
smol::fs::create_dir_all(&container_dir)
|
||||
|
@ -894,7 +896,7 @@ async fn get_server_binary_path(
|
|||
.context("failed to create container directory")?;
|
||||
}
|
||||
|
||||
let path = fetch_latest_server_binary_path(
|
||||
let binary = fetch_latest_server_binary(
|
||||
adapter.clone(),
|
||||
language.clone(),
|
||||
http_client,
|
||||
|
@ -902,12 +904,12 @@ async fn get_server_binary_path(
|
|||
statuses.clone(),
|
||||
)
|
||||
.await;
|
||||
if let Err(error) = path.as_ref() {
|
||||
if let Some(cached_path) = adapter.cached_server_binary(container_dir).await {
|
||||
if let Err(error) = binary.as_ref() {
|
||||
if let Some(cached) = adapter.cached_server_binary(container_dir).await {
|
||||
statuses
|
||||
.broadcast((language.clone(), LanguageServerBinaryStatus::Cached))
|
||||
.await?;
|
||||
return Ok(cached_path);
|
||||
return Ok(cached);
|
||||
} else {
|
||||
statuses
|
||||
.broadcast((
|
||||
|
@ -919,16 +921,16 @@ async fn get_server_binary_path(
|
|||
.await?;
|
||||
}
|
||||
}
|
||||
path
|
||||
binary
|
||||
}
|
||||
|
||||
async fn fetch_latest_server_binary_path(
|
||||
async fn fetch_latest_server_binary(
|
||||
adapter: Arc<CachedLspAdapter>,
|
||||
language: Arc<Language>,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
container_dir: &Path,
|
||||
lsp_binary_statuses_tx: async_broadcast::Sender<(Arc<Language>, LanguageServerBinaryStatus)>,
|
||||
) -> Result<PathBuf> {
|
||||
) -> Result<LanguageServerBinary> {
|
||||
let container_dir: Arc<Path> = container_dir.into();
|
||||
lsp_binary_statuses_tx
|
||||
.broadcast((
|
||||
|
@ -942,13 +944,13 @@ async fn fetch_latest_server_binary_path(
|
|||
lsp_binary_statuses_tx
|
||||
.broadcast((language.clone(), LanguageServerBinaryStatus::Downloading))
|
||||
.await?;
|
||||
let path = adapter
|
||||
let binary = adapter
|
||||
.fetch_server_binary(version_info, http_client, container_dir.to_path_buf())
|
||||
.await?;
|
||||
lsp_binary_statuses_tx
|
||||
.broadcast((language.clone(), LanguageServerBinaryStatus::Downloaded))
|
||||
.await?;
|
||||
Ok(path)
|
||||
Ok(binary)
|
||||
}
|
||||
|
||||
impl Language {
|
||||
|
@ -1485,11 +1487,11 @@ impl LspAdapter for Arc<FakeLspAdapter> {
|
|||
_: Box<dyn 'static + Send + Any>,
|
||||
_: Arc<dyn HttpClient>,
|
||||
_: PathBuf,
|
||||
) -> Result<PathBuf> {
|
||||
) -> Result<LanguageServerBinary> {
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
async fn cached_server_binary(&self, _: PathBuf) -> Option<PathBuf> {
|
||||
async fn cached_server_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue