From 0420558fd479fee25be4420afa8dca92bd4f0130 Mon Sep 17 00:00:00 2001 From: Myriad-Dreamin Date: Sun, 16 Nov 2025 06:28:11 +0800 Subject: [PATCH] feat: disable typst::compile in syntax only mode --- Cargo.lock | 3 +++ crates/tinymist-cli/src/cmd/test.rs | 4 +-- crates/tinymist-dap/Cargo.toml | 1 + crates/tinymist-dap/src/lib.rs | 2 +- crates/tinymist-debug/Cargo.toml | 1 + crates/tinymist-debug/src/lib.rs | 2 +- crates/tinymist-query/src/code_action.rs | 2 +- crates/tinymist-query/src/tests.rs | 2 +- crates/tinymist-world/Cargo.toml | 1 + crates/tinymist-world/README.md | 4 +-- crates/tinymist-world/src/compute.rs | 2 +- crates/tinymist-world/src/system.rs | 2 +- crates/tinymist/src/task/user_action.rs | 2 +- crates/typlite/src/lib.rs | 1 + crates/typlite/src/parser/media.rs | 1 + crates/typst-shim/src/lib.rs | 3 +++ crates/typst-shim/src/syntax_only.rs | 34 ++++++++++++++++++++++++ docs/tinymist/feature/testing.typ | 2 +- locales/tinymist-vscode.toml | 2 +- 19 files changed, 58 insertions(+), 13 deletions(-) create mode 100644 crates/typst-shim/src/syntax_only.rs diff --git a/Cargo.lock b/Cargo.lock index 4ce0e17e..b3cc72c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4562,6 +4562,7 @@ dependencies = [ "tinymist-world", "typst", "typst-library", + "typst-shim", ] [[package]] @@ -4580,6 +4581,7 @@ dependencies = [ "tinymist-world", "typst", "typst-library", + "typst-shim", ] [[package]] @@ -4903,6 +4905,7 @@ dependencies = [ "ttf-parser", "typst", "typst-assets", + "typst-shim", "wasm-bindgen", "web-sys", ] diff --git a/crates/tinymist-cli/src/cmd/test.rs b/crates/tinymist-cli/src/cmd/test.rs index 569390d3..689e9f13 100644 --- a/crates/tinymist-cli/src/cmd/test.rs +++ b/crates/tinymist-cli/src/cmd/test.rs @@ -219,7 +219,7 @@ pub async fn test_main(args: TestArgs) -> Result<()> { } fn test_once(world: &LspWorld, ctx: &TestContext) -> Result { - let doc = typst::compile::(&world).output?; + let doc = typst_shim::compile_opt::(&world).output?; let mut snap = CompileSnapshot::from_world(world.clone()); snap.success_doc = Some(TypstDocument::Paged(Arc::new(doc))); @@ -449,7 +449,7 @@ impl<'a> TestRunner<'a> { } fn build_example(&self, world: &dyn World) -> (bool, Option) { - let result = typst::compile::(world); + let result = typst_shim::compile_opt::(world); if !result.warnings.is_empty() { self.diagnostics.lock().push(result.warnings); } diff --git a/crates/tinymist-dap/Cargo.toml b/crates/tinymist-dap/Cargo.toml index a45b6d5f..8d132ba5 100644 --- a/crates/tinymist-dap/Cargo.toml +++ b/crates/tinymist-dap/Cargo.toml @@ -13,6 +13,7 @@ rust-version.workspace = true [dependencies] typst-library.workspace = true +typst-shim.workspace = true typst.workspace = true tinymist-std.workspace = true tinymist-analysis.workspace = true diff --git a/crates/tinymist-dap/src/lib.rs b/crates/tinymist-dap/src/lib.rs index 54e60fd5..8f1f26ac 100644 --- a/crates/tinymist-dap/src/lib.rs +++ b/crates/tinymist-dap/src/lib.rs @@ -79,7 +79,7 @@ pub fn start_session( adaptor.before_compile(); step_global(BreakpointKind::BeforeCompile, &world); - let result = typst::compile::(&world); + let result = typst_shim::compile_opt::(&world); adaptor.after_compile(result); step_global(BreakpointKind::AfterCompile, &world); diff --git a/crates/tinymist-debug/Cargo.toml b/crates/tinymist-debug/Cargo.toml index ca9ce202..53be2fe9 100644 --- a/crates/tinymist-debug/Cargo.toml +++ b/crates/tinymist-debug/Cargo.toml @@ -13,6 +13,7 @@ rust-version.workspace = true [dependencies] typst-library.workspace = true +typst-shim.workspace = true typst.workspace = true tinymist-std.workspace = true tinymist-analysis.workspace = true diff --git a/crates/tinymist-debug/src/lib.rs b/crates/tinymist-debug/src/lib.rs index 15615f65..c4e68dfb 100644 --- a/crates/tinymist-debug/src/lib.rs +++ b/crates/tinymist-debug/src/lib.rs @@ -30,7 +30,7 @@ pub fn collect_coverage( base: &CompilerWorld, ) -> Result { let (cov, result) = with_cov(base, |instr| { - if let Err(e) = typst::compile::(&instr).output { + if let Err(e) = typst_shim::compile_opt::(&instr).output { print_diagnostics(instr, e.iter(), tinymist_world::DiagnosticFormat::Human) .context_ut("failed to print diagnostics")?; bail!(""); diff --git a/crates/tinymist-query/src/code_action.rs b/crates/tinymist-query/src/code_action.rs index 5e9f8e71..08d1d9b7 100644 --- a/crates/tinymist-query/src/code_action.rs +++ b/crates/tinymist-query/src/code_action.rs @@ -131,7 +131,7 @@ mod tests { let Warned { output, warnings: compiler_warnings, - } = typst::compile::(ctx.world()); + } = typst_shim::compile_opt::(ctx.world()); let compiler_errors = output.err().unwrap_or_default(); let compiler_diags = compiler_warnings.iter().chain(compiler_errors.iter()); diff --git a/crates/tinymist-query/src/tests.rs b/crates/tinymist-query/src/tests.rs index f57fbe92..b6cb45c6 100644 --- a/crates/tinymist-query/src/tests.rs +++ b/crates/tinymist-query/src/tests.rs @@ -147,7 +147,7 @@ pub fn compile_doc_for_test( let mut snap = LspCompileSnapshot::from_world(world.into_owned()); snap.world.set_is_compiling(true); - let doc = typst::compile(&snap.world).output.unwrap(); + let doc = typst_shim::compile_opt(&snap.world).output.unwrap(); snap.success_doc = Some(TypstDocument::Paged(Arc::new(doc))); WorldComputeGraph::new(snap) } diff --git a/crates/tinymist-world/Cargo.toml b/crates/tinymist-world/Cargo.toml index b75e6605..65925ab8 100644 --- a/crates/tinymist-world/Cargo.toml +++ b/crates/tinymist-world/Cargo.toml @@ -44,6 +44,7 @@ tar.workspace = true tinymist-package.workspace = true tinymist-std.workspace = true tinymist-vfs.workspace = true +typst-shim.workspace = true typst.workspace = true typst-assets.workspace = true ttf-parser.workspace = true diff --git a/crates/tinymist-world/README.md b/crates/tinymist-world/README.md index 4dd092e3..cc5ebaef 100644 --- a/crates/tinymist-world/README.md +++ b/crates/tinymist-world/README.md @@ -16,9 +16,9 @@ let universe = args ```rust let world = verse.snapshot(); // in current thread -let doc = typst::compile(&world)?; +let doc = typst_shim::compile_opt(&world)?; // the snapshot is Send + Sync std::thread::spawn(move || { - let doc = typst::compile(&world)?; + let doc = typst_shim::compile_opt(&world)?; }); ``` diff --git a/crates/tinymist-world/src/compute.rs b/crates/tinymist-world/src/compute.rs index 6b0643ee..439f29cc 100644 --- a/crates/tinymist-world/src/compute.rs +++ b/crates/tinymist-world/src/compute.rs @@ -303,7 +303,7 @@ impl CompilationTask { }; world.to_mut().set_is_compiling(true); - let compiled = ::typst::compile::(world.as_ref()); + let compiled = ::typst_shim::compile_opt::(world.as_ref()); world.to_mut().set_is_compiling(false); let exclude_html_warnings = if !is_html_compilation { diff --git a/crates/tinymist-world/src/system.rs b/crates/tinymist-world/src/system.rs index 6b259413..a0764507 100644 --- a/crates/tinymist-world/src/system.rs +++ b/crates/tinymist-world/src/system.rs @@ -136,7 +136,7 @@ mod tests { .expect("failed to resolve system universe"); let world = verse.snapshot(); - let _res = typst::compile::(&world); + let _res = typst_shim::compile_opt::(&world); } static FONT_COMPUTED: AtomicBool = AtomicBool::new(false); diff --git a/crates/tinymist/src/task/user_action.rs b/crates/tinymist/src/task/user_action.rs index 35ca4b6d..6e4c08ca 100644 --- a/crates/tinymist/src/task/user_action.rs +++ b/crates/tinymist/src/task/user_action.rs @@ -238,7 +238,7 @@ async fn trace_main( req_id: RequestId, ) -> ! { typst_timing::enable(); - let res = typst::compile::(g.world()); + let res = typst_shim::compile_opt::(g.world()); let diags = match &res.output { Ok(_res) => res.warnings, Err(errors) => errors.clone(), diff --git a/crates/typlite/src/lib.rs b/crates/typlite/src/lib.rs index 7b7ce802..9bd33caa 100644 --- a/crates/typlite/src/lib.rs +++ b/crates/typlite/src/lib.rs @@ -436,6 +436,7 @@ impl Typlite { format: Format, world: Arc, ) -> tinymist_std::Result { + // this is not affected by syntax-only mode (typst_shim::compile_opt) let compiled = typst::compile(&world); let collector = WarningCollector::default(); collector.extend( diff --git a/crates/typlite/src/parser/media.rs b/crates/typlite/src/parser/media.rs index 2dc56676..8cbf2b9a 100644 --- a/crates/typlite/src/parser/media.rs +++ b/crates/typlite/src/parser/media.rs @@ -278,6 +278,7 @@ impl HtmlToAstParser { ) .unwrap(); + // this is not affected by syntax-only mode (typst_shim::compile_opt) let compiled = typst::compile(&world); self.warnings.extend(compiled.warnings.iter().cloned()); let doc = match compiled.output { diff --git a/crates/typst-shim/src/lib.rs b/crates/typst-shim/src/lib.rs index 841d50b1..8c34b96a 100644 --- a/crates/typst-shim/src/lib.rs +++ b/crates/typst-shim/src/lib.rs @@ -1,5 +1,8 @@ //! # typst-shim +mod syntax_only; +pub use syntax_only::*; + pub use cfg_if::cfg_if; cfg_if! { diff --git a/crates/typst-shim/src/syntax_only.rs b/crates/typst-shim/src/syntax_only.rs new file mode 100644 index 00000000..74491760 --- /dev/null +++ b/crates/typst-shim/src/syntax_only.rs @@ -0,0 +1,34 @@ +use std::sync::atomic::{AtomicBool, Ordering}; +use typst::{ + Document, World, + diag::{SourceDiagnostic, SourceResult, Warned}, + ecow::eco_vec, +}; +use typst_syntax::Span; + +/// Global flag indicating whether syntax-only mode is enabled. +pub static SYNTAX_ONLY: AtomicBool = AtomicBool::new(false); + +/// Check if syntax-only mode is enabled. +pub fn is_syntax_only() -> bool { + SYNTAX_ONLY.load(Ordering::Relaxed) +} + +/// Compile the document if syntax-only mode is disabled; otherwise, return an +/// error. +pub fn compile_opt(world: &dyn World) -> Warned> +where + D: Document, +{ + if is_syntax_only() { + Warned { + output: Err(eco_vec![SourceDiagnostic::error( + Span::detached(), + "Compilation is disabled in syntax-only mode.", + )]), + warnings: Default::default(), + } + } else { + typst::compile::(world) + } +} diff --git a/docs/tinymist/feature/testing.typ b/docs/tinymist/feature/testing.typ index 735cbcea..ea358025 100644 --- a/docs/tinymist/feature/testing.typ +++ b/docs/tinymist/feature/testing.typ @@ -14,7 +14,7 @@ Given a file, tinymist will try to discover tests related to the file. - All dependent files in the same workspace will be checked. - For example, if file `a.typ` contains `import "b.typ"` or `include "b.typ"`, tinymist will check `b.typ` for tests as well. - For each file including the entry file itself, tinymist will check the file for tests. - - If a file is named `example-*.typ`, it is considered an *example document* and will be compiled using `typst::compile`. + - If a file is named `example-*.typ`, it is considered an *example document* and will be compiled using `typst_shim::compile_opt`. - Both png export and html export may be called. - For now, png export is always called for each example file. - If the label `` can be found in the example file, html export will be called. diff --git a/locales/tinymist-vscode.toml b/locales/tinymist-vscode.toml index 88171e49..6278f403 100644 --- a/locales/tinymist-vscode.toml +++ b/locales/tinymist-vscode.toml @@ -1036,7 +1036,7 @@ en = "Configure whether to enable syntax-only mode for the language server. In s zh = "配置是否为语言服务器启用仅语法模式。在仅语法模式下,语言服务器将仅提供语法检查和基本的代码补全,但不会执行完整的文档编译或代码分析。这对于提高低端设备的性能或处理大型文档时非常有用。" [extension.tinymist.config.tinymist.lsp.syntaxOnly.string.enum.auto] -en = "Always enable syntax-only mode. The strategy may be changed in the future, for example, automatically enable syntax-only mode when the system is in power-saving mode." +en = "Always disable syntax-only mode. The strategy may be changed in the future, for example, automatically enable syntax-only mode when the system is in power-saving mode." zh = "始终启用仅语法模式。未来可能会更改策略,例如,当系统处于省电模式时自动启用仅语法模式。" [extension.tinymist.config.tinymist.lsp.syntaxOnly.string.enum.onPowerSaving]