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) {
 | 
			
		||||
          // 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)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,10 @@ export async function createClient(
 | 
			
		||||
  serverOptions: lc.ServerOptions
 | 
			
		||||
): Promise<lc.LanguageClient> {
 | 
			
		||||
  const clientOptions: lc.LanguageClientOptions = {
 | 
			
		||||
    documentSelector: [{ scheme: 'file', language: 'kcl' }],
 | 
			
		||||
    documentSelector: [
 | 
			
		||||
      { scheme: 'file', language: 'kcl' },
 | 
			
		||||
      { scheme: 'untitled', language: 'kcl' },
 | 
			
		||||
    ],
 | 
			
		||||
    initializationOptions,
 | 
			
		||||
    traceOutputChannel,
 | 
			
		||||
    outputChannel,
 | 
			
		||||
 | 
			
		||||
@ -447,9 +447,9 @@ impl FnData {
 | 
			
		||||
    #[allow(clippy::literal_string_with_formatting_args)]
 | 
			
		||||
    pub(super) fn to_autocomplete_snippet(&self) -> String {
 | 
			
		||||
        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" {
 | 
			
		||||
            return "hole(${0:holeSketch}, ${1:%})${}".to_owned();
 | 
			
		||||
            return "hole(${0:holeSketch}, ${1:%})".to_owned();
 | 
			
		||||
        }
 | 
			
		||||
        let mut args = Vec::new();
 | 
			
		||||
        let mut index = 0;
 | 
			
		||||
@ -459,9 +459,7 @@ impl FnData {
 | 
			
		||||
                args.push(arg_str);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // We end with ${} so you can jump to the end of the snippet.
 | 
			
		||||
        // After the last argument.
 | 
			
		||||
        format!("{}({})${{}}", self.preferred_name, args.join(", "))
 | 
			
		||||
        format!("{}({})", self.preferred_name, args.join(", "))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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)]
 | 
			
		||||
    fn to_autocomplete_snippet(&self) -> Result<String> {
 | 
			
		||||
        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" {
 | 
			
		||||
            return Ok("hole(${0:holeSketch}, ${1:%})${}".to_string());
 | 
			
		||||
            return Ok("hole(${0:holeSketch}, ${1:%})".to_string());
 | 
			
		||||
        }
 | 
			
		||||
        let in_keyword_fn = self.keyword_arguments();
 | 
			
		||||
        let mut args = Vec::new();
 | 
			
		||||
@ -514,9 +514,7 @@ pub trait StdLibFn: std::fmt::Debug + Send + Sync {
 | 
			
		||||
                args.push(arg_str);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // We end with ${} so you can jump to the end of the snippet.
 | 
			
		||||
        // After the last argument.
 | 
			
		||||
        Ok(format!("{}({})${{}}", self.name(), args.join(", ")))
 | 
			
		||||
        Ok(format!("{}({})", self.name(), args.join(", ")))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn to_signature_help(&self) -> SignatureHelp {
 | 
			
		||||
@ -894,7 +892,7 @@ mod tests {
 | 
			
		||||
    fn get_autocomplete_snippet_line() {
 | 
			
		||||
        let line_fn: Box<dyn StdLibFn> = Box::new(crate::std::sketch::Line);
 | 
			
		||||
        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]
 | 
			
		||||
@ -902,7 +900,7 @@ mod tests {
 | 
			
		||||
    fn get_autocomplete_snippet_extrude() {
 | 
			
		||||
        let extrude_fn: Box<dyn StdLibFn> = Box::new(crate::std::extrude::Extrude);
 | 
			
		||||
        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]
 | 
			
		||||
@ -912,7 +910,7 @@ mod tests {
 | 
			
		||||
        let snippet = fillet_fn.to_autocomplete_snippet().unwrap();
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            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() {
 | 
			
		||||
        let start_sketch_on_fn: Box<dyn StdLibFn> = Box::new(crate::std::sketch::StartSketchOn);
 | 
			
		||||
        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]
 | 
			
		||||
@ -931,7 +929,7 @@ mod tests {
 | 
			
		||||
        let snippet = pattern_fn.to_autocomplete_snippet().unwrap();
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            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!();
 | 
			
		||||
        };
 | 
			
		||||
        let snippet = revolve_fn.to_autocomplete_snippet();
 | 
			
		||||
        assert_eq!(snippet, r#"revolve(axis = ${0:X})${}"#);
 | 
			
		||||
        assert_eq!(snippet, r#"revolve(axis = ${0:X})"#);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
@ -955,7 +953,7 @@ mod tests {
 | 
			
		||||
        let snippet = circle_fn.to_autocomplete_snippet();
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            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},
 | 
			
		||||
	angleEnd = ${1:3.14},
 | 
			
		||||
	radius = ${2:3.14},
 | 
			
		||||
}, ${3:%})${}"#
 | 
			
		||||
}, ${3:%})"#
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -978,7 +976,7 @@ mod tests {
 | 
			
		||||
    fn get_autocomplete_snippet_map() {
 | 
			
		||||
        let map_fn: Box<dyn StdLibFn> = Box::new(crate::std::array::Map);
 | 
			
		||||
        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]
 | 
			
		||||
@ -988,7 +986,7 @@ mod tests {
 | 
			
		||||
        let snippet = pattern_fn.to_autocomplete_snippet().unwrap();
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            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();
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            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() {
 | 
			
		||||
        let loft_fn: Box<dyn StdLibFn> = Box::new(crate::std::loft::Loft);
 | 
			
		||||
        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]
 | 
			
		||||
@ -1015,7 +1013,7 @@ mod tests {
 | 
			
		||||
    fn get_autocomplete_snippet_sweep() {
 | 
			
		||||
        let sweep_fn: Box<dyn StdLibFn> = Box::new(crate::std::sweep::Sweep);
 | 
			
		||||
        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]
 | 
			
		||||
@ -1023,7 +1021,7 @@ mod tests {
 | 
			
		||||
    fn get_autocomplete_snippet_hole() {
 | 
			
		||||
        let hole_fn: Box<dyn StdLibFn> = Box::new(crate::std::sketch::Hole);
 | 
			
		||||
        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]
 | 
			
		||||
@ -1036,7 +1034,7 @@ mod tests {
 | 
			
		||||
        let snippet = helix_fn.to_autocomplete_snippet();
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            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() {
 | 
			
		||||
        let union_fn: Box<dyn StdLibFn> = Box::new(crate::std::csg::Union);
 | 
			
		||||
        let snippet = union_fn.to_autocomplete_snippet().unwrap();
 | 
			
		||||
        assert_eq!(snippet, r#"union(${0:%})${}"#);
 | 
			
		||||
        assert_eq!(snippet, r#"union(${0:%})"#);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
@ -1053,7 +1051,7 @@ mod tests {
 | 
			
		||||
    fn get_autocomplete_snippet_subtract() {
 | 
			
		||||
        let subtract_fn: Box<dyn StdLibFn> = Box::new(crate::std::csg::Subtract);
 | 
			
		||||
        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]
 | 
			
		||||
@ -1061,7 +1059,7 @@ mod tests {
 | 
			
		||||
    fn get_autocomplete_snippet_intersect() {
 | 
			
		||||
        let intersect_fn: Box<dyn StdLibFn> = Box::new(crate::std::csg::Intersect);
 | 
			
		||||
        let snippet = intersect_fn.to_autocomplete_snippet().unwrap();
 | 
			
		||||
        assert_eq!(snippet, r#"intersect(${0:%})${}"#);
 | 
			
		||||
        assert_eq!(snippet, r#"intersect(${0:%})"#);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
@ -1073,7 +1071,7 @@ mod tests {
 | 
			
		||||
            snippet,
 | 
			
		||||
            r#"getCommonEdge(faces = [{
 | 
			
		||||
	value = ${0:"string"},
 | 
			
		||||
}])${}"#
 | 
			
		||||
}])"#
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1082,10 +1080,7 @@ mod tests {
 | 
			
		||||
    fn get_autocomplete_snippet_scale() {
 | 
			
		||||
        let scale_fn: Box<dyn StdLibFn> = Box::new(crate::std::transform::Scale);
 | 
			
		||||
        let snippet = scale_fn.to_autocomplete_snippet().unwrap();
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            snippet,
 | 
			
		||||
            r#"scale(${0:%}, x = ${1:3.14}, y = ${2:3.14}, z = ${3:3.14})${}"#
 | 
			
		||||
        );
 | 
			
		||||
        assert_eq!(snippet, r#"scale(${0:%}, x = ${1:3.14}, y = ${2:3.14}, z = ${3:3.14})"#);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
@ -1095,7 +1090,7 @@ mod tests {
 | 
			
		||||
        let snippet = translate_fn.to_autocomplete_snippet().unwrap();
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            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();
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[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