Skip to content

Commit 7da5311

Browse files
committed
fix(lsp): compare only the formatted range on range formatting
1 parent ceed34a commit 7da5311

File tree

2 files changed

+83
-7
lines changed

2 files changed

+83
-7
lines changed

crates/biome_lsp/src/handlers/formatting.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::utils::text_edit;
44
use anyhow::Context;
55
use biome_fs::BiomePath;
66
use biome_lsp_converters::from_proto;
7-
use biome_rowan::{TextRange, TextSize};
7+
use biome_rowan::{TextLen, TextRange, TextSize};
88
use biome_service::file_handlers::{AstroFileHandler, SvelteFileHandler, VueFileHandler};
99
use biome_service::workspace::{
1010
CheckFileSizeParams, FeaturesBuilder, FileFeaturesResult, FormatFileParams, FormatOnTypeParams,
@@ -149,14 +149,19 @@ pub(crate) fn format_range(
149149
range: format_range,
150150
})?;
151151

152-
let indels =
153-
biome_text_edit::TextEdit::from_unicode_words(content.as_str(), formatted.as_code());
152+
let formatted_range = formatted
153+
.range()
154+
.unwrap_or_else(|| TextRange::up_to(content.text_len()));
155+
let indels = biome_text_edit::TextEdit::from_unicode_words(
156+
&content.as_str()[formatted_range],
157+
formatted.as_code(),
158+
);
154159
let position_encoding = session.position_encoding();
155160
let edits = text_edit(
156161
&doc.line_index,
157162
indels,
158163
position_encoding,
159-
Some(format_range.start().into()),
164+
Some(formatted_range.start().into()),
160165
)?;
161166

162167
Ok(Some(edits))
@@ -217,13 +222,18 @@ pub(crate) fn format_on_type(
217222
path: path.clone(),
218223
})?;
219224

220-
let indels =
221-
biome_text_edit::TextEdit::from_unicode_words(content.as_str(), formatted.as_code());
225+
let formatted_range = formatted
226+
.range()
227+
.unwrap_or_else(|| TextRange::up_to(content.text_len()));
228+
let indels = biome_text_edit::TextEdit::from_unicode_words(
229+
&content.as_str()[formatted_range],
230+
formatted.as_code(),
231+
);
222232
let edits = text_edit(
223233
&doc.line_index,
224234
indels,
225235
position_encoding,
226-
Some(offset.into()),
236+
Some(formatted_range.start().into()),
227237
)?;
228238
Ok(Some(edits))
229239
} else {

crates/biome_lsp/src/server.tests.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,72 @@ async fn document_no_extension() -> Result<()> {
793793
Ok(())
794794
}
795795

796+
#[tokio::test]
797+
async fn document_range_formatting() -> Result<()> {
798+
let factory = ServerFactory::default();
799+
let (service, client) = factory.create().into_inner();
800+
let (stream, sink) = client.split();
801+
let mut server = Server::new(service);
802+
803+
let (sender, _) = channel(CHANNEL_BUFFER_SIZE);
804+
let reader = tokio::spawn(client_handler(stream, sink, sender));
805+
806+
server.initialize().await?;
807+
server.initialized().await?;
808+
809+
server
810+
.notify(
811+
"textDocument/didOpen",
812+
DidOpenTextDocumentParams {
813+
text_document: TextDocumentItem {
814+
uri: uri!("document.js"),
815+
language_id: String::from("javascript"),
816+
version: 0,
817+
text: String::from("doNotFormatHere()\nformatHere()\ndoNotFormatHere()\n"),
818+
},
819+
},
820+
)
821+
.await?;
822+
823+
let res: Option<Vec<TextEdit>> = server
824+
.request(
825+
"textDocument/rangeFormatting",
826+
"formatting",
827+
DocumentRangeFormattingParams {
828+
text_document: TextDocumentIdentifier {
829+
uri: uri!("document.js"),
830+
},
831+
range: Range::new(Position::new(1, 0), Position::new(2, 0)),
832+
options: FormattingOptions {
833+
tab_size: 4,
834+
insert_spaces: false,
835+
properties: HashMap::default(),
836+
trim_trailing_whitespace: None,
837+
insert_final_newline: None,
838+
trim_final_newlines: None,
839+
},
840+
work_done_progress_params: WorkDoneProgressParams {
841+
work_done_token: None,
842+
},
843+
},
844+
)
845+
.await?
846+
.context("formatting returned None")?;
847+
848+
assert_eq!(
849+
res.context("formatting did not return an edit list")?,
850+
vec![TextEdit::new(
851+
Range::new(Position::new(1, 12), Position::new(1, 12)),
852+
";".to_string()
853+
)]
854+
);
855+
856+
server.shutdown().await?;
857+
reader.abort();
858+
859+
Ok(())
860+
}
861+
796862
#[tokio::test]
797863
async fn pull_diagnostics() -> Result<()> {
798864
let factory = ServerFactory::default();

0 commit comments

Comments
 (0)