mirror of
https://github.com/denoland/deno.git
synced 2025-01-03 12:58:54 -05:00
fix(lsp): handle repeating patterns in registry correctly (#13275)
This commit is contained in:
parent
d9b130410b
commit
01ff7a8784
15 changed files with 120 additions and 28 deletions
|
@ -249,7 +249,11 @@ impl StringOrVec {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_string(&self, maybe_key: Option<&Key>) -> String {
|
pub fn to_string(
|
||||||
|
&self,
|
||||||
|
maybe_key: Option<&Key>,
|
||||||
|
omit_initial_prefix: bool,
|
||||||
|
) -> String {
|
||||||
match self {
|
match self {
|
||||||
Self::String(s) => s.clone(),
|
Self::String(s) => s.clone(),
|
||||||
Self::Vec(v) => {
|
Self::Vec(v) => {
|
||||||
|
@ -262,9 +266,13 @@ impl StringOrVec {
|
||||||
("/".to_string(), "".to_string())
|
("/".to_string(), "".to_string())
|
||||||
};
|
};
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
for segment in v {
|
for (i, segment) in v.iter().enumerate() {
|
||||||
|
if omit_initial_prefix && i == 0 {
|
||||||
|
s.push_str(&format!("{}{}", segment, suffix));
|
||||||
|
} else {
|
||||||
s.push_str(&format!("{}{}{}", prefix, segment, suffix));
|
s.push_str(&format!("{}{}{}", prefix, segment, suffix));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ fn get_completor_type(
|
||||||
if let StringOrNumber::String(name) = &k.name {
|
if let StringOrNumber::String(name) = &k.name {
|
||||||
let value = match_result
|
let value = match_result
|
||||||
.get(name)
|
.get(name)
|
||||||
.map(|s| s.to_string(Some(k)))
|
.map(|s| s.to_string(Some(k), false))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
len += value.chars().count();
|
len += value.chars().count();
|
||||||
if offset <= len {
|
if offset <= len {
|
||||||
|
@ -213,11 +213,12 @@ fn get_endpoint_with_match(
|
||||||
Token::Key(k) if k.name == *key => Some(k),
|
Token::Key(k) if k.name == *key => Some(k),
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
url = url.replace(&format!("${{{}}}", name), &value.to_string(maybe_key));
|
url = url
|
||||||
|
.replace(&format!("${{{}}}", name), &value.to_string(maybe_key, true));
|
||||||
url = url.replace(
|
url = url.replace(
|
||||||
&format!("${{{{{}}}}}", name),
|
&format!("${{{{{}}}}}", name),
|
||||||
&percent_encoding::percent_encode(
|
&percent_encoding::percent_encode(
|
||||||
value.to_string(maybe_key).as_bytes(),
|
value.to_string(maybe_key, true).as_bytes(),
|
||||||
COMPONENT,
|
COMPONENT,
|
||||||
)
|
)
|
||||||
.to_string(),
|
.to_string(),
|
||||||
|
@ -1212,15 +1213,7 @@ mod tests {
|
||||||
.await;
|
.await;
|
||||||
assert!(completions.is_some());
|
assert!(completions.is_some());
|
||||||
let completions = completions.unwrap().items;
|
let completions = completions.unwrap().items;
|
||||||
assert_eq!(completions.len(), 1);
|
assert_eq!(completions.len(), 3);
|
||||||
assert_eq!(completions[0].label, "/x");
|
|
||||||
assert_eq!(
|
|
||||||
completions[0].text_edit,
|
|
||||||
Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
|
|
||||||
range,
|
|
||||||
new_text: "http://localhost:4545/x".to_string()
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
let range = lsp::Range {
|
let range = lsp::Range {
|
||||||
start: lsp::Position {
|
start: lsp::Position {
|
||||||
line: 0,
|
line: 0,
|
||||||
|
@ -1236,15 +1229,7 @@ mod tests {
|
||||||
.await;
|
.await;
|
||||||
assert!(completions.is_some());
|
assert!(completions.is_some());
|
||||||
let completions = completions.unwrap().items;
|
let completions = completions.unwrap().items;
|
||||||
assert_eq!(completions.len(), 1);
|
assert_eq!(completions.len(), 3);
|
||||||
assert_eq!(completions[0].label, "/x");
|
|
||||||
assert_eq!(
|
|
||||||
completions[0].text_edit,
|
|
||||||
Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
|
|
||||||
range,
|
|
||||||
new_text: "http://localhost:4545/x".to_string()
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
let range = lsp::Range {
|
let range = lsp::Range {
|
||||||
start: lsp::Position {
|
start: lsp::Position {
|
||||||
line: 0,
|
line: 0,
|
||||||
|
@ -1328,6 +1313,30 @@ mod tests {
|
||||||
"documentation": format!("http://localhost:4545/lsp/registries/doc_a_{}.json", completions[0].label),
|
"documentation": format!("http://localhost:4545/lsp/registries/doc_a_{}.json", completions[0].label),
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let range = lsp::Range {
|
||||||
|
start: lsp::Position {
|
||||||
|
line: 0,
|
||||||
|
character: 20,
|
||||||
|
},
|
||||||
|
end: lsp::Position {
|
||||||
|
line: 0,
|
||||||
|
character: 49,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let completions = module_registry
|
||||||
|
.get_completions("http://localhost:4545/x/a@v1.", 29, &range, |_| false)
|
||||||
|
.await;
|
||||||
|
assert!(completions.is_some());
|
||||||
|
let completions = completions.unwrap().items;
|
||||||
|
assert_eq!(completions.len(), 2);
|
||||||
|
assert_eq!(
|
||||||
|
completions[0].data,
|
||||||
|
Some(json!({
|
||||||
|
"documentation": format!("http://localhost:4545/lsp/registries/doc_a_{}.json", completions[0].label),
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
let range = lsp::Range {
|
let range = lsp::Range {
|
||||||
start: lsp::Position {
|
start: lsp::Position {
|
||||||
line: 0,
|
line: 0,
|
||||||
|
@ -1338,7 +1347,6 @@ mod tests {
|
||||||
character: 53,
|
character: 53,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let completions = module_registry
|
let completions = module_registry
|
||||||
.get_completions("http://localhost:4545/x/a@v1.0.0/", 33, &range, |_| {
|
.get_completions("http://localhost:4545/x/a@v1.0.0/", 33, &range, |_| {
|
||||||
false
|
false
|
||||||
|
@ -1353,6 +1361,53 @@ mod tests {
|
||||||
assert_eq!(completions[1].detail, Some("(path)".to_string()));
|
assert_eq!(completions[1].detail, Some("(path)".to_string()));
|
||||||
assert_eq!(completions[0].kind, Some(lsp::CompletionItemKind::FILE));
|
assert_eq!(completions[0].kind, Some(lsp::CompletionItemKind::FILE));
|
||||||
assert!(completions[1].command.is_some());
|
assert!(completions[1].command.is_some());
|
||||||
|
|
||||||
|
let range = lsp::Range {
|
||||||
|
start: lsp::Position {
|
||||||
|
line: 0,
|
||||||
|
character: 20,
|
||||||
|
},
|
||||||
|
end: lsp::Position {
|
||||||
|
line: 0,
|
||||||
|
character: 54,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let completions = module_registry
|
||||||
|
.get_completions("http://localhost:4545/x/a@v1.0.0/b", 34, &range, |_| {
|
||||||
|
false
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
assert!(completions.is_some());
|
||||||
|
let completions = completions.unwrap().items;
|
||||||
|
assert_eq!(completions.len(), 1);
|
||||||
|
assert_eq!(completions[0].detail, Some("(path)".to_string()));
|
||||||
|
assert_eq!(completions[0].kind, Some(lsp::CompletionItemKind::FILE));
|
||||||
|
assert!(completions[0].command.is_some());
|
||||||
|
|
||||||
|
let range = lsp::Range {
|
||||||
|
start: lsp::Position {
|
||||||
|
line: 0,
|
||||||
|
character: 20,
|
||||||
|
},
|
||||||
|
end: lsp::Position {
|
||||||
|
line: 0,
|
||||||
|
character: 55,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let completions = module_registry
|
||||||
|
.get_completions(
|
||||||
|
"http://localhost:4545/x/a@v1.0.0/b/",
|
||||||
|
35,
|
||||||
|
&range,
|
||||||
|
|_| false,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert!(completions.is_some());
|
||||||
|
let completions = completions.unwrap().items;
|
||||||
|
assert_eq!(completions.len(), 1);
|
||||||
|
assert_eq!(completions[0].detail, Some("(path)".to_string()));
|
||||||
|
assert_eq!(completions[0].kind, Some(lsp::CompletionItemKind::FILE));
|
||||||
|
assert!(completions[0].command.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|
3
cli/tests/testdata/lsp/registries/a_v1.0.0_b.json
vendored
Normal file
3
cli/tests/testdata/lsp/registries/a_v1.0.0_b.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[
|
||||||
|
"b/c.ts"
|
||||||
|
]
|
4
cli/tests/testdata/lsp/registries/a_versions_v1..json
vendored
Normal file
4
cli/tests/testdata/lsp/registries/a_versions_v1..json
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[
|
||||||
|
"v1.0.0",
|
||||||
|
"v1.0.1"
|
||||||
|
]
|
|
@ -12,11 +12,11 @@
|
||||||
{
|
{
|
||||||
"key": "version",
|
"key": "version",
|
||||||
"documentation": "/lsp/registries/doc_${module}_${{version}}.json",
|
"documentation": "/lsp/registries/doc_${module}_${{version}}.json",
|
||||||
"url": "/lsp/registries/${module}_versions.json"
|
"url": "/lsp/registries/${module}_versions_${{version}}.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "path",
|
"key": "path",
|
||||||
"url": "/lsp/registries/${module}_${{version}}.json"
|
"url": "/lsp/registries/${module}_${{version}}_${path}.json"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -30,7 +30,29 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "path",
|
"key": "path",
|
||||||
"url": "/lsp/registries/${module}_latest.json"
|
"url": "/lsp/registries/${module}_latest_${path}.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"schema": "/std@:version?/:path*",
|
||||||
|
"variables": [
|
||||||
|
{
|
||||||
|
"key": "version",
|
||||||
|
"url": "/lsp/registries/std_${{version}}.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "path",
|
||||||
|
"url": "/lsp/registries/std_${{version}}_${path}.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"schema": "/std/:path*",
|
||||||
|
"variables": [
|
||||||
|
{
|
||||||
|
"key": "path",
|
||||||
|
"url": "/lsp/registries/std_latest_${path}.json"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue