From 46da80d726ace0e69e8a0993e01b682d0abc5725 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 4 Mar 2022 10:11:10 +0100 Subject: [PATCH 1/2] Use LSP range formatting when document formatting is not available --- crates/project/src/project.rs | 44 ++++++++++++++++++++++++++++------- crates/text/src/rope.rs | 4 ++++ crates/text/src/text.rs | 4 ++++ 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index a89317db90410d99c9d876b9206adace06ec8682..f207430d7ae104407552753528cbcf7aafcfe269 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -1314,15 +1314,41 @@ impl Project { } for (buffer, buffer_abs_path, lang_server) in local_buffers { - let lsp_edits = lang_server - .request::(lsp::DocumentFormattingParams { - text_document: lsp::TextDocumentIdentifier::new( - lsp::Url::from_file_path(&buffer_abs_path).unwrap(), - ), - options: Default::default(), - work_done_progress_params: Default::default(), - }) - .await?; + let capabilities = if let Some(capabilities) = lang_server.capabilities().await { + capabilities + } else { + continue; + }; + + let text_document = lsp::TextDocumentIdentifier::new( + lsp::Url::from_file_path(&buffer_abs_path).unwrap(), + ); + let lsp_edits = if capabilities.document_formatting_provider.is_some() { + lang_server + .request::(lsp::DocumentFormattingParams { + text_document, + options: Default::default(), + work_done_progress_params: Default::default(), + }) + .await? + } else if capabilities.document_range_formatting_provider.is_some() { + let buffer_start = lsp::Position::new(0, 0); + let buffer_end = buffer + .read_with(&cx, |buffer, _| buffer.max_point_utf16()) + .to_lsp_position(); + lang_server + .request::( + lsp::DocumentRangeFormattingParams { + text_document, + range: lsp::Range::new(buffer_start, buffer_end), + options: Default::default(), + work_done_progress_params: Default::default(), + }, + ) + .await? + } else { + continue; + }; if let Some(lsp_edits) = lsp_edits { let edits = buffer diff --git a/crates/text/src/rope.rs b/crates/text/src/rope.rs index 3d1cb28eb18bc0605a64cc40aa66b4618a2dcb2b..ce666968b2146f8a956029b139593fd4e0c1b2b9 100644 --- a/crates/text/src/rope.rs +++ b/crates/text/src/rope.rs @@ -126,6 +126,10 @@ impl Rope { self.chunks.extent(&()) } + pub fn max_point_utf16(&self) -> PointUtf16 { + self.chunks.extent(&()) + } + pub fn cursor(&self, offset: usize) -> Cursor { Cursor::new(self, offset) } diff --git a/crates/text/src/text.rs b/crates/text/src/text.rs index 95441a12080c148afa07cfe0527b8db20b38ec06..89943777e06e4d21ef488a215c807064319e71a0 100644 --- a/crates/text/src/text.rs +++ b/crates/text/src/text.rs @@ -1526,6 +1526,10 @@ impl BufferSnapshot { self.visible_text.max_point() } + pub fn max_point_utf16(&self) -> PointUtf16 { + self.visible_text.max_point_utf16() + } + pub fn point_to_offset(&self, point: Point) -> usize { self.visible_text.point_to_offset(point) } From d8ef3a5d61ad581bcbe7f1d15db2fa4dd6c6688f Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 4 Mar 2022 11:24:18 +0100 Subject: [PATCH 2/2] Support formatting in fake LSP capabilities --- crates/lsp/src/lsp.rs | 2 ++ crates/project/src/project.rs | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index fce206830297baf1c256a7c87c86b2564529149b..5f3eb2caaffa9c055c8f038197beb41b0d105b73 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -524,6 +524,8 @@ impl LanguageServer { ServerCapabilities { document_highlight_provider: Some(OneOf::Left(true)), code_action_provider: Some(CodeActionProviderCapability::Simple(true)), + document_formatting_provider: Some(OneOf::Left(true)), + document_range_formatting_provider: Some(OneOf::Left(true)), ..Default::default() } } diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index f207430d7ae104407552753528cbcf7aafcfe269..53ca4bf3329c0ee8263499a54663558cb5ee95bc 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -1323,7 +1323,10 @@ impl Project { let text_document = lsp::TextDocumentIdentifier::new( lsp::Url::from_file_path(&buffer_abs_path).unwrap(), ); - let lsp_edits = if capabilities.document_formatting_provider.is_some() { + let lsp_edits = if capabilities + .document_formatting_provider + .map_or(false, |provider| provider != lsp::OneOf::Left(false)) + { lang_server .request::(lsp::DocumentFormattingParams { text_document, @@ -1331,7 +1334,10 @@ impl Project { work_done_progress_params: Default::default(), }) .await? - } else if capabilities.document_range_formatting_provider.is_some() { + } else if capabilities + .document_range_formatting_provider + .map_or(false, |provider| provider != lsp::OneOf::Left(false)) + { let buffer_start = lsp::Position::new(0, 0); let buffer_end = buffer .read_with(&cx, |buffer, _| buffer.max_point_utf16())