feat(lsp): add completions for type system keywords
Added top-level keyword completions for: - concept: with semicolon-terminated snippet - sub_concept: with dot notation snippet - concept_comparison: with brace-delimited snippet Added test verifying type system keywords appear in completions with correct snippet formatting.
This commit is contained in:
@@ -683,6 +683,9 @@ fn top_level_keyword_completions() -> Vec<CompletionItem> {
|
|||||||
keyword_item("location", "Define a location", "location ${1:Name} {\n $0\n}"),
|
keyword_item("location", "Define a location", "location ${1:Name} {\n $0\n}"),
|
||||||
keyword_item("species", "Define a species", "species ${1:Name} {\n $0\n}"),
|
keyword_item("species", "Define a species", "species ${1:Name} {\n $0\n}"),
|
||||||
keyword_item("use", "Import declarations", "use ${1:path::to::item};"),
|
keyword_item("use", "Import declarations", "use ${1:path::to::item};"),
|
||||||
|
keyword_item("concept", "Define an algebraic data type", "concept ${1:Name};"),
|
||||||
|
keyword_item("sub_concept", "Define a sub-type", "sub_concept ${1:Parent}.${2:Name} {\n $0\n}"),
|
||||||
|
keyword_item("concept_comparison", "Pattern match on concepts", "concept_comparison ${1:Name} {\n $0\n}"),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -248,6 +248,57 @@ character Bob {}"#;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_type_system_completions() {
|
||||||
|
let doc = Document::new("".to_string());
|
||||||
|
let params = make_params(0, 0);
|
||||||
|
|
||||||
|
let result = completion::get_completions(&doc, ¶ms);
|
||||||
|
assert!(result.is_some());
|
||||||
|
|
||||||
|
if let Some(response) = result {
|
||||||
|
match response {
|
||||||
|
| tower_lsp::lsp_types::CompletionResponse::Array(items) => {
|
||||||
|
// Should have type system keywords
|
||||||
|
assert!(
|
||||||
|
items.iter().any(|item| item.label == "concept"),
|
||||||
|
"Should have concept keyword"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
items.iter().any(|item| item.label == "sub_concept"),
|
||||||
|
"Should have sub_concept keyword"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
items.iter().any(|item| item.label == "concept_comparison"),
|
||||||
|
"Should have concept_comparison keyword"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check snippets have correct format
|
||||||
|
let concept_item = items.iter().find(|item| item.label == "concept");
|
||||||
|
assert!(concept_item.is_some());
|
||||||
|
if let Some(item) = concept_item {
|
||||||
|
let snippet = item.insert_text.as_ref().unwrap();
|
||||||
|
assert!(
|
||||||
|
snippet.contains(";"),
|
||||||
|
"concept snippet should end with semicolon"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let sub_item = items.iter().find(|item| item.label == "sub_concept");
|
||||||
|
assert!(sub_item.is_some());
|
||||||
|
if let Some(item) = sub_item {
|
||||||
|
let snippet = item.insert_text.as_ref().unwrap();
|
||||||
|
assert!(
|
||||||
|
snippet.contains("."),
|
||||||
|
"sub_concept snippet should contain dot notation"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
| _ => panic!("Expected array response"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_no_duplicate_completions() {
|
fn test_no_duplicate_completions() {
|
||||||
let source = "character Alice {}\ncharacter Alice {}"; // Duplicate name
|
let source = "character Alice {}\ncharacter Alice {}"; // Duplicate name
|
||||||
|
|||||||
Reference in New Issue
Block a user