mirror of
https://github.com/denoland/deno.git
synced 2025-01-08 15:19:40 -05:00
fix(lsp): handle mbc properly when formatting (#9273)
This commit is contained in:
parent
43f4a23f89
commit
ada43cc56a
4 changed files with 157 additions and 7 deletions
|
@ -669,7 +669,7 @@ impl Inner {
|
||||||
)
|
)
|
||||||
})?
|
})?
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let line_index = self.documents.line_index(&specifier);
|
||||||
let file_path =
|
let file_path =
|
||||||
if let Ok(file_path) = params.text_document.uri.to_file_path() {
|
if let Ok(file_path) = params.text_document.uri.to_file_path() {
|
||||||
file_path
|
file_path
|
||||||
|
@ -685,7 +685,9 @@ impl Inner {
|
||||||
// TODO(@kitsonk) this could be handled better in `cli/tools/fmt.rs` in the
|
// TODO(@kitsonk) this could be handled better in `cli/tools/fmt.rs` in the
|
||||||
// future.
|
// future.
|
||||||
match dprint::format_text(&file_path, &file_text, &config) {
|
match dprint::format_text(&file_path, &file_text, &config) {
|
||||||
Ok(new_text) => Some(text::get_edits(&file_text, &new_text)),
|
Ok(new_text) => {
|
||||||
|
Some(text::get_edits(&file_text, &new_text, line_index))
|
||||||
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!("Format error: {}", err);
|
warn!("Format error: {}", err);
|
||||||
None
|
None
|
||||||
|
@ -702,6 +704,7 @@ impl Inner {
|
||||||
Ok(Some(text_edits))
|
Ok(Some(text_edits))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
self.client.show_message(MessageType::Warning, format!("Unable to format \"{}\". Likely due to unrecoverable syntax errors in the file.", specifier)).await;
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1524,6 +1527,81 @@ mod tests {
|
||||||
harness.run().await;
|
harness.run().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_format_mbc() {
|
||||||
|
let mut harness = LspTestHarness::new(vec![
|
||||||
|
("initialize_request.json", LspResponse::RequestAny),
|
||||||
|
("initialized_notification.json", LspResponse::None),
|
||||||
|
("did_open_notification_mbc_fmt.json", LspResponse::None),
|
||||||
|
(
|
||||||
|
"formatting_request_mbc_fmt.json",
|
||||||
|
LspResponse::Request(
|
||||||
|
2,
|
||||||
|
json!([
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": {
|
||||||
|
"line": 0,
|
||||||
|
"character": 12
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 0,
|
||||||
|
"character": 13,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"newText": "\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": {
|
||||||
|
"line": 0,
|
||||||
|
"character": 21
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 0,
|
||||||
|
"character": 22
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"newText": "\";"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"character": 12,
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"character": 13,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"newText": "\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"character": 23,
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"character": 25,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"newText": "\");"
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"shutdown_request.json",
|
||||||
|
LspResponse::Request(3, json!(null)),
|
||||||
|
),
|
||||||
|
("exit_notification.json", LspResponse::None),
|
||||||
|
]);
|
||||||
|
harness.run().await;
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_large_doc_change() {
|
async fn test_large_doc_change() {
|
||||||
let mut harness = LspTestHarness::new(vec![
|
let mut harness = LspTestHarness::new(vec![
|
||||||
|
|
|
@ -181,8 +181,8 @@ impl LineIndex {
|
||||||
|
|
||||||
/// Returns a u16 position based on a u8 offset.
|
/// Returns a u16 position based on a u8 offset.
|
||||||
pub fn position_utf16(&self, offset: TextSize) -> lsp_types::Position {
|
pub fn position_utf16(&self, offset: TextSize) -> lsp_types::Position {
|
||||||
let line = partition_point(&self.utf8_offsets, |&it| it <= offset) - 1;
|
let line = partition_point(&self.utf16_offsets, |&it| it <= offset) - 1;
|
||||||
let line_start_offset = self.utf8_offsets[line];
|
let line_start_offset = self.utf16_offsets[line];
|
||||||
let col = offset - line_start_offset;
|
let col = offset - line_start_offset;
|
||||||
|
|
||||||
lsp_types::Position {
|
lsp_types::Position {
|
||||||
|
@ -208,13 +208,21 @@ impl LineIndex {
|
||||||
|
|
||||||
/// Compare two strings and return a vector of text edit records which are
|
/// Compare two strings and return a vector of text edit records which are
|
||||||
/// supported by the Language Server Protocol.
|
/// supported by the Language Server Protocol.
|
||||||
pub fn get_edits(a: &str, b: &str) -> Vec<TextEdit> {
|
pub fn get_edits(
|
||||||
|
a: &str,
|
||||||
|
b: &str,
|
||||||
|
maybe_line_index: Option<LineIndex>,
|
||||||
|
) -> Vec<TextEdit> {
|
||||||
if a == b {
|
if a == b {
|
||||||
return vec![];
|
return vec![];
|
||||||
}
|
}
|
||||||
let chunks = diff(a, b);
|
let chunks = diff(a, b);
|
||||||
let mut text_edits = Vec::<TextEdit>::new();
|
let mut text_edits = Vec::<TextEdit>::new();
|
||||||
let line_index = LineIndex::new(a);
|
let line_index = if let Some(line_index) = maybe_line_index {
|
||||||
|
line_index
|
||||||
|
} else {
|
||||||
|
LineIndex::new(a)
|
||||||
|
};
|
||||||
let mut iter = chunks.iter().peekable();
|
let mut iter = chunks.iter().peekable();
|
||||||
let mut a_pos = TextSize::from(0);
|
let mut a_pos = TextSize::from(0);
|
||||||
loop {
|
loop {
|
||||||
|
@ -565,7 +573,7 @@ const C: char = \"メ メ\";
|
||||||
fn test_get_edits() {
|
fn test_get_edits() {
|
||||||
let a = "abcdefg";
|
let a = "abcdefg";
|
||||||
let b = "a\nb\nchije\nfg\n";
|
let b = "a\nb\nchije\nfg\n";
|
||||||
let actual = get_edits(a, b);
|
let actual = get_edits(a, b, None);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
actual,
|
actual,
|
||||||
vec![
|
vec![
|
||||||
|
@ -599,6 +607,44 @@ const C: char = \"メ メ\";
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_edits_mbc() {
|
||||||
|
let a = "const bar = \"👍🇺🇸😃\";\nconsole.log('hello deno')\n";
|
||||||
|
let b = "const bar = \"👍🇺🇸😃\";\nconsole.log(\"hello deno\");\n";
|
||||||
|
let actual = get_edits(a, b, None);
|
||||||
|
assert_eq!(
|
||||||
|
actual,
|
||||||
|
vec![
|
||||||
|
TextEdit {
|
||||||
|
range: lsp_types::Range {
|
||||||
|
start: lsp_types::Position {
|
||||||
|
line: 1,
|
||||||
|
character: 12
|
||||||
|
},
|
||||||
|
end: lsp_types::Position {
|
||||||
|
line: 1,
|
||||||
|
character: 13
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new_text: "\"".to_string()
|
||||||
|
},
|
||||||
|
TextEdit {
|
||||||
|
range: lsp_types::Range {
|
||||||
|
start: lsp_types::Position {
|
||||||
|
line: 1,
|
||||||
|
character: 23
|
||||||
|
},
|
||||||
|
end: lsp_types::Position {
|
||||||
|
line: 1,
|
||||||
|
character: 25
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new_text: "\");".to_string()
|
||||||
|
},
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_range_change() {
|
fn test_get_range_change() {
|
||||||
let a = "abcdefg";
|
let a = "abcdefg";
|
||||||
|
|
12
cli/tests/lsp/did_open_notification_mbc_fmt.json
Normal file
12
cli/tests/lsp/did_open_notification_mbc_fmt.json
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": "textDocument/didOpen",
|
||||||
|
"params": {
|
||||||
|
"textDocument": {
|
||||||
|
"uri": "file:///a/file.ts",
|
||||||
|
"languageId": "typescript",
|
||||||
|
"version": 1,
|
||||||
|
"text": "const bar = '👍🇺🇸😃'\nconsole.log('hello deno')\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
cli/tests/lsp/formatting_request_mbc_fmt.json
Normal file
14
cli/tests/lsp/formatting_request_mbc_fmt.json
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 2,
|
||||||
|
"method": "textDocument/formatting",
|
||||||
|
"params": {
|
||||||
|
"textDocument": {
|
||||||
|
"uri": "file:///a/file.ts"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"tabSize": 2,
|
||||||
|
"insertSpaces": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue