diff --git a/kclvm/tools/src/LSP/src/completion.rs b/kclvm/tools/src/LSP/src/completion.rs index eb0524acf..ab214e74a 100644 --- a/kclvm/tools/src/LSP/src/completion.rs +++ b/kclvm/tools/src/LSP/src/completion.rs @@ -162,7 +162,7 @@ pub(crate) fn get_completion( pos: &KCLPos, prog_scope: &ProgramScope, ) -> IndexSet { - let expr = inner_most_expr_in_stmt(&stmt.node, pos, None).0; + let (expr, parent) = inner_most_expr_in_stmt(&stmt.node, pos, None); match expr { Some(node) => { let mut items: IndexSet = IndexSet::new(); @@ -233,6 +233,32 @@ pub(crate) fn get_completion( }); } } + Expr::Config(config_expr) => match parent { + Some(schema_expr) => { + if let Expr::Schema(schema_expr) = schema_expr.node { + let schema_def = + find_def(stmt, &schema_expr.name.get_end_pos(), prog_scope); + if let Some(schema) = schema_def { + match schema { + Definition::Object(obj) => { + let schema_type = obj.ty.into_schema_type(); + items.extend( + schema_type + .attrs + .keys() + .map(|s| KCLCompletionItem { + label: s.to_string(), + }) + .collect::>(), + ); + } + Definition::Scope(_) => {} + } + } + } + } + None => {} + }, _ => {} } diff --git a/kclvm/tools/src/LSP/src/goto_def.rs b/kclvm/tools/src/LSP/src/goto_def.rs index 142e7ed10..2d19cccc7 100644 --- a/kclvm/tools/src/LSP/src/goto_def.rs +++ b/kclvm/tools/src/LSP/src/goto_def.rs @@ -124,6 +124,7 @@ pub(crate) fn find_def( } let (inner_expr, parent) = inner_most_expr_in_stmt(&node.node, kcl_pos, None); + if let Some(expr) = inner_expr { if let Expr::Identifier(id) = expr.node { let id_node = Node::node_with_pos( diff --git a/kclvm/tools/src/LSP/src/test_data/completion_test/dot/completion.k b/kclvm/tools/src/LSP/src/test_data/completion_test/dot/completion.k index 8af168856..4a7000b08 100644 --- a/kclvm/tools/src/LSP/src/test_data/completion_test/dot/completion.k +++ b/kclvm/tools/src/LSP/src/test_data/completion_test/dot/completion.k @@ -24,3 +24,7 @@ p4 = Person{ } +schema P: + a: int = 1 + +aaaa = P{}. diff --git a/kclvm/tools/src/LSP/src/tests.rs b/kclvm/tools/src/LSP/src/tests.rs index 3d4c66b20..079d7c2ee 100644 --- a/kclvm/tools/src/LSP/src/tests.rs +++ b/kclvm/tools/src/LSP/src/tests.rs @@ -856,7 +856,7 @@ fn var_completion_test() { items.extend( vec![ "", // generate from error recovery of "pkg." - "subpkg", "math", "Person", "p", "p1", "p2", "p3", "p4", + "subpkg", "math", "Person", "P", "p", "p1", "p2", "p3", "p4", "aaaa", ] .iter() .map(|name| KCLCompletionItem { @@ -994,7 +994,7 @@ fn dot_completion_test() { // test completion for literal str builtin function let pos = KCLPos { - filename: file, + filename: file.clone(), line: 21, column: Some(4), }; @@ -1007,7 +1007,24 @@ fn dot_completion_test() { }); } let expect: CompletionResponse = into_completion_items(&items).into(); + items.clear(); + + assert_eq!(got, expect); + let pos = KCLPos { + filename: file, + line: 30, + column: Some(11), + }; + + let got = completion(Some('.'), &program, &pos, &prog_scope).unwrap(); + items.insert(KCLCompletionItem { + label: "__settings__".to_string(), + }); + items.insert(KCLCompletionItem { + label: "a".to_string(), + }); + let expect: CompletionResponse = into_completion_items(&items).into(); assert_eq!(got, expect); }