diff --git a/crates/tinymist-query/src/completion.rs b/crates/tinymist-query/src/completion.rs index e0abc1a6..429a7eb9 100644 --- a/crates/tinymist-query/src/completion.rs +++ b/crates/tinymist-query/src/completion.rs @@ -308,10 +308,13 @@ mod tests { use super::*; use crate::{syntax::find_module_level_docs, tests::*}; - #[test] - fn test() { - snapshot_testing("completion", &|ctx, path| { - let source = ctx.source_by_path(&path).unwrap(); + struct TestConfig { + pkg_mode: bool, + } + + fn run(c: TestConfig) -> impl Fn(&mut AnalysisContext, PathBuf) { + fn test(ctx: &mut AnalysisContext, id: TypstFileId) { + let source = ctx.source_by_id(id).unwrap(); let rng = find_test_range(&source); let text = source.text()[rng.clone()].to_string(); @@ -367,7 +370,7 @@ mod tests { let mut results = vec![]; for s in rng.clone() { let request = CompletionRequest { - path: path.clone(), + path: ctx.path_for_id(id).unwrap(), position: ctx.to_lsp_pos(s, &source), explicit: false, }; @@ -384,6 +387,30 @@ mod tests { }, { assert_snapshot!(JsonRepr::new_pure(results)); }) - }); + } + + move |ctx, path| { + if c.pkg_mode { + let files = ctx + .source_files() + .iter() + .filter(|id| !id.vpath().as_rootless_path().ends_with("lib.typ")); + for id in files.copied().collect::>() { + test(ctx, id); + } + } else { + test(ctx, ctx.file_id_by_path(&path).unwrap()); + } + } + } + + #[test] + fn test_base() { + snapshot_testing("completion", &run(TestConfig { pkg_mode: false })); + } + + #[test] + fn test_pkgs() { + snapshot_testing("completion-pkgs", &run(TestConfig { pkg_mode: true })); } } diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-_size-to-pt.typ-2.snap b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-_size-to-pt.typ-2.snap new file mode 100644 index 00000000..7c6cf7b5 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-_size-to-pt.typ-2.snap @@ -0,0 +1,12 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: Completion on / (65..66) +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-_size-to-pt.typ +--- +[ + { + "isIncomplete": false, + "items": [] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-_size-to-pt.typ-3.snap b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-_size-to-pt.typ-3.snap new file mode 100644 index 00000000..bdf3cc2d --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-_size-to-pt.typ-3.snap @@ -0,0 +1,12 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: Completion on / (76..77) +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-_size-to-pt.typ +--- +[ + { + "isIncomplete": false, + "items": [] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-_size-to-pt.typ-4.snap b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-_size-to-pt.typ-4.snap new file mode 100644 index 00000000..2db95b79 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-_size-to-pt.typ-4.snap @@ -0,0 +1,12 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: Completion on / (70..71) +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-_size-to-pt.typ +--- +[ + { + "isIncomplete": false, + "items": [] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-_size-to-pt.typ.snap b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-_size-to-pt.typ.snap new file mode 100644 index 00000000..2db95b79 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-_size-to-pt.typ.snap @@ -0,0 +1,12 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: Completion on / (70..71) +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-_size-to-pt.typ +--- +[ + { + "isIncomplete": false, + "items": [] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-current-heading.typ-2.snap b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-current-heading.typ-2.snap new file mode 100644 index 00000000..6e18ed03 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-current-heading.typ-2.snap @@ -0,0 +1,12 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: Completion on / (65..66) +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-current-heading.typ +--- +[ + { + "isIncomplete": false, + "items": [] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-current-heading.typ-3.snap b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-current-heading.typ-3.snap new file mode 100644 index 00000000..79961ee0 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-current-heading.typ-3.snap @@ -0,0 +1,31 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: Completion on / (76..77) +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-current-heading.typ +--- +[ + { + "isIncomplete": false, + "items": [ + { + "kind": 21, + "label": "true", + "sortText": "000", + "textEdit": { + "newText": "true", + "range": { + "end": { + "character": 30, + "line": 2 + }, + "start": { + "character": 30, + "line": 2 + } + } + } + } + ] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-current-heading.typ-4.snap b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-current-heading.typ-4.snap new file mode 100644 index 00000000..8ea3fdea --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-current-heading.typ-4.snap @@ -0,0 +1,31 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: Completion on / (66..67) +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-current-heading.typ +--- +[ + { + "isIncomplete": false, + "items": [ + { + "kind": 21, + "label": "9999", + "sortText": "000", + "textEdit": { + "newText": "9999", + "range": { + "end": { + "character": 24, + "line": 2 + }, + "start": { + "character": 24, + "line": 2 + } + } + } + } + ] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-current-heading.typ.snap b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-current-heading.typ.snap new file mode 100644 index 00000000..1eb6319f --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-current-heading.typ.snap @@ -0,0 +1,67 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: Completion on / (77..78) +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-current-heading.typ +--- +[ + { + "isIncomplete": false, + "items": [ + { + "kind": 5, + "label": "depth", + "sortText": "000", + "textEdit": { + "newText": "depth: ${1:}", + "range": { + "end": { + "character": 17, + "line": 2 + }, + "start": { + "character": 17, + "line": 2 + } + } + } + }, + { + "kind": 5, + "label": "hierachical", + "sortText": "001", + "textEdit": { + "newText": "hierachical: ${1:}", + "range": { + "end": { + "character": 17, + "line": 2 + }, + "start": { + "character": 17, + "line": 2 + } + } + } + }, + { + "kind": 5, + "label": "level", + "sortText": "002", + "textEdit": { + "newText": "level: ${1:}", + "range": { + "end": { + "character": 17, + "line": 2 + }, + "start": { + "character": 17, + "line": 2 + } + } + } + } + ] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-fit-to-height.typ-2.snap b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-fit-to-height.typ-2.snap new file mode 100644 index 00000000..5bd3454c --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-fit-to-height.typ-2.snap @@ -0,0 +1,12 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: Completion on / (67..68) +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-fit-to-height.typ +--- +[ + { + "isIncomplete": false, + "items": [] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-fit-to-height.typ-3.snap b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-fit-to-height.typ-3.snap new file mode 100644 index 00000000..ff22f8db --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-fit-to-height.typ-3.snap @@ -0,0 +1,12 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: Completion on / (59..60) +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-fit-to-height.typ +--- +[ + { + "isIncomplete": false, + "items": [] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-fit-to-height.typ.snap b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-fit-to-height.typ.snap new file mode 100644 index 00000000..ff22f8db --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-fit-to-height.typ.snap @@ -0,0 +1,12 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: Completion on / (59..60) +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-fit-to-height.typ +--- +[ + { + "isIncomplete": false, + "items": [] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-reconstruct.typ-2.snap b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-reconstruct.typ-2.snap new file mode 100644 index 00000000..2d0888d8 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-reconstruct.typ-2.snap @@ -0,0 +1,31 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: Completion on / (65..66) +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-reconstruct.typ +--- +[ + { + "isIncomplete": false, + "items": [ + { + "kind": 21, + "label": "\"body\"", + "sortText": "000", + "textEdit": { + "newText": "\"body\"", + "range": { + "end": { + "character": 24, + "line": 2 + }, + "start": { + "character": 24, + "line": 2 + } + } + } + } + ] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-reconstruct.typ-3.snap b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-reconstruct.typ-3.snap new file mode 100644 index 00000000..64ddc3ea --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-reconstruct.typ-3.snap @@ -0,0 +1,31 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: Completion on / (68..69) +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-reconstruct.typ +--- +[ + { + "isIncomplete": false, + "items": [ + { + "kind": 21, + "label": "true", + "sortText": "000", + "textEdit": { + "newText": "true", + "range": { + "end": { + "character": 22, + "line": 2 + }, + "start": { + "character": 22, + "line": 2 + } + } + } + } + ] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-reconstruct.typ-4.snap b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-reconstruct.typ-4.snap new file mode 100644 index 00000000..2522b66f --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-reconstruct.typ-4.snap @@ -0,0 +1,31 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: Completion on / (66..67) +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-reconstruct.typ +--- +[ + { + "isIncomplete": false, + "items": [ + { + "kind": 21, + "label": "false", + "sortText": "000", + "textEdit": { + "newText": "false", + "range": { + "end": { + "character": 20, + "line": 2 + }, + "start": { + "character": 20, + "line": 2 + } + } + } + } + ] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-reconstruct.typ.snap b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-reconstruct.typ.snap new file mode 100644 index 00000000..fca69725 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/snaps/test@touying-utils-reconstruct.typ.snap @@ -0,0 +1,67 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: Completion on / (87..88) +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-reconstruct.typ +--- +[ + { + "isIncomplete": false, + "items": [ + { + "kind": 5, + "label": "body-name", + "sortText": "000", + "textEdit": { + "newText": "body-name: ${1:}", + "range": { + "end": { + "character": 13, + "line": 2 + }, + "start": { + "character": 13, + "line": 2 + } + } + } + }, + { + "kind": 5, + "label": "labeled", + "sortText": "001", + "textEdit": { + "newText": "labeled: ${1:}", + "range": { + "end": { + "character": 13, + "line": 2 + }, + "start": { + "character": 13, + "line": 2 + } + } + } + }, + { + "kind": 5, + "label": "named", + "sortText": "002", + "textEdit": { + "newText": "named: ${1:}", + "range": { + "end": { + "character": 13, + "line": 2 + }, + "start": { + "character": 13, + "line": 2 + } + } + } + } + ] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-_size-to-pt.typ b/crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-_size-to-pt.typ new file mode 100644 index 00000000..85bc9043 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-_size-to-pt.typ @@ -0,0 +1,25 @@ +// path: lib.typ +// - level (auto, ): The level +#let _size-to-pt(size, container-dimension) = { + let to-convert = size + if type(size) == ratio { + to-convert = container-dimension * size + } + measure(v(to-convert)).height +} +----- +// contains: level, hierachical, depth +#import "lib.typ": * +#current-heading(/* range 0..1 */)[]; +----- +// contains: "body" +#import "lib.typ": * +#current-heading(level: /* range 0..1 */)[]; +----- +// contains: false, true +#import "lib.typ": * +#current-heading(hierachical: /* range 0..1 */)[]; +----- +// contains: false, true +#import "lib.typ": * +#current-heading(depth: /* range 0..1 */)[]; diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-current-heading.typ b/crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-current-heading.typ new file mode 100644 index 00000000..fe98b3a5 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-current-heading.typ @@ -0,0 +1,43 @@ +// path: lib.typ +// - level (auto, int): The level +#let current-heading(level: auto, hierachical: true, depth: 9999) = { + let current-page = here().page() + if not hierachical and level != auto { + let headings = query(heading).filter(h => ( + h.location().page() <= current-page and h.level <= depth and h.level == level + )) + return headings.at(-1, default: none) + } + let headings = query(heading).filter(h => h.location().page() <= current-page and h.level <= depth) + if headings == () { + return + } + if level == auto { + return headings.last() + } + let current-level = headings.last().level + let current-heading = headings.pop() + while headings.len() > 0 and level < current-level { + current-level = headings.last().level + current-heading = headings.pop() + } + if level == current-level { + return current-heading + } +} +----- +// contains: level, hierachical, depth +#import "lib.typ": * +#current-heading(/* range 0..1 */)[]; +----- +// contains: "body" +#import "lib.typ": * +#current-heading(level: /* range 0..1 */)[]; +----- +// contains: false, true +#import "lib.typ": * +#current-heading(hierachical: /* range 0..1 */)[]; +----- +// contains: 9999, 1 +#import "lib.typ": * +#current-heading(depth: /* range 0..1 */)[]; diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-fit-to-height.typ b/crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-fit-to-height.typ new file mode 100644 index 00000000..871b84f4 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-fit-to-height.typ @@ -0,0 +1,31 @@ +// path: lib.typ +// - level (auto, ): The level +#let fit-to-height( + width: none, + prescale-width: none, + grow: true, + shrink: true, + height, + body, +) = { + [ + #show before-label: none + #show after-label: none + #v(1em) + hidden#before-label + #v(height) + hidden#after-label + ] +} +----- +// contains: 1 +#import "lib.typ": * +#fit-to-height(width: /* range 0..1 */)[]; +----- +// contains: 1 +#import "lib.typ": * +#fit-to-height(prescale-width: /* range 0..1 */)[]; +----- +// contains: 1 +#import "lib.typ": * +#fit-to-height(height: /* range 0..1 */)[]; diff --git a/crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-reconstruct.typ b/crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-reconstruct.typ new file mode 100644 index 00000000..abc90985 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion-pkgs/touying-utils-reconstruct.typ @@ -0,0 +1,18 @@ +// path: lib.typ +#let reconstruct(body-name: "body", labeled: true, named: false, it, ..new-body) = { } +----- +// contains: body-name, labeled, named, it, new-body +#import "lib.typ": * +#reconstruct(/* range 0..1 */)[]; +----- +// contains: "body" +#import "lib.typ": * +#reconstruct(body-name: /* range 0..1 */)[]; +----- +// contains: false, true +#import "lib.typ": * +#reconstruct(labeled: /* range 0..1 */)[]; +----- +// contains: false, true +#import "lib.typ": * +#reconstruct(named: /* range 0..1 */)[]; diff --git a/crates/tinymist-query/src/tests.rs b/crates/tinymist-query/src/tests.rs index 66797b57..ebfbaa3c 100644 --- a/crates/tinymist-query/src/tests.rs +++ b/crates/tinymist-query/src/tests.rs @@ -142,9 +142,6 @@ pub fn run_with_sources(source: &str, f: impl FnOnce(&mut LspUniverse, PathBu .unwrap(); let sources = source.split("-----"); - let pw = root.join(Path::new("/main.typ")); - world.map_shadow(&pw, Bytes::from_static(b"")).unwrap(); - let mut last_pw = None; for (i, source) in sources.enumerate() { // find prelude