mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 07:14:47 -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();
|
||||
|
||||
let line_index = self.documents.line_index(&specifier);
|
||||
let file_path =
|
||||
if let Ok(file_path) = params.text_document.uri.to_file_path() {
|
||||
file_path
|
||||
|
@ -685,7 +685,9 @@ impl Inner {
|
|||
// TODO(@kitsonk) this could be handled better in `cli/tools/fmt.rs` in the
|
||||
// future.
|
||||
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) => {
|
||||
warn!("Format error: {}", err);
|
||||
None
|
||||
|
@ -702,6 +704,7 @@ impl Inner {
|
|||
Ok(Some(text_edits))
|
||||
}
|
||||
} else {
|
||||
self.client.show_message(MessageType::Warning, format!("Unable to format \"{}\". Likely due to unrecoverable syntax errors in the file.", specifier)).await;
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
@ -1524,6 +1527,81 @@ mod tests {
|
|||
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]
|
||||
async fn test_large_doc_change() {
|
||||
let mut harness = LspTestHarness::new(vec![
|
||||
|
|
|
@ -181,8 +181,8 @@ impl LineIndex {
|
|||
|
||||
/// Returns a u16 position based on a u8 offset.
|
||||
pub fn position_utf16(&self, offset: TextSize) -> lsp_types::Position {
|
||||
let line = partition_point(&self.utf8_offsets, |&it| it <= offset) - 1;
|
||||
let line_start_offset = self.utf8_offsets[line];
|
||||
let line = partition_point(&self.utf16_offsets, |&it| it <= offset) - 1;
|
||||
let line_start_offset = self.utf16_offsets[line];
|
||||
let col = offset - line_start_offset;
|
||||
|
||||
lsp_types::Position {
|
||||
|
@ -208,13 +208,21 @@ impl LineIndex {
|
|||
|
||||
/// Compare two strings and return a vector of text edit records which are
|
||||
/// 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 {
|
||||
return vec![];
|
||||
}
|
||||
let chunks = diff(a, b);
|
||||
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 a_pos = TextSize::from(0);
|
||||
loop {
|
||||
|
@ -565,7 +573,7 @@ const C: char = \"メ メ\";
|
|||
fn test_get_edits() {
|
||||
let a = "abcdefg";
|
||||
let b = "a\nb\nchije\nfg\n";
|
||||
let actual = get_edits(a, b);
|
||||
let actual = get_edits(a, b, None);
|
||||
assert_eq!(
|
||||
actual,
|
||||
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]
|
||||
fn test_get_range_change() {
|
||||
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