Compare commits

..

3 Commits

Author SHA1 Message Date
Said A.
c7f55e8718
Merge 7acb4e203d93e711e2bf25e6fffac909faeac8ed into d1deb80bb8b4d5fad348c23a3e079e4854aa57e4 2025-07-07 10:46:52 +00:00
Said Aroua
7acb4e203d Add autocomplete tests 2025-07-07 12:46:23 +02:00
Said Aroua
ecb0be4db4 Fix regression in autocomplete of references 2025-07-07 12:32:01 +02:00

View File

@ -76,7 +76,7 @@ pub struct Completion {
} }
/// A kind of item that can be completed. /// A kind of item that can be completed.
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
pub enum CompletionKind { pub enum CompletionKind {
/// A syntactical structure. /// A syntactical structure.
@ -130,7 +130,14 @@ fn complete_markup(ctx: &mut CompletionContext) -> bool {
return true; return true;
} }
// Start of a reference: "@|" or "@he|". // Start of a reference: "@|".
if ctx.leaf.kind() == SyntaxKind::Text && ctx.before.ends_with("@") {
ctx.from = ctx.cursor;
ctx.label_completions();
return true;
}
// An existing reference: "@he|".
if ctx.leaf.kind() == SyntaxKind::RefMarker { if ctx.leaf.kind() == SyntaxKind::RefMarker {
ctx.from = ctx.leaf.offset() + 1; ctx.from = ctx.leaf.offset() + 1;
ctx.label_completions(); ctx.label_completions();
@ -1564,7 +1571,7 @@ mod tests {
use typst::layout::PagedDocument; use typst::layout::PagedDocument;
use super::{autocomplete, Completion}; use super::{autocomplete, Completion, CompletionKind};
use crate::tests::{FilePos, TestWorld, WorldLike}; use crate::tests::{FilePos, TestWorld, WorldLike};
/// Quote a string. /// Quote a string.
@ -1730,6 +1737,33 @@ mod tests {
test_with_doc(&world, -1, doc.as_ref()).must_include(["test"]); test_with_doc(&world, -1, doc.as_ref()).must_include(["test"]);
} }
#[test]
fn test_autocomplete_ref_shorthand_with_partial_identifier() {
let mut world = TestWorld::new("x<test>");
let doc = typst::compile(&world).output.ok();
let end = world.main.text().len();
world.main.edit(end..end, " @te");
test_with_doc(&world, -1, doc.as_ref()).must_include(["test"]);
}
#[test]
fn test_autocomplete_ref_identical_labels_returns_single_completion() {
let mut world = TestWorld::new("x<test> y<test>");
let doc = typst::compile(&world).output.ok();
let end = world.main.text().len();
world.main.edit(end..end, " @");
let result = test_with_doc(&world, -1, doc.as_ref());
let completions = result.completions();
let label_count =
completions.iter().filter(|c| c.kind == CompletionKind::Label).count();
assert_eq!(label_count, 1);
}
/// Test what kind of brackets we autocomplete for function calls depending /// Test what kind of brackets we autocomplete for function calls depending
/// on the function and existing parens. /// on the function and existing parens.
#[test] #[test]