Fix vscode lsp bugs (#6271)
* start of shit Signed-off-by: Jess Frazelle <github@jessfraz.com> * untitled test Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
@ -389,6 +389,13 @@ export class LanguageServerPlugin implements PluginValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (insertText && insertTextFormat === 2) {
|
if (insertText && insertTextFormat === 2) {
|
||||||
|
// We end with ${} so you can jump to the end of the snippet.
|
||||||
|
// After the last argument.
|
||||||
|
// This is not standard from the lsp so we add it here.
|
||||||
|
if (insertText.endsWith(')')) {
|
||||||
|
// We have a function its safe to insert the ${} at the end.
|
||||||
|
insertText = insertText + '${}'
|
||||||
|
}
|
||||||
return snippetCompletion(insertText, completion)
|
return snippetCompletion(insertText, completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,10 @@ export async function createClient(
|
|||||||
serverOptions: lc.ServerOptions
|
serverOptions: lc.ServerOptions
|
||||||
): Promise<lc.LanguageClient> {
|
): Promise<lc.LanguageClient> {
|
||||||
const clientOptions: lc.LanguageClientOptions = {
|
const clientOptions: lc.LanguageClientOptions = {
|
||||||
documentSelector: [{ scheme: 'file', language: 'kcl' }],
|
documentSelector: [
|
||||||
|
{ scheme: 'file', language: 'kcl' },
|
||||||
|
{ scheme: 'untitled', language: 'kcl' },
|
||||||
|
],
|
||||||
initializationOptions,
|
initializationOptions,
|
||||||
traceOutputChannel,
|
traceOutputChannel,
|
||||||
outputChannel,
|
outputChannel,
|
||||||
|
@ -447,9 +447,9 @@ impl FnData {
|
|||||||
#[allow(clippy::literal_string_with_formatting_args)]
|
#[allow(clippy::literal_string_with_formatting_args)]
|
||||||
pub(super) fn to_autocomplete_snippet(&self) -> String {
|
pub(super) fn to_autocomplete_snippet(&self) -> String {
|
||||||
if self.name == "loft" {
|
if self.name == "loft" {
|
||||||
return "loft([${0:sketch000}, ${1:sketch001}])${}".to_owned();
|
return "loft([${0:sketch000}, ${1:sketch001}])".to_owned();
|
||||||
} else if self.name == "hole" {
|
} else if self.name == "hole" {
|
||||||
return "hole(${0:holeSketch}, ${1:%})${}".to_owned();
|
return "hole(${0:holeSketch}, ${1:%})".to_owned();
|
||||||
}
|
}
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
@ -459,9 +459,7 @@ impl FnData {
|
|||||||
args.push(arg_str);
|
args.push(arg_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We end with ${} so you can jump to the end of the snippet.
|
format!("{}({})", self.preferred_name, args.join(", "))
|
||||||
// After the last argument.
|
|
||||||
format!("{}({})${{}}", self.preferred_name, args.join(", "))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_signature_help(&self) -> SignatureHelp {
|
fn to_signature_help(&self) -> SignatureHelp {
|
||||||
|
@ -501,9 +501,9 @@ pub trait StdLibFn: std::fmt::Debug + Send + Sync {
|
|||||||
#[allow(clippy::literal_string_with_formatting_args)]
|
#[allow(clippy::literal_string_with_formatting_args)]
|
||||||
fn to_autocomplete_snippet(&self) -> Result<String> {
|
fn to_autocomplete_snippet(&self) -> Result<String> {
|
||||||
if self.name() == "loft" {
|
if self.name() == "loft" {
|
||||||
return Ok("loft([${0:sketch000}, ${1:sketch001}])${}".to_string());
|
return Ok("loft([${0:sketch000}, ${1:sketch001}])".to_string());
|
||||||
} else if self.name() == "hole" {
|
} else if self.name() == "hole" {
|
||||||
return Ok("hole(${0:holeSketch}, ${1:%})${}".to_string());
|
return Ok("hole(${0:holeSketch}, ${1:%})".to_string());
|
||||||
}
|
}
|
||||||
let in_keyword_fn = self.keyword_arguments();
|
let in_keyword_fn = self.keyword_arguments();
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
@ -514,9 +514,7 @@ pub trait StdLibFn: std::fmt::Debug + Send + Sync {
|
|||||||
args.push(arg_str);
|
args.push(arg_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We end with ${} so you can jump to the end of the snippet.
|
Ok(format!("{}({})", self.name(), args.join(", ")))
|
||||||
// After the last argument.
|
|
||||||
Ok(format!("{}({})${{}}", self.name(), args.join(", ")))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_signature_help(&self) -> SignatureHelp {
|
fn to_signature_help(&self) -> SignatureHelp {
|
||||||
@ -894,7 +892,7 @@ mod tests {
|
|||||||
fn get_autocomplete_snippet_line() {
|
fn get_autocomplete_snippet_line() {
|
||||||
let line_fn: Box<dyn StdLibFn> = Box::new(crate::std::sketch::Line);
|
let line_fn: Box<dyn StdLibFn> = Box::new(crate::std::sketch::Line);
|
||||||
let snippet = line_fn.to_autocomplete_snippet().unwrap();
|
let snippet = line_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(snippet, r#"line(${0:%}, end = [${1:3.14}, ${2:3.14}])${}"#);
|
assert_eq!(snippet, r#"line(${0:%}, end = [${1:3.14}, ${2:3.14}])"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -902,7 +900,7 @@ mod tests {
|
|||||||
fn get_autocomplete_snippet_extrude() {
|
fn get_autocomplete_snippet_extrude() {
|
||||||
let extrude_fn: Box<dyn StdLibFn> = Box::new(crate::std::extrude::Extrude);
|
let extrude_fn: Box<dyn StdLibFn> = Box::new(crate::std::extrude::Extrude);
|
||||||
let snippet = extrude_fn.to_autocomplete_snippet().unwrap();
|
let snippet = extrude_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(snippet, r#"extrude(${0:%}, length = ${1:3.14})${}"#);
|
assert_eq!(snippet, r#"extrude(${0:%}, length = ${1:3.14})"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -912,7 +910,7 @@ mod tests {
|
|||||||
let snippet = fillet_fn.to_autocomplete_snippet().unwrap();
|
let snippet = fillet_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
snippet,
|
snippet,
|
||||||
r#"fillet(${0:%}, radius = ${1:3.14}, tags = [${2:"tag_or_edge_fn"}])${}"#
|
r#"fillet(${0:%}, radius = ${1:3.14}, tags = [${2:"tag_or_edge_fn"}])"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -920,7 +918,7 @@ mod tests {
|
|||||||
fn get_autocomplete_snippet_start_sketch_on() {
|
fn get_autocomplete_snippet_start_sketch_on() {
|
||||||
let start_sketch_on_fn: Box<dyn StdLibFn> = Box::new(crate::std::sketch::StartSketchOn);
|
let start_sketch_on_fn: Box<dyn StdLibFn> = Box::new(crate::std::sketch::StartSketchOn);
|
||||||
let snippet = start_sketch_on_fn.to_autocomplete_snippet().unwrap();
|
let snippet = start_sketch_on_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(snippet, r#"startSketchOn(${0:"XY"})${}"#);
|
assert_eq!(snippet, r#"startSketchOn(${0:"XY"})"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -931,7 +929,7 @@ mod tests {
|
|||||||
let snippet = pattern_fn.to_autocomplete_snippet().unwrap();
|
let snippet = pattern_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
snippet,
|
snippet,
|
||||||
r#"patternCircular3d(${0:%}, instances = ${1:10}, axis = [${2:3.14}, ${3:3.14}, ${4:3.14}], center = [${5:3.14}, ${6:3.14}, ${7:3.14}], arcDegrees = ${8:3.14}, rotateDuplicates = ${9:false})${}"#
|
r#"patternCircular3d(${0:%}, instances = ${1:10}, axis = [${2:3.14}, ${3:3.14}, ${4:3.14}], center = [${5:3.14}, ${6:3.14}, ${7:3.14}], arcDegrees = ${8:3.14}, rotateDuplicates = ${9:false})"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,7 +940,7 @@ mod tests {
|
|||||||
panic!();
|
panic!();
|
||||||
};
|
};
|
||||||
let snippet = revolve_fn.to_autocomplete_snippet();
|
let snippet = revolve_fn.to_autocomplete_snippet();
|
||||||
assert_eq!(snippet, r#"revolve(axis = ${0:X})${}"#);
|
assert_eq!(snippet, r#"revolve(axis = ${0:X})"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -955,7 +953,7 @@ mod tests {
|
|||||||
let snippet = circle_fn.to_autocomplete_snippet();
|
let snippet = circle_fn.to_autocomplete_snippet();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
snippet,
|
snippet,
|
||||||
r#"circle(center = [${0:3.14}, ${1:3.14}], radius = ${2:3.14})${}"#
|
r#"circle(center = [${0:3.14}, ${1:3.14}], radius = ${2:3.14})"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -970,7 +968,7 @@ mod tests {
|
|||||||
angleStart = ${0:3.14},
|
angleStart = ${0:3.14},
|
||||||
angleEnd = ${1:3.14},
|
angleEnd = ${1:3.14},
|
||||||
radius = ${2:3.14},
|
radius = ${2:3.14},
|
||||||
}, ${3:%})${}"#
|
}, ${3:%})"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -978,7 +976,7 @@ mod tests {
|
|||||||
fn get_autocomplete_snippet_map() {
|
fn get_autocomplete_snippet_map() {
|
||||||
let map_fn: Box<dyn StdLibFn> = Box::new(crate::std::array::Map);
|
let map_fn: Box<dyn StdLibFn> = Box::new(crate::std::array::Map);
|
||||||
let snippet = map_fn.to_autocomplete_snippet().unwrap();
|
let snippet = map_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(snippet, r#"map(${0:[0..9]})${}"#);
|
assert_eq!(snippet, r#"map(${0:[0..9]})"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -988,7 +986,7 @@ mod tests {
|
|||||||
let snippet = pattern_fn.to_autocomplete_snippet().unwrap();
|
let snippet = pattern_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
snippet,
|
snippet,
|
||||||
r#"patternLinear2d(${0:%}, instances = ${1:10}, distance = ${2:3.14}, axis = [${3:3.14}, ${4:3.14}])${}"#
|
r#"patternLinear2d(${0:%}, instances = ${1:10}, distance = ${2:3.14}, axis = [${3:3.14}, ${4:3.14}])"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -998,7 +996,7 @@ mod tests {
|
|||||||
let snippet = appearance_fn.to_autocomplete_snippet().unwrap();
|
let snippet = appearance_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
snippet,
|
snippet,
|
||||||
r#"appearance(${0:%}, color = ${1:"#.to_owned() + "\"#" + r#"ff0000"})${}"#
|
r#"appearance(${0:%}, color = ${1:"#.to_owned() + "\"#" + r#"ff0000"})"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1007,7 +1005,7 @@ mod tests {
|
|||||||
fn get_autocomplete_snippet_loft() {
|
fn get_autocomplete_snippet_loft() {
|
||||||
let loft_fn: Box<dyn StdLibFn> = Box::new(crate::std::loft::Loft);
|
let loft_fn: Box<dyn StdLibFn> = Box::new(crate::std::loft::Loft);
|
||||||
let snippet = loft_fn.to_autocomplete_snippet().unwrap();
|
let snippet = loft_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(snippet, r#"loft([${0:sketch000}, ${1:sketch001}])${}"#);
|
assert_eq!(snippet, r#"loft([${0:sketch000}, ${1:sketch001}])"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1015,7 +1013,7 @@ mod tests {
|
|||||||
fn get_autocomplete_snippet_sweep() {
|
fn get_autocomplete_snippet_sweep() {
|
||||||
let sweep_fn: Box<dyn StdLibFn> = Box::new(crate::std::sweep::Sweep);
|
let sweep_fn: Box<dyn StdLibFn> = Box::new(crate::std::sweep::Sweep);
|
||||||
let snippet = sweep_fn.to_autocomplete_snippet().unwrap();
|
let snippet = sweep_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(snippet, r#"sweep(${0:%}, path = ${1:sketch000})${}"#);
|
assert_eq!(snippet, r#"sweep(${0:%}, path = ${1:sketch000})"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1023,7 +1021,7 @@ mod tests {
|
|||||||
fn get_autocomplete_snippet_hole() {
|
fn get_autocomplete_snippet_hole() {
|
||||||
let hole_fn: Box<dyn StdLibFn> = Box::new(crate::std::sketch::Hole);
|
let hole_fn: Box<dyn StdLibFn> = Box::new(crate::std::sketch::Hole);
|
||||||
let snippet = hole_fn.to_autocomplete_snippet().unwrap();
|
let snippet = hole_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(snippet, r#"hole(${0:holeSketch}, ${1:%})${}"#);
|
assert_eq!(snippet, r#"hole(${0:holeSketch}, ${1:%})"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1036,7 +1034,7 @@ mod tests {
|
|||||||
let snippet = helix_fn.to_autocomplete_snippet();
|
let snippet = helix_fn.to_autocomplete_snippet();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
snippet,
|
snippet,
|
||||||
r#"helix(revolutions = ${0:3.14}, angleStart = ${1:3.14}, radius = ${2:3.14}, axis = ${3:X}, length = ${4:3.14})${}"#
|
r#"helix(revolutions = ${0:3.14}, angleStart = ${1:3.14}, radius = ${2:3.14}, axis = ${3:X}, length = ${4:3.14})"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1045,7 +1043,7 @@ mod tests {
|
|||||||
fn get_autocomplete_snippet_union() {
|
fn get_autocomplete_snippet_union() {
|
||||||
let union_fn: Box<dyn StdLibFn> = Box::new(crate::std::csg::Union);
|
let union_fn: Box<dyn StdLibFn> = Box::new(crate::std::csg::Union);
|
||||||
let snippet = union_fn.to_autocomplete_snippet().unwrap();
|
let snippet = union_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(snippet, r#"union(${0:%})${}"#);
|
assert_eq!(snippet, r#"union(${0:%})"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1053,7 +1051,7 @@ mod tests {
|
|||||||
fn get_autocomplete_snippet_subtract() {
|
fn get_autocomplete_snippet_subtract() {
|
||||||
let subtract_fn: Box<dyn StdLibFn> = Box::new(crate::std::csg::Subtract);
|
let subtract_fn: Box<dyn StdLibFn> = Box::new(crate::std::csg::Subtract);
|
||||||
let snippet = subtract_fn.to_autocomplete_snippet().unwrap();
|
let snippet = subtract_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(snippet, r#"subtract(${0:%}, tools = ${1:%})${}"#);
|
assert_eq!(snippet, r#"subtract(${0:%}, tools = ${1:%})"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1061,7 +1059,7 @@ mod tests {
|
|||||||
fn get_autocomplete_snippet_intersect() {
|
fn get_autocomplete_snippet_intersect() {
|
||||||
let intersect_fn: Box<dyn StdLibFn> = Box::new(crate::std::csg::Intersect);
|
let intersect_fn: Box<dyn StdLibFn> = Box::new(crate::std::csg::Intersect);
|
||||||
let snippet = intersect_fn.to_autocomplete_snippet().unwrap();
|
let snippet = intersect_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(snippet, r#"intersect(${0:%})${}"#);
|
assert_eq!(snippet, r#"intersect(${0:%})"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1073,7 +1071,7 @@ mod tests {
|
|||||||
snippet,
|
snippet,
|
||||||
r#"getCommonEdge(faces = [{
|
r#"getCommonEdge(faces = [{
|
||||||
value = ${0:"string"},
|
value = ${0:"string"},
|
||||||
}])${}"#
|
}])"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1082,10 +1080,7 @@ mod tests {
|
|||||||
fn get_autocomplete_snippet_scale() {
|
fn get_autocomplete_snippet_scale() {
|
||||||
let scale_fn: Box<dyn StdLibFn> = Box::new(crate::std::transform::Scale);
|
let scale_fn: Box<dyn StdLibFn> = Box::new(crate::std::transform::Scale);
|
||||||
let snippet = scale_fn.to_autocomplete_snippet().unwrap();
|
let snippet = scale_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(snippet, r#"scale(${0:%}, x = ${1:3.14}, y = ${2:3.14}, z = ${3:3.14})"#);
|
||||||
snippet,
|
|
||||||
r#"scale(${0:%}, x = ${1:3.14}, y = ${2:3.14}, z = ${3:3.14})${}"#
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1095,7 +1090,7 @@ mod tests {
|
|||||||
let snippet = translate_fn.to_autocomplete_snippet().unwrap();
|
let snippet = translate_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
snippet,
|
snippet,
|
||||||
r#"translate(${0:%}, x = ${1:3.14}, y = ${2:3.14}, z = ${3:3.14})${}"#
|
r#"translate(${0:%}, x = ${1:3.14}, y = ${2:3.14}, z = ${3:3.14})"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1106,7 +1101,7 @@ mod tests {
|
|||||||
let snippet = rotate_fn.to_autocomplete_snippet().unwrap();
|
let snippet = rotate_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
snippet,
|
snippet,
|
||||||
r#"rotate(${0:%}, roll = ${1:3.14}, pitch = ${2:3.14}, yaw = ${3:3.14})${}"#
|
r#"rotate(${0:%}, roll = ${1:3.14}, pitch = ${2:3.14}, yaw = ${3:3.14})"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3418,3 +3418,148 @@ async fn kcl_test_kcl_lsp_multi_file_error() {
|
|||||||
|
|
||||||
server.executor_ctx().await.clone().unwrap().close().await;
|
server.executor_ctx().await.clone().unwrap().close().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
|
async fn test_kcl_lsp_on_hover_untitled_file_scheme() {
|
||||||
|
let server = kcl_lsp_server(true).await.unwrap();
|
||||||
|
|
||||||
|
// Send open file.
|
||||||
|
server
|
||||||
|
.did_open(tower_lsp::lsp_types::DidOpenTextDocumentParams {
|
||||||
|
text_document: tower_lsp::lsp_types::TextDocumentItem {
|
||||||
|
uri: "untitled:Untitled-1".try_into().unwrap(),
|
||||||
|
language_id: "kcl".to_string(),
|
||||||
|
version: 1,
|
||||||
|
text: r#"startSketchOn(XY)
|
||||||
|
foo = 42
|
||||||
|
foo
|
||||||
|
|
||||||
|
fn bar(x: string): string {
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
bar("an arg")
|
||||||
|
|
||||||
|
startSketchOn(XY)
|
||||||
|
|> startProfileAt([0, 0], %)
|
||||||
|
|> line(end = [10, 0])
|
||||||
|
|> line(end = [0, 10])
|
||||||
|
"#
|
||||||
|
.to_string(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// Std lib call
|
||||||
|
let hover = server
|
||||||
|
.hover(tower_lsp::lsp_types::HoverParams {
|
||||||
|
text_document_position_params: tower_lsp::lsp_types::TextDocumentPositionParams {
|
||||||
|
text_document: tower_lsp::lsp_types::TextDocumentIdentifier {
|
||||||
|
uri: "untitled:Untitled-1".try_into().unwrap(),
|
||||||
|
},
|
||||||
|
position: tower_lsp::lsp_types::Position { line: 0, character: 2 },
|
||||||
|
},
|
||||||
|
work_done_progress_params: Default::default(),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
match hover.unwrap().contents {
|
||||||
|
tower_lsp::lsp_types::HoverContents::Markup(tower_lsp::lsp_types::MarkupContent { value, .. }) => {
|
||||||
|
assert!(value.contains("startSketchOn"));
|
||||||
|
assert!(value.contains(": SketchSurface"));
|
||||||
|
assert!(value.contains("Start a new 2-dimensional sketch on a specific"));
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variable use
|
||||||
|
let hover = server
|
||||||
|
.hover(tower_lsp::lsp_types::HoverParams {
|
||||||
|
text_document_position_params: tower_lsp::lsp_types::TextDocumentPositionParams {
|
||||||
|
text_document: tower_lsp::lsp_types::TextDocumentIdentifier {
|
||||||
|
uri: "untitled:Untitled-1".try_into().unwrap(),
|
||||||
|
},
|
||||||
|
position: tower_lsp::lsp_types::Position { line: 2, character: 1 },
|
||||||
|
},
|
||||||
|
work_done_progress_params: Default::default(),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
match hover.unwrap().contents {
|
||||||
|
tower_lsp::lsp_types::HoverContents::Markup(tower_lsp::lsp_types::MarkupContent { value, .. }) => {
|
||||||
|
assert!(value.contains("foo: number = 42"));
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// User-defined function call.
|
||||||
|
let hover = server
|
||||||
|
.hover(tower_lsp::lsp_types::HoverParams {
|
||||||
|
text_document_position_params: tower_lsp::lsp_types::TextDocumentPositionParams {
|
||||||
|
text_document: tower_lsp::lsp_types::TextDocumentIdentifier {
|
||||||
|
uri: "untitled:Untitled-1".try_into().unwrap(),
|
||||||
|
},
|
||||||
|
position: tower_lsp::lsp_types::Position { line: 8, character: 1 },
|
||||||
|
},
|
||||||
|
work_done_progress_params: Default::default(),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
match hover.unwrap().contents {
|
||||||
|
tower_lsp::lsp_types::HoverContents::Markup(tower_lsp::lsp_types::MarkupContent { value, .. }) => {
|
||||||
|
assert!(value.contains("bar(x: string): string"));
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variable inside a function
|
||||||
|
let hover = server
|
||||||
|
.hover(tower_lsp::lsp_types::HoverParams {
|
||||||
|
text_document_position_params: tower_lsp::lsp_types::TextDocumentPositionParams {
|
||||||
|
text_document: tower_lsp::lsp_types::TextDocumentIdentifier {
|
||||||
|
uri: "untitled:Untitled-1".try_into().unwrap(),
|
||||||
|
},
|
||||||
|
position: tower_lsp::lsp_types::Position { line: 5, character: 9 },
|
||||||
|
},
|
||||||
|
work_done_progress_params: Default::default(),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
match hover.unwrap().contents {
|
||||||
|
tower_lsp::lsp_types::HoverContents::Markup(tower_lsp::lsp_types::MarkupContent { value, .. }) => {
|
||||||
|
assert!(value.contains("x: string"));
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// std function KwArg
|
||||||
|
let hover = server
|
||||||
|
.hover(tower_lsp::lsp_types::HoverParams {
|
||||||
|
text_document_position_params: tower_lsp::lsp_types::TextDocumentPositionParams {
|
||||||
|
text_document: tower_lsp::lsp_types::TextDocumentIdentifier {
|
||||||
|
uri: "untitled:Untitled-1".try_into().unwrap(),
|
||||||
|
},
|
||||||
|
position: tower_lsp::lsp_types::Position {
|
||||||
|
line: 12,
|
||||||
|
character: 11,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
work_done_progress_params: Default::default(),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
match hover.unwrap().contents {
|
||||||
|
tower_lsp::lsp_types::HoverContents::Markup(tower_lsp::lsp_types::MarkupContent { value, .. }) => {
|
||||||
|
assert!(value.contains("end?: [number]"));
|
||||||
|
assert!(value.contains("How far away (along the X and Y axes) should this line go?"));
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
server.executor_ctx().await.clone().unwrap().close().await;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user