diff --git a/crates/tinymist-project/src/lsp.rs b/crates/tinymist-project/src/lsp.rs index b097ab39..23e15b54 100644 --- a/crates/tinymist-project/src/lsp.rs +++ b/crates/tinymist-project/src/lsp.rs @@ -12,7 +12,8 @@ use tinymist_world::{args::*, WorldComputeGraph}; use tinymist_world::{ CompileSnapshot, CompilerFeat, CompilerUniverse, CompilerWorld, EntryOpts, EntryState, }; -use typst::foundations::{Dict, Str, Value}; +use typst::diag::FileResult; +use typst::foundations::{Bytes, Dict, Str, Value}; use typst::utils::LazyHash; use typst::Features; @@ -30,7 +31,7 @@ impl CompilerFeat for LspCompilerFeat { /// Uses [`FontResolverImpl`] directly. type FontResolver = FontResolverImpl; /// It accesses a physical file system. - type AccessModel = SystemAccessModel; + type AccessModel = DynAccessModel; /// It performs native HTTP requests for fetching package data. type Registry = HttpRegistry; } @@ -77,6 +78,7 @@ impl WorldProvider for CompileOnceArgs { packages, fonts, self.creation_timestamp, + DynAccessModel(Arc::new(SystemAccessModel {})), )) } @@ -170,6 +172,7 @@ impl WorldProvider for (ProjectInput, ImmutPath) { packages, Arc::new(fonts), None, // creation_timestamp - not available in project file context + DynAccessModel(Arc::new(SystemAccessModel {})), )) } @@ -210,6 +213,7 @@ pub struct LspUniverseBuilder; impl LspUniverseBuilder { /// Create [`LspUniverse`] with the given options. /// See [`LspCompilerFeat`] for instantiation details. + #[allow(clippy::too_many_arguments)] pub fn build( entry: EntryState, export_target: ExportTarget, @@ -218,6 +222,7 @@ impl LspUniverseBuilder { package_registry: HttpRegistry, font_resolver: Arc, creation_timestamp: Option, + am: DynAccessModel, ) -> LspUniverse { let package_registry = Arc::new(package_registry); let resolver = Arc::new(RegistryPathMapper::new(package_registry.clone())); @@ -233,7 +238,7 @@ impl LspUniverseBuilder { entry, features, Some(inputs), - Vfs::new(resolver, SystemAccessModel {}), + Vfs::new(resolver, am), package_registry, font_resolver, creation_timestamp, @@ -274,3 +279,37 @@ impl LspUniverseBuilder { ) } } + +/// Access model for LSP universe and worlds. +pub trait LspAccessModel: Send + Sync { + /// Returns the content of a file entry. + fn content(&self, src: &Path) -> FileResult; +} + +impl LspAccessModel for T +where + T: tinymist_world::vfs::PathAccessModel + Send + Sync + 'static, +{ + fn content(&self, src: &Path) -> FileResult { + self.content(src) + } +} + +/// Access model for LSP universe and worlds. +#[derive(Clone)] +pub struct DynAccessModel(pub Arc); + +impl DynAccessModel { + /// Create a new dynamic access model from the given access model. + pub fn new(access_model: Arc) -> Self { + Self(access_model) + } +} + +impl tinymist_world::vfs::PathAccessModel for DynAccessModel { + fn content(&self, src: &Path) -> FileResult { + self.0.content(src) + } + + fn reset(&mut self) {} +} diff --git a/crates/tinymist-tests/src/lib.rs b/crates/tinymist-tests/src/lib.rs index b326b6ad..5726eaef 100644 --- a/crates/tinymist-tests/src/lib.rs +++ b/crates/tinymist-tests/src/lib.rs @@ -6,8 +6,8 @@ use std::{ }; use tinymist_project::{ - base::ShadowApi, font::FontResolverImpl, CompileFontArgs, EntryManager, EntryState, - ExportTarget, LspUniverse, LspUniverseBuilder, + base::ShadowApi, font::FontResolverImpl, vfs::system::SystemAccessModel, CompileFontArgs, + DynAccessModel, EntryManager, EntryState, ExportTarget, LspUniverse, LspUniverseBuilder, }; use typst::{foundations::Bytes, syntax::VirtualPath}; @@ -64,6 +64,7 @@ pub fn run_with_sources(source: &str, f: impl FnOnce(&mut LspUniverse, PathBu LspUniverseBuilder::resolve_package(None, None), FONT_RESOLVER.clone(), None, + DynAccessModel(Arc::new(SystemAccessModel {})), ); let sources = source.split("-----"); diff --git a/crates/tinymist/src/project.rs b/crates/tinymist/src/project.rs index 8cde315d..86110f42 100644 --- a/crates/tinymist/src/project.rs +++ b/crates/tinymist/src/project.rs @@ -19,6 +19,7 @@ #![allow(missing_docs)] +use reflexo_typst::vfs::system::SystemAccessModel; use reflexo_typst::{diag::print_diagnostics, TypstDocument}; use serde::{Deserialize, Serialize}; pub use tinymist_project::*; @@ -200,6 +201,8 @@ impl ServerState { packages, fonts, creation_timestamp, + // todo: impl an access model delegation to vscode's ssh-fs + DynAccessModel(Arc::new(SystemAccessModel {})), ); // todo: unify filesystem watcher