Fix #cite autocompletion

This commit is contained in:
Laurenz 2024-11-09 11:38:13 +01:00
parent 6f294eac56
commit c526f031cc
2 changed files with 38 additions and 2 deletions

View File

@ -1050,7 +1050,7 @@ impl<'a> CompletionContext<'a> {
/// A small window of context before the cursor.
fn before_window(&self, size: usize) -> &str {
Scanner::new(self.before).from(self.cursor.saturating_sub(size))
Scanner::new(self.before).get(self.cursor.saturating_sub(size)..self.cursor)
}
/// Add a prefix and suffix to all applications.
@ -1455,4 +1455,23 @@ mod tests {
fn test_autocomplete_before_window_char_boundary() {
test("😀😀 #text(font: \"\")", -2);
}
/// Ensure that autocompletion for `#cite(|)` completes bibligraphy labels,
/// but no other labels.
#[test]
fn test_autocomplete_cite_function() {
// First compile a working file to get a document.
let mut world = TestWorld::new("#bibliography(\"works.bib\") <bib>")
.with_asset_by_name("works.bib");
let doc = typst::compile(&world).output.ok();
// Then, add the invalid `#cite` call. Had the document been invalid
// initially, we would have no populated document to autocomplete with.
let end = world.main.len_bytes();
world.main.edit(end..end, " #cite()");
test_with_world_and_doc(&world, doc.as_ref(), -1)
.must_include(["netwok", "glacier-melt", "supplement"])
.must_exclude(["bib"]);
}
}

View File

@ -97,6 +97,8 @@ fn summarize_font_family<'a>(variants: impl Iterator<Item = &'a FontInfo>) -> Ec
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use typst::diag::{FileError, FileResult};
use typst::foundations::{Bytes, Datetime, Smart};
use typst::layout::{Abs, Margin, PageElem};
@ -108,6 +110,7 @@ mod tests {
/// A world for IDE testing.
pub struct TestWorld {
pub main: Source,
assets: HashMap<FileId, Bytes>,
base: &'static TestBase,
}
@ -120,10 +123,21 @@ mod tests {
let main = Source::new(Self::main_id(), text.into());
Self {
main,
assets: HashMap::new(),
base: singleton!(TestBase, TestBase::default()),
}
}
/// Add an additional file to the test world.
#[track_caller]
pub fn with_asset_by_name(mut self, filename: &str) -> Self {
let id = FileId::new(None, VirtualPath::new(filename));
let data = typst_dev_assets::get_by_name(filename).unwrap();
let bytes = Bytes::from_static(data);
self.assets.insert(id, bytes);
self
}
/// The ID of the main file in a `TestWorld`.
pub fn main_id() -> FileId {
*singleton!(FileId, FileId::new(None, VirtualPath::new("main.typ")))
@ -152,7 +166,10 @@ mod tests {
}
fn file(&self, id: FileId) -> FileResult<Bytes> {
Err(FileError::NotFound(id.vpath().as_rootless_path().into()))
match self.assets.get(&id) {
Some(bytes) => Ok(bytes.clone()),
None => Err(FileError::NotFound(id.vpath().as_rootless_path().into())),
}
}
fn font(&self, index: usize) -> Option<Font> {