diff --git a/Cargo.lock b/Cargo.lock index 75fbab62..1fd1bf78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4038,6 +4038,7 @@ dependencies = [ "triomphe", "ttf-parser", "typst", + "typst-assets", "typst-ts-compiler", "typst-ts-core", "unscanny", diff --git a/crates/tinymist-query/Cargo.toml b/crates/tinymist-query/Cargo.toml index 92ca584d..815dc22c 100644 --- a/crates/tinymist-query/Cargo.toml +++ b/crates/tinymist-query/Cargo.toml @@ -57,6 +57,7 @@ once_cell.workspace = true insta.workspace = true serde.workspace = true serde_json.workspace = true +typst-assets = { workspace = true, features = ["fonts"] } typst-ts-core = { workspace = true, default-features = false, features = [ "flat-vector", "vector-bbox", diff --git a/crates/tinymist-query/src/fixtures/completion/modify_string.typ b/crates/tinymist-query/src/fixtures/completion/modify_string.typ new file mode 100644 index 00000000..26dc6e82 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion/modify_string.typ @@ -0,0 +1,3 @@ +// contains: "New Computer Modern" + +#set text(font: ""/* range -2..0 */) \ No newline at end of file diff --git a/crates/tinymist-query/src/fixtures/completion/modify_string_2.typ b/crates/tinymist-query/src/fixtures/completion/modify_string_2.typ new file mode 100644 index 00000000..d8dea383 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion/modify_string_2.typ @@ -0,0 +1,3 @@ +// contains: "New Computer Modern" + +#set text(font: (""/* range -2..0 */)) \ No newline at end of file diff --git a/crates/tinymist-query/src/fixtures/completion/snaps/test@modify_string.typ.snap b/crates/tinymist-query/src/fixtures/completion/snaps/test@modify_string.typ.snap new file mode 100644 index 00000000..b6bcd762 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion/snaps/test@modify_string.typ.snap @@ -0,0 +1,54 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: "Completion on \"\" (52..54)" +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion/modify_string.typ +--- +[ + { + "isIncomplete": false, + "items": [ + { + "kind": 21, + "label": "\"New Computer Modern\"", + "sortText": "003", + "textEdit": { + "newText": "\"New Computer Modern", + "range": { + "end": { + "character": 16, + "line": 2 + }, + "start": { + "character": 16, + "line": 2 + } + } + } + } + ] + }, + { + "isIncomplete": false, + "items": [ + { + "kind": 21, + "label": "\"New Computer Modern\"", + "sortText": "003", + "textEdit": { + "newText": "New Computer Modern", + "range": { + "end": { + "character": 17, + "line": 2 + }, + "start": { + "character": 16, + "line": 2 + } + } + } + } + ] + } +] diff --git a/crates/tinymist-query/src/fixtures/completion/snaps/test@modify_string_2.typ.snap b/crates/tinymist-query/src/fixtures/completion/snaps/test@modify_string_2.typ.snap new file mode 100644 index 00000000..977f62a8 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/completion/snaps/test@modify_string_2.typ.snap @@ -0,0 +1,54 @@ +--- +source: crates/tinymist-query/src/completion.rs +description: "Completion on \"\" (53..55)" +expression: "JsonRepr::new_pure(results)" +input_file: crates/tinymist-query/src/fixtures/completion/modify_string_2.typ +--- +[ + { + "isIncomplete": false, + "items": [ + { + "kind": 21, + "label": "\"New Computer Modern\"", + "sortText": "003", + "textEdit": { + "newText": "\"New Computer Modern", + "range": { + "end": { + "character": 17, + "line": 2 + }, + "start": { + "character": 17, + "line": 2 + } + } + } + } + ] + }, + { + "isIncomplete": false, + "items": [ + { + "kind": 21, + "label": "\"New Computer Modern\"", + "sortText": "003", + "textEdit": { + "newText": "New Computer Modern", + "range": { + "end": { + "character": 18, + "line": 2 + }, + "start": { + "character": 18, + "line": 2 + } + } + } + } + ] + } +] diff --git a/crates/tinymist-query/src/tests.rs b/crates/tinymist-query/src/tests.rs index 98c3ed59..ac9bd11f 100644 --- a/crates/tinymist-query/src/tests.rs +++ b/crates/tinymist-query/src/tests.rs @@ -1,5 +1,6 @@ use core::fmt; use std::{ + borrow::Cow, collections::{HashMap, HashSet}, ops::Range, path::{Path, PathBuf}, @@ -105,6 +106,8 @@ pub fn run_with_sources( }; let mut world = TypstSystemUniverse::new(CompileOpts { entry: EntryOpts::new_rooted(root.as_path().into(), None), + with_embedded_fonts: typst_assets::fonts().map(Cow::Borrowed).collect(), + no_system_fonts: true, ..Default::default() }) .unwrap(); diff --git a/crates/tinymist-query/src/upstream/complete.rs b/crates/tinymist-query/src/upstream/complete.rs index 27a822fc..27d56295 100644 --- a/crates/tinymist-query/src/upstream/complete.rs +++ b/crates/tinymist-query/src/upstream/complete.rs @@ -1190,9 +1190,21 @@ impl<'a, 'w> CompletionContext<'a, 'w> { } } else if at { apply = Some(eco_format!("at(\"{label}\")")); - } else if label.starts_with('"') && self.after.starts_with('"') { - if let Some(trimmed) = label.strip_suffix('"') { - apply = Some(trimmed.into()); + } else { + let apply_label = &mut label.as_str(); + if apply_label.ends_with('"') && self.after.starts_with('"') { + if let Some(trimmed) = apply_label.strip_suffix('"') { + *apply_label = trimmed; + } + } + if apply_label.starts_with('"') && self.before.ends_with('"') { + if let Some(trimmed) = apply_label.strip_prefix('"') { + *apply_label = trimmed; + } + } + + if apply_label.len() != label.len() { + apply = Some((*apply_label).into()); } }