Compare commits
10 commits
main
...
fix-none-r
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fa2e24fcc7 | ||
![]() |
11a5d86999 | ||
![]() |
31076619b3 | ||
![]() |
ae6b79a398 | ||
![]() |
e047398756 | ||
![]() |
6f69765172 | ||
![]() |
3410652c71 | ||
![]() |
0617098175 | ||
![]() |
7684bc265b | ||
![]() |
cdb4db55da |
3 changed files with 195 additions and 139 deletions
98
crates/lsp/src/capabilities.rs
Normal file
98
crates/lsp/src/capabilities.rs
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
use lsp_types::{
|
||||||
|
ServerCapabilities, TextDocumentSyncCapability, TextDocumentSyncKind,
|
||||||
|
TextDocumentSyncSaveOptions,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::DynamicCapabilities;
|
||||||
|
|
||||||
|
pub mod cap {
|
||||||
|
pub struct DidChangeTextDocument;
|
||||||
|
pub struct DidSaveTextDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait EffectiveCapability {
|
||||||
|
type Value;
|
||||||
|
fn compute(static_caps: &ServerCapabilities, dynamic_caps: &DynamicCapabilities)
|
||||||
|
-> Self::Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EffectiveCapability for cap::DidChangeTextDocument {
|
||||||
|
type Value = Option<TextDocumentSyncKind>;
|
||||||
|
|
||||||
|
fn compute(
|
||||||
|
static_caps: &ServerCapabilities,
|
||||||
|
dynamic_caps: &DynamicCapabilities,
|
||||||
|
) -> Self::Value {
|
||||||
|
dynamic_caps
|
||||||
|
.text_document_sync_did_change
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|id_to_sync_kind_map| {
|
||||||
|
if id_to_sync_kind_map.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let mut has_incremental = false;
|
||||||
|
for data in id_to_sync_kind_map.values() {
|
||||||
|
let sync_kind = match data.sync_kind {
|
||||||
|
0 => Some(TextDocumentSyncKind::NONE),
|
||||||
|
1 => Some(TextDocumentSyncKind::FULL),
|
||||||
|
2 => Some(TextDocumentSyncKind::INCREMENTAL),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
if sync_kind == Some(TextDocumentSyncKind::FULL) {
|
||||||
|
return Some(TextDocumentSyncKind::FULL);
|
||||||
|
}
|
||||||
|
if sync_kind == Some(TextDocumentSyncKind::INCREMENTAL) {
|
||||||
|
has_incremental = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if has_incremental {
|
||||||
|
Some(TextDocumentSyncKind::INCREMENTAL)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
static_caps
|
||||||
|
.text_document_sync
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|sync| match sync {
|
||||||
|
TextDocumentSyncCapability::Kind(kind) => Some(*kind),
|
||||||
|
TextDocumentSyncCapability::Options(opts) => opts.change,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EffectiveCapability for cap::DidSaveTextDocument {
|
||||||
|
type Value = Option<bool>;
|
||||||
|
|
||||||
|
fn compute(
|
||||||
|
static_caps: &ServerCapabilities,
|
||||||
|
dynamic_caps: &DynamicCapabilities,
|
||||||
|
) -> Self::Value {
|
||||||
|
dynamic_caps
|
||||||
|
.text_document_sync_did_save
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|id_to_save_options_map| {
|
||||||
|
if id_to_save_options_map.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(
|
||||||
|
id_to_save_options_map
|
||||||
|
.values()
|
||||||
|
.any(|data| data.include_text.unwrap_or(false)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.or_else(|| match static_caps.text_document_sync.as_ref()? {
|
||||||
|
TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
|
||||||
|
TextDocumentSyncSaveOptions::Supported(true) => Some(false),
|
||||||
|
TextDocumentSyncSaveOptions::Supported(false) => None,
|
||||||
|
TextDocumentSyncSaveOptions::SaveOptions(save_opts) => {
|
||||||
|
Some(save_opts.include_text.unwrap_or(false))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TextDocumentSyncCapability::Kind(_) => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,8 @@
|
||||||
|
mod capabilities;
|
||||||
mod input_handler;
|
mod input_handler;
|
||||||
|
|
||||||
|
pub use capabilities::{EffectiveCapability, cap};
|
||||||
|
|
||||||
pub use lsp_types::request::*;
|
pub use lsp_types::request::*;
|
||||||
pub use lsp_types::*;
|
pub use lsp_types::*;
|
||||||
|
|
||||||
|
@ -86,7 +89,8 @@ pub struct LanguageServer {
|
||||||
name: LanguageServerName,
|
name: LanguageServerName,
|
||||||
process_name: Arc<str>,
|
process_name: Arc<str>,
|
||||||
binary: LanguageServerBinary,
|
binary: LanguageServerBinary,
|
||||||
capabilities: RwLock<ServerCapabilities>,
|
static_capabilities: RwLock<ServerCapabilities>,
|
||||||
|
dynamic_capabilities: RwLock<DynamicCapabilities>,
|
||||||
/// Configuration sent to the server, stored for display in the language server logs
|
/// Configuration sent to the server, stored for display in the language server logs
|
||||||
/// buffer. This is represented as the message sent to the LSP in order to avoid cloning it (can
|
/// buffer. This is represented as the message sent to the LSP in order to avoid cloning it (can
|
||||||
/// be large in cases like sending schemas to the json server).
|
/// be large in cases like sending schemas to the json server).
|
||||||
|
@ -301,6 +305,13 @@ pub struct AdapterServerCapabilities {
|
||||||
pub code_action_kinds: Option<Vec<CodeActionKind>>,
|
pub code_action_kinds: Option<Vec<CodeActionKind>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
pub struct DynamicCapabilities {
|
||||||
|
pub text_document_sync_did_change:
|
||||||
|
Option<HashMap<String, TextDocumentChangeRegistrationOptions>>,
|
||||||
|
pub text_document_sync_did_save: Option<HashMap<String, TextDocumentSaveRegistrationOptions>>,
|
||||||
|
}
|
||||||
|
|
||||||
impl LanguageServer {
|
impl LanguageServer {
|
||||||
/// Starts a language server process.
|
/// Starts a language server process.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
@ -484,7 +495,8 @@ impl LanguageServer {
|
||||||
.map(|name| Arc::from(name.to_string_lossy()))
|
.map(|name| Arc::from(name.to_string_lossy()))
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
binary,
|
binary,
|
||||||
capabilities: Default::default(),
|
static_capabilities: Default::default(),
|
||||||
|
dynamic_capabilities: Default::default(),
|
||||||
configuration,
|
configuration,
|
||||||
code_action_kinds,
|
code_action_kinds,
|
||||||
next_id: Default::default(),
|
next_id: Default::default(),
|
||||||
|
@ -898,7 +910,7 @@ impl LanguageServer {
|
||||||
if let Some(info) = response.server_info {
|
if let Some(info) = response.server_info {
|
||||||
self.process_name = info.name.into();
|
self.process_name = info.name.into();
|
||||||
}
|
}
|
||||||
self.capabilities = RwLock::new(response.capabilities);
|
self.static_capabilities = RwLock::new(response.capabilities);
|
||||||
self.configuration = configuration;
|
self.configuration = configuration;
|
||||||
|
|
||||||
self.notify::<notification::Initialized>(&InitializedParams {})?;
|
self.notify::<notification::Initialized>(&InitializedParams {})?;
|
||||||
|
@ -1130,7 +1142,18 @@ impl LanguageServer {
|
||||||
|
|
||||||
/// Get the reported capabilities of the running language server.
|
/// Get the reported capabilities of the running language server.
|
||||||
pub fn capabilities(&self) -> ServerCapabilities {
|
pub fn capabilities(&self) -> ServerCapabilities {
|
||||||
self.capabilities.read().clone()
|
self.static_capabilities.read().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_dynamic_capabilities(&self, update: impl FnOnce(&mut DynamicCapabilities)) {
|
||||||
|
update(self.dynamic_capabilities.write().deref_mut());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get effective capabilities by combining static and dynamic capabilities.
|
||||||
|
pub fn effective_capability<Cap: EffectiveCapability>(&self) -> Cap::Value {
|
||||||
|
let static_capabilities = self.capabilities();
|
||||||
|
let dynamic_capabilities = self.dynamic_capabilities.read().clone();
|
||||||
|
Cap::compute(&static_capabilities, &dynamic_capabilities)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the reported capabilities of the running language server and
|
/// Get the reported capabilities of the running language server and
|
||||||
|
@ -1143,7 +1166,7 @@ impl LanguageServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_capabilities(&self, update: impl FnOnce(&mut ServerCapabilities)) {
|
pub fn update_capabilities(&self, update: impl FnOnce(&mut ServerCapabilities)) {
|
||||||
update(self.capabilities.write().deref_mut());
|
update(self.static_capabilities.write().deref_mut());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn configuration(&self) -> &Value {
|
pub fn configuration(&self) -> &Value {
|
||||||
|
|
|
@ -74,9 +74,8 @@ use lsp::{
|
||||||
FileOperationPatternKind, FileOperationRegistrationOptions, FileRename, FileSystemWatcher,
|
FileOperationPatternKind, FileOperationRegistrationOptions, FileRename, FileSystemWatcher,
|
||||||
LSP_REQUEST_TIMEOUT, LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions,
|
LSP_REQUEST_TIMEOUT, LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions,
|
||||||
LanguageServerId, LanguageServerName, LanguageServerSelector, LspRequestFuture,
|
LanguageServerId, LanguageServerName, LanguageServerSelector, LspRequestFuture,
|
||||||
MessageActionItem, MessageType, OneOf, RenameFilesParams, SymbolKind,
|
MessageActionItem, MessageType, OneOf, RenameFilesParams, SymbolKind, TextEdit,
|
||||||
TextDocumentSyncSaveOptions, TextEdit, WillRenameFiles, WorkDoneProgressCancelParams,
|
WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
|
||||||
WorkspaceFolder, notification::DidRenameFiles,
|
|
||||||
};
|
};
|
||||||
use node_runtime::read_package_installed_version;
|
use node_runtime::read_package_installed_version;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
@ -7208,14 +7207,8 @@ impl LspStore {
|
||||||
.collect()
|
.collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
let document_sync_kind = language_server
|
let document_sync_kind =
|
||||||
.capabilities()
|
language_server.effective_capability::<lsp::cap::DidChangeTextDocument>();
|
||||||
.text_document_sync
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|sync| match sync {
|
|
||||||
lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
|
|
||||||
lsp::TextDocumentSyncCapability::Options(options) => options.change,
|
|
||||||
});
|
|
||||||
|
|
||||||
let content_changes: Vec<_> = match document_sync_kind {
|
let content_changes: Vec<_> = match document_sync_kind {
|
||||||
Some(lsp::TextDocumentSyncKind::FULL) => {
|
Some(lsp::TextDocumentSyncKind::FULL) => {
|
||||||
|
@ -7276,7 +7269,9 @@ impl LspStore {
|
||||||
let local = self.as_local()?;
|
let local = self.as_local()?;
|
||||||
|
|
||||||
for server in local.language_servers_for_worktree(worktree_id) {
|
for server in local.language_servers_for_worktree(worktree_id) {
|
||||||
if let Some(include_text) = include_text(server.as_ref()) {
|
if let Some(include_text) =
|
||||||
|
server.effective_capability::<lsp::cap::DidSaveTextDocument>()
|
||||||
|
{
|
||||||
let text = if include_text {
|
let text = if include_text {
|
||||||
Some(buffer.read(cx).text())
|
Some(buffer.read(cx).text())
|
||||||
} else {
|
} else {
|
||||||
|
@ -11706,12 +11701,11 @@ impl LspStore {
|
||||||
// Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
|
// Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
|
||||||
}
|
}
|
||||||
"workspace/symbol" => {
|
"workspace/symbol" => {
|
||||||
if let Some(options) = parse_register_capabilities(reg)? {
|
let options = parse_register_capabilities(reg)?;
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.workspace_symbol_provider = Some(options);
|
capabilities.workspace_symbol_provider = Some(options);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
"workspace/fileOperations" => {
|
"workspace/fileOperations" => {
|
||||||
if let Some(options) = reg.register_options {
|
if let Some(options) = reg.register_options {
|
||||||
|
@ -11735,12 +11729,11 @@ impl LspStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"textDocument/rangeFormatting" => {
|
"textDocument/rangeFormatting" => {
|
||||||
if let Some(options) = parse_register_capabilities(reg)? {
|
let options = parse_register_capabilities(reg)?;
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.document_range_formatting_provider = Some(options);
|
capabilities.document_range_formatting_provider = Some(options);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
"textDocument/onTypeFormatting" => {
|
"textDocument/onTypeFormatting" => {
|
||||||
if let Some(options) = reg
|
if let Some(options) = reg
|
||||||
|
@ -11755,36 +11748,32 @@ impl LspStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"textDocument/formatting" => {
|
"textDocument/formatting" => {
|
||||||
if let Some(options) = parse_register_capabilities(reg)? {
|
let options = parse_register_capabilities(reg)?;
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.document_formatting_provider = Some(options);
|
capabilities.document_formatting_provider = Some(options);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
"textDocument/rename" => {
|
"textDocument/rename" => {
|
||||||
if let Some(options) = parse_register_capabilities(reg)? {
|
let options = parse_register_capabilities(reg)?;
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.rename_provider = Some(options);
|
capabilities.rename_provider = Some(options);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
"textDocument/inlayHint" => {
|
"textDocument/inlayHint" => {
|
||||||
if let Some(options) = parse_register_capabilities(reg)? {
|
let options = parse_register_capabilities(reg)?;
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.inlay_hint_provider = Some(options);
|
capabilities.inlay_hint_provider = Some(options);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
"textDocument/documentSymbol" => {
|
"textDocument/documentSymbol" => {
|
||||||
if let Some(options) = parse_register_capabilities(reg)? {
|
let options = parse_register_capabilities(reg)?;
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.document_symbol_provider = Some(options);
|
capabilities.document_symbol_provider = Some(options);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
"textDocument/codeAction" => {
|
"textDocument/codeAction" => {
|
||||||
if let Some(options) = reg
|
if let Some(options) = reg
|
||||||
|
@ -11800,12 +11789,11 @@ impl LspStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"textDocument/definition" => {
|
"textDocument/definition" => {
|
||||||
if let Some(options) = parse_register_capabilities(reg)? {
|
let options = parse_register_capabilities(reg)?;
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_capabilities(|capabilities| {
|
||||||
capabilities.definition_provider = Some(options);
|
capabilities.definition_provider = Some(options);
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
"textDocument/completion" => {
|
"textDocument/completion" => {
|
||||||
if let Some(caps) = reg
|
if let Some(caps) = reg
|
||||||
|
@ -11844,47 +11832,27 @@ impl LspStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"textDocument/didChange" => {
|
"textDocument/didChange" => {
|
||||||
if let Some(sync_kind) = reg
|
if let Some(options) = reg.register_options {
|
||||||
.register_options
|
let options: lsp::TextDocumentChangeRegistrationOptions =
|
||||||
.and_then(|opts| opts.get("syncKind").cloned())
|
serde_json::from_value(options)?;
|
||||||
.map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
|
server.update_dynamic_capabilities(|dyn_caps| {
|
||||||
.transpose()?
|
let map = dyn_caps
|
||||||
{
|
.text_document_sync_did_change
|
||||||
server.update_capabilities(|capabilities| {
|
.get_or_insert_with(HashMap::default);
|
||||||
let mut sync_options =
|
map.insert(reg.id, options);
|
||||||
Self::take_text_document_sync_options(capabilities);
|
|
||||||
sync_options.change = Some(sync_kind);
|
|
||||||
capabilities.text_document_sync =
|
|
||||||
Some(lsp::TextDocumentSyncCapability::Options(sync_options));
|
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"textDocument/didSave" => {
|
"textDocument/didSave" => {
|
||||||
if let Some(include_text) = reg
|
if let Some(options) = reg.register_options {
|
||||||
.register_options
|
let options: lsp::TextDocumentSaveRegistrationOptions =
|
||||||
.map(|opts| {
|
serde_json::from_value(options)?;
|
||||||
let transpose = opts
|
server.update_dynamic_capabilities(|dyn_caps| {
|
||||||
.get("includeText")
|
let map = dyn_caps
|
||||||
.cloned()
|
.text_document_sync_did_save
|
||||||
.map(serde_json::from_value::<Option<bool>>)
|
.get_or_insert_with(HashMap::default);
|
||||||
.transpose();
|
map.insert(reg.id, options);
|
||||||
match transpose {
|
|
||||||
Ok(value) => Ok(value.flatten()),
|
|
||||||
Err(e) => Err(e),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.transpose()?
|
|
||||||
{
|
|
||||||
server.update_capabilities(|capabilities| {
|
|
||||||
let mut sync_options =
|
|
||||||
Self::take_text_document_sync_options(capabilities);
|
|
||||||
sync_options.save =
|
|
||||||
Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
|
|
||||||
include_text,
|
|
||||||
}));
|
|
||||||
capabilities.text_document_sync =
|
|
||||||
Some(lsp::TextDocumentSyncCapability::Options(sync_options));
|
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
@ -12035,20 +12003,18 @@ impl LspStore {
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
"textDocument/didChange" => {
|
"textDocument/didChange" => {
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_dynamic_capabilities(|dyn_caps| {
|
||||||
let mut sync_options = Self::take_text_document_sync_options(capabilities);
|
if let Some(map) = dyn_caps.text_document_sync_did_change.as_mut() {
|
||||||
sync_options.change = None;
|
map.remove(&unreg.id);
|
||||||
capabilities.text_document_sync =
|
}
|
||||||
Some(lsp::TextDocumentSyncCapability::Options(sync_options));
|
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
"textDocument/didSave" => {
|
"textDocument/didSave" => {
|
||||||
server.update_capabilities(|capabilities| {
|
server.update_dynamic_capabilities(|dyn_caps| {
|
||||||
let mut sync_options = Self::take_text_document_sync_options(capabilities);
|
if let Some(map) = dyn_caps.text_document_sync_did_save.as_mut() {
|
||||||
sync_options.save = None;
|
map.remove(&unreg.id);
|
||||||
capabilities.text_document_sync =
|
}
|
||||||
Some(lsp::TextDocumentSyncCapability::Options(sync_options));
|
|
||||||
});
|
});
|
||||||
notify_server_capabilities_updated(&server, cx);
|
notify_server_capabilities_updated(&server, cx);
|
||||||
}
|
}
|
||||||
|
@ -12159,20 +12125,6 @@ impl LspStore {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn take_text_document_sync_options(
|
|
||||||
capabilities: &mut lsp::ServerCapabilities,
|
|
||||||
) -> lsp::TextDocumentSyncOptions {
|
|
||||||
match capabilities.text_document_sync.take() {
|
|
||||||
Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
|
|
||||||
Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
|
|
||||||
let mut sync_options = lsp::TextDocumentSyncOptions::default();
|
|
||||||
sync_options.change = Some(sync_kind);
|
|
||||||
sync_options
|
|
||||||
}
|
|
||||||
None => lsp::TextDocumentSyncOptions::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
|
pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
|
||||||
let data = self.lsp_code_lens.get_mut(&buffer_id)?;
|
let data = self.lsp_code_lens.get_mut(&buffer_id)?;
|
||||||
|
@ -12184,10 +12136,10 @@ impl LspStore {
|
||||||
// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
|
// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
|
||||||
fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
|
fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
|
||||||
reg: lsp::Registration,
|
reg: lsp::Registration,
|
||||||
) -> anyhow::Result<Option<OneOf<bool, T>>> {
|
) -> Result<OneOf<bool, T>> {
|
||||||
Ok(match reg.register_options {
|
Ok(match reg.register_options {
|
||||||
Some(options) => Some(OneOf::Right(serde_json::from_value::<T>(options)?)),
|
Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
|
||||||
None => Some(OneOf::Left(true)),
|
None => OneOf::Left(true),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13272,23 +13224,6 @@ async fn populate_labels_for_symbols(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
|
|
||||||
match server.capabilities().text_document_sync.as_ref()? {
|
|
||||||
lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
|
|
||||||
// Server wants didSave but didn't specify includeText.
|
|
||||||
lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
|
|
||||||
// Server doesn't want didSave at all.
|
|
||||||
lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
|
|
||||||
// Server provided SaveOptions.
|
|
||||||
lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
|
|
||||||
Some(save_options.include_text.unwrap_or(false))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// We do not have any save info. Kind affects didChange only.
|
|
||||||
lsp::TextDocumentSyncCapability::Kind(_) => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Completion items are displayed in a `UniformList`.
|
/// Completion items are displayed in a `UniformList`.
|
||||||
/// Usually, those items are single-line strings, but in LSP responses,
|
/// Usually, those items are single-line strings, but in LSP responses,
|
||||||
/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
|
/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue