Detailed changes
@@ -30,7 +30,10 @@ use gpui::{AppContext, AsyncAppContext, Model, SharedString, Task};
pub use highlight_map::HighlightMap;
use http_client::HttpClient;
pub use language_registry::{LanguageName, LoadedLanguage};
-use lsp::{CodeActionKind, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerName};
+use lsp::{
+ CodeActionKind, InitializeParams, LanguageServerBinary, LanguageServerBinaryOptions,
+ LanguageServerName,
+};
use parking_lot::Mutex;
use regex::Regex;
use schemars::{
@@ -484,6 +487,11 @@ pub trait LspAdapter: 'static + Send + Sync {
fn language_ids(&self) -> HashMap<String, String> {
Default::default()
}
+
+ /// Support custom initialize params.
+ fn prepare_initialize_params(&self, original: InitializeParams) -> Result<InitializeParams> {
+ Ok(original)
+ }
}
async fn try_fetch_server_binary<L: LspAdapter + 'static + Send + Sync + ?Sized>(
@@ -4,10 +4,11 @@ use futures::StreamExt;
use gpui::AsyncAppContext;
use http_client::github::{latest_github_release, GitHubLspBinaryVersion};
pub use language::*;
-use lsp::{LanguageServerBinary, LanguageServerName};
+use lsp::{InitializeParams, LanguageServerBinary, LanguageServerName};
+use serde_json::json;
use smol::fs::{self, File};
use std::{any::Any, env::consts, path::PathBuf, sync::Arc};
-use util::{fs::remove_matching, maybe, ResultExt};
+use util::{fs::remove_matching, maybe, merge_json_value_into, ResultExt};
pub struct CLspAdapter;
@@ -257,6 +258,26 @@ impl super::LspAdapter for CLspAdapter {
filter_range,
})
}
+
+ fn prepare_initialize_params(
+ &self,
+ mut original: InitializeParams,
+ ) -> Result<InitializeParams> {
+ // enable clangd's dot-to-arrow feature.
+ let experimental = json!({
+ "textDocument": {
+ "completion" : {
+ "editsNearCursor": true
+ }
+ }
+ });
+ if let Some(ref mut original_experimental) = original.capabilities.experimental {
+ merge_json_value_into(experimental, original_experimental);
+ } else {
+ original.capabilities.experimental = Some(experimental);
+ }
+ Ok(original)
+ }
}
async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
@@ -599,22 +599,14 @@ impl LanguageServer {
Ok(())
}
- /// Initializes a language server by sending the `Initialize` request.
- /// Note that `options` is used directly to construct [`InitializeParams`], which is why it is owned.
- ///
- /// [LSP Specification](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initialize)
- pub fn initialize(
- mut self,
- options: Option<Value>,
- cx: &AppContext,
- ) -> Task<Result<Arc<Self>>> {
+ pub fn default_initialize_params(&self, cx: &AppContext) -> InitializeParams {
let root_uri = Url::from_file_path(&self.working_dir).unwrap();
#[allow(deprecated)]
- let params = InitializeParams {
+ InitializeParams {
process_id: None,
root_path: None,
root_uri: Some(root_uri.clone()),
- initialization_options: options,
+ initialization_options: None,
capabilities: ClientCapabilities {
workspace: Some(WorkspaceClientCapabilities {
configuration: Some(true),
@@ -779,6 +771,22 @@ impl LanguageServer {
}),
locale: None,
..Default::default()
+ }
+ }
+
+ /// Initializes a language server by sending the `Initialize` request.
+ /// Note that `options` is used directly to construct [`InitializeParams`], which is why it is owned.
+ ///
+ /// [LSP Specification](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initialize)
+ pub fn initialize(
+ mut self,
+ initialize_params: Option<InitializeParams>,
+ cx: &AppContext,
+ ) -> Task<Result<Arc<Self>>> {
+ let params = if let Some(params) = initialize_params {
+ params
+ } else {
+ self.default_initialize_params(cx)
};
cx.spawn(|_| async move {
@@ -5673,8 +5673,6 @@ impl LspStore {
.initialization_options(&(delegate))
.await?;
- Self::setup_lsp_messages(this.clone(), &language_server, delegate, adapter);
-
match (&mut initialization_options, override_options) {
(Some(initialization_options), Some(override_options)) => {
merge_json_value_into(override_options, initialization_options);
@@ -5683,8 +5681,18 @@ impl LspStore {
_ => {}
}
+ let initialization_params = cx.update(|cx| {
+ let mut params = language_server.default_initialize_params(cx);
+ params.initialization_options = initialization_options;
+ adapter.adapter.prepare_initialize_params(params)
+ })??;
+
+ Self::setup_lsp_messages(this.clone(), &language_server, delegate, adapter);
+
let language_server = cx
- .update(|cx| language_server.initialize(initialization_options, cx))?
+ .update(|cx| {
+ language_server.initialize(Some(initialization_params), cx)
+ })?
.await
.inspect_err(|_| {
if let Some(this) = this.upgrade() {