feat: leave typst-preview as optional dependencies (#49)

* feat: leave typst-preview as optional dependencies

* build: configure cargo.toml correctly
This commit is contained in:
Myriad-Dreamin 2024-03-16 11:09:04 +08:00 committed by GitHub
parent 222681ca97
commit f4fd0fc276
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 186 additions and 147 deletions

59
Cargo.lock generated
View file

@ -567,39 +567,18 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "comemo"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf5705468fa80602ee6a5f9318306e6c428bffd53e43209a78bc05e6e667c6f4"
dependencies = [
"comemo-macros 0.3.1",
"siphasher 1.0.0",
]
[[package]]
name = "comemo"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df6916408a724339aa77b18214233355f3eb04c42eb895e5f8909215bd8a7a91"
dependencies = [
"comemo-macros 0.4.0",
"comemo-macros",
"once_cell",
"parking_lot",
"siphasher 1.0.0",
]
[[package]]
name = "comemo-macros"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54af6ac68ada2d161fa9cc1ab52676228e340866d094d6542107e74b82acc095"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
]
[[package]]
name = "comemo-macros"
version = "0.4.0"
@ -2698,7 +2677,7 @@ source = "git+https://github.com/Myriad-Dreamin/typst.ts?rev=2ba02c5ff3e2ab73584
dependencies = [
"base64 0.22.0",
"bitvec",
"comemo 0.4.0",
"comemo",
"dashmap",
"ecow",
"fxhash",
@ -3609,7 +3588,7 @@ dependencies = [
"clap_complete_fig",
"clap_mangen",
"codespan-reporting",
"comemo 0.4.0",
"comemo",
"crossbeam-channel",
"env_logger",
"futures",
@ -3626,7 +3605,7 @@ dependencies = [
"tokio",
"tokio-util",
"typst",
"typst-assets",
"typst-assets 0.10.0",
"typst-pdf",
"typst-preview",
"typst-ts-compiler",
@ -3639,7 +3618,7 @@ name = "tinymist-query"
version = "0.10.2"
dependencies = [
"anyhow",
"comemo 0.4.0",
"comemo",
"ena",
"fxhash",
"indexmap 2.2.5",
@ -3898,7 +3877,7 @@ dependencies = [
"bitflags 2.4.2",
"chinese-number",
"ciborium",
"comemo 0.4.0",
"comemo",
"csv",
"ecow",
"fontdb",
@ -3938,7 +3917,7 @@ dependencies = [
"ttf-parser",
"two-face",
"typed-arena",
"typst-assets",
"typst-assets 0.10.0",
"typst-macros",
"typst-syntax",
"typst-timing",
@ -3955,12 +3934,17 @@ name = "typst-assets"
version = "0.10.0"
source = "git+https://github.com/typst/typst-assets?rev=4d1211a#4d1211ab5ba8a02992a7362000e6dd422d44dd68"
[[package]]
name = "typst-assets"
version = "0.11.0-rc1"
source = "git+https://github.com/typst/typst-assets?tag=v0.11.0-rc1#0ef66188759fc7035be57d9608ccb1ecfd3ef796"
[[package]]
name = "typst-ide"
version = "0.10.0"
source = "git+https://github.com/Myriad-Dreamin/typst.git?branch=tinymist-v0.11.0#e1daef5ab881af01bd86f2dd9700dd759c017387"
dependencies = [
"comemo 0.4.0",
"comemo",
"ecow",
"if_chain",
"log",
@ -3987,7 +3971,7 @@ source = "git+https://github.com/Myriad-Dreamin/typst.git?branch=tinymist-v0.11.
dependencies = [
"base64 0.22.0",
"bytemuck",
"comemo 0.4.0",
"comemo",
"ecow",
"image",
"miniz_oxide",
@ -3997,7 +3981,7 @@ dependencies = [
"svg2pdf",
"ttf-parser",
"typst",
"typst-assets",
"typst-assets 0.10.0",
"typst-macros",
"typst-timing",
"unicode-properties",
@ -4007,14 +3991,14 @@ dependencies = [
[[package]]
name = "typst-preview"
version = "0.10.8"
version = "0.10.10"
dependencies = [
"anyhow",
"await-tree",
"clap",
"clap_complete",
"clap_mangen",
"comemo 0.3.1",
"comemo",
"elsa",
"env_logger",
"futures",
@ -4031,6 +4015,7 @@ dependencies = [
"tokio",
"tokio-tungstenite",
"typst",
"typst-assets 0.11.0-rc1",
"typst-ts-compiler",
"typst-ts-core",
"typst-ts-svg-exporter",
@ -4042,7 +4027,7 @@ name = "typst-syntax"
version = "0.10.0"
source = "git+https://github.com/Myriad-Dreamin/typst.git?branch=tinymist-v0.11.0#e1daef5ab881af01bd86f2dd9700dd759c017387"
dependencies = [
"comemo 0.4.0",
"comemo",
"ecow",
"once_cell",
"serde",
@ -4073,7 +4058,7 @@ dependencies = [
"base64 0.22.0",
"chrono",
"codespan-reporting",
"comemo 0.4.0",
"comemo",
"dirs",
"dissimilar",
"flate2",
@ -4111,7 +4096,7 @@ dependencies = [
"base64-serde",
"bitvec",
"byteorder",
"comemo 0.4.0",
"comemo",
"crossbeam-queue",
"dashmap",
"ecow",
@ -4145,7 +4130,7 @@ version = "0.4.2-rc8"
source = "git+https://github.com/Myriad-Dreamin/typst.ts?rev=2ba02c5ff3e2ab735849d4e96b331bec14c24a00#2ba02c5ff3e2ab735849d4e96b331bec14c24a00"
dependencies = [
"base64 0.22.0",
"comemo 0.4.0",
"comemo",
"log",
"once_cell",
"rayon",

View file

@ -11,7 +11,7 @@ rust-version = "1.74"
[workspace]
resolver = "2"
members = ["crates/*", "external/typst-preview"]
members = ["crates/*"]
[workspace.dependencies]
@ -39,7 +39,7 @@ typst-pdf = "0.10.0"
typst-assets = { git = "https://github.com/typst/typst-assets", rev = "4d1211a" }
typst-ts-core = { version = "0.4.2-rc7" }
typst-ts-compiler = { version = "0.4.2-rc7" }
typst-preview = { path = "external/typst-preview" }
typst-preview = { git = "https://github.com/Enter-tainer/typst-preview", rev = "b7db246d8a61a2f1caf9d3a6aa6b74ac68c3027c" }
lsp-server = "0.7.3"
lsp-types = { version = "=0.95.0", features = ["proposed"] }
@ -93,6 +93,8 @@ missing_safety_doc = "warn"
undocumented_unsafe_blocks = "warn"
[patch.crates-io]
typst = { git = "https://github.com/Myriad-Dreamin/typst.git", branch = "tinymist-v0.11.0" }
typst-ide = { git = "https://github.com/Myriad-Dreamin/typst.git", branch = "tinymist-v0.11.0" }
typst-pdf = { git = "https://github.com/Myriad-Dreamin/typst.git", branch = "tinymist-v0.11.0" }
@ -110,3 +112,7 @@ typst-ts-compiler = { git = "https://github.com/Myriad-Dreamin/typst.ts", rev =
# typst-ts-svg-exporter = { path = "../typst.ts/exporter/svg" }
# typst-ts-core = { path = "../typst.ts/core" }
# typst-ts-compiler = { path = "../typst.ts/compiler" }
# https://github.com/rust-lang/cargo/issues/8690
[patch."https://github.com/Enter-tainer/typst-preview"]
typst-preview = { path = "external/typst-preview" }

View file

@ -46,15 +46,16 @@ typst-ts-core = { version = "0.4.2-rc6", default-features = false, features = [
] }
codespan-reporting = "0.11"
typst-ts-compiler.workspace = true
typst-preview.workspace = true
typst-preview = { workspace = true, optional = true }
lsp-server.workspace = true
crossbeam-channel.workspace = true
lsp-types.workspace = true
[features]
default = ["cli"]
default = ["cli", "preview"]
cli = ["clap"]
preview = ["typst-preview"]
[build-dependencies]
anyhow.workspace = true

View file

@ -3,7 +3,7 @@
use core::fmt;
use std::{
path::{Path, PathBuf},
sync::{Arc, Mutex as SyncMutex},
sync::Arc,
};
use log::{debug, error, info, trace, warn};
@ -17,14 +17,11 @@ use tinymist_query::{
use tokio::sync::{broadcast, mpsc, oneshot, watch};
use typst::{
diag::{SourceDiagnostic, SourceResult},
layout::Position,
syntax::{Span, VirtualPath},
syntax::VirtualPath,
util::Deferred,
};
use typst_preview::{
CompilationHandle, CompilationHandleImpl, CompileHost, CompileStatus, DocToSrcJumpInfo,
EditorServer, Location, MemoryFiles, MemoryFilesShort, SourceFileServer,
};
#[cfg(feature = "preview")]
use typst_preview::{CompilationHandle, CompilationHandleImpl, CompileStatus};
use typst_ts_compiler::{
service::{
CompileDriver as CompileDriverInner, CompileExporter, CompileMiddleware, Compiler,
@ -34,8 +31,8 @@ use typst_ts_compiler::{
TypstSystemWorld,
};
use typst_ts_core::{
config::CompileOpts, debug_loc::SourceSpanOffset, error::prelude::*, typst::prelude::EcoVec,
Error, ImmutPath, TypstDocument, TypstWorld,
config::CompileOpts, error::prelude::*, typst::prelude::EcoVec, Error, ImmutPath,
TypstDocument, TypstWorld,
};
use super::compile::CompileClient as TsCompileClient;
@ -46,6 +43,21 @@ use crate::{
utils,
};
#[cfg(not(feature = "preview"))]
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(tag = "kind", content = "data")]
pub enum CompileStatus {
Compiling,
CompileSuccess,
CompileError,
}
#[cfg(not(feature = "preview"))]
pub trait CompilationHandle: Send + 'static {
fn status(&self, status: CompileStatus);
fn notify_compile(&self, res: Result<Arc<TypstDocument>, CompileStatus>);
}
type CompileService<H> = CompileActorInner<Reporter<CompileExporter<CompileDriver>, H>>;
type CompileClient<H> = TsCompileClient<CompileService<H>>;
@ -92,7 +104,8 @@ pub fn create_server(
let inner = Deferred::new({
let current_runtime = tokio::runtime::Handle::current();
let handler = CompileHandler {
inner: Arc::new(SyncMutex::new(None)),
#[cfg(feature = "preview")]
inner: Arc::new(Mutex::new(None)),
};
let diag_group = diag_group.clone();
@ -213,21 +226,28 @@ macro_rules! query_world2 {
#[derive(Clone)]
pub struct CompileHandler {
inner: Arc<SyncMutex<Option<CompilationHandleImpl>>>,
#[cfg(feature = "preview")]
inner: Arc<Mutex<Option<CompilationHandleImpl>>>,
}
impl CompilationHandle for CompileHandler {
fn status(&self, status: CompileStatus) {
let inner = self.inner.lock().unwrap();
if let Some(inner) = inner.as_ref() {
inner.status(status);
fn status(&self, _status: CompileStatus) {
#[cfg(feature = "preview")]
{
let inner = self.inner.lock();
if let Some(inner) = inner.as_ref() {
inner.status(_status);
}
}
}
fn notify_compile(&self, result: Result<Arc<TypstDocument>, CompileStatus>) {
let inner = self.inner.lock().unwrap();
if let Some(inner) = inner.as_ref() {
inner.notify_compile(result.clone());
fn notify_compile(&self, _result: Result<Arc<TypstDocument>, CompileStatus>) {
#[cfg(feature = "preview")]
{
let inner = self.inner.lock();
if let Some(inner) = inner.as_ref() {
inner.notify_compile(_result.clone());
}
}
}
}
@ -296,11 +316,13 @@ pub struct Reporter<C, H> {
position_encoding: PositionEncoding,
diag_tx: DiagnosticsSender,
inner: C,
#[allow(unused)]
cb: H,
}
impl<C: Compiler<World = TypstSystemWorld>, H: CompilationHandle> CompileMiddleware
for Reporter<C, H>
impl<C: Compiler<World = TypstSystemWorld>, H> CompileMiddleware for Reporter<C, H>
where
H: CompilationHandle,
{
type Compiler = C;
@ -316,15 +338,18 @@ impl<C: Compiler<World = TypstSystemWorld>, H: CompilationHandle> CompileMiddlew
&mut self,
env: &mut typst_ts_compiler::service::CompileEnv,
) -> SourceResult<Arc<TypstDocument>> {
#[cfg(feature = "preview")]
self.cb.status(CompileStatus::Compiling);
match self.inner_mut().compile(env) {
Ok(doc) => {
#[cfg(feature = "preview")]
self.cb.notify_compile(Ok(doc.clone()));
self.notify_diagnostics(EcoVec::new());
Ok(doc)
}
Err(err) => {
#[cfg(feature = "preview")]
self.cb.notify_compile(Err(CompileStatus::CompileError));
self.notify_diagnostics(err);
@ -587,91 +612,6 @@ impl CompileActor {
}
}
impl SourceFileServer for CompileActor {
async fn resolve_source_span(
&mut self,
loc: Location,
) -> Result<Option<SourceSpanOffset>, Error> {
let Location::Src(src_loc) = loc;
self.inner().resolve_src_location(src_loc).await
}
async fn resolve_document_position(
&mut self,
loc: Location,
) -> Result<Option<Position>, Error> {
let Location::Src(src_loc) = loc;
let path = Path::new(&src_loc.filepath).to_owned();
let line = src_loc.pos.line;
let column = src_loc.pos.column;
self.inner()
.resolve_src_to_doc_jump(path, line, column)
.await
}
async fn resolve_source_location(
&mut self,
s: Span,
offset: Option<usize>,
) -> Result<Option<DocToSrcJumpInfo>, Error> {
Ok(self
.inner()
.resolve_span_and_offset(s, offset)
.await
.map_err(|err| {
error!("TypstActor: failed to resolve span and offset: {:#}", err);
})
.ok()
.flatten()
.map(|e| DocToSrcJumpInfo {
filepath: e.filepath,
start: e.start,
end: e.end,
}))
}
}
impl EditorServer for CompileActor {
async fn update_memory_files(
&mut self,
files: MemoryFiles,
reset_shadow: bool,
) -> Result<(), Error> {
// todo: is it safe to believe that the path is normalized?
let now = std::time::SystemTime::now();
let files = FileChangeSet::new_inserts(
files
.files
.into_iter()
.map(|(path, content)| {
let content = content.as_bytes().into();
// todo: cloning PathBuf -> Arc<Path>
(path.into(), Ok((now, content)).into())
})
.collect(),
);
self.inner().add_memory_changes(if reset_shadow {
MemoryEvent::Sync(files)
} else {
MemoryEvent::Update(files)
});
Ok(())
}
async fn remove_shadow_files(&mut self, files: MemoryFilesShort) -> Result<(), Error> {
// todo: is it safe to believe that the path is normalized?
let files = FileChangeSet::new_removes(files.files.into_iter().map(From::from).collect());
self.inner().add_memory_changes(MemoryEvent::Update(files));
Ok(())
}
}
impl CompileHost for CompileActor {}
impl CompileActor {
pub fn query(&self, query: CompilerQueryRequest) -> anyhow::Result<CompilerQueryResponse> {
use CompilerQueryRequest::*;
@ -760,3 +700,110 @@ impl CompileActor {
Ok(fut?)
}
}
#[cfg(feature = "preview")]
mod preview_exts {
use std::path::Path;
use typst::layout::Position;
use typst::syntax::Span;
use typst_preview::{
CompileHost, DocToSrcJumpInfo, EditorServer, Location, MemoryFiles, MemoryFilesShort,
SourceFileServer,
};
use typst_ts_compiler::vfs::notify::FileChangeSet;
use typst_ts_compiler::vfs::notify::MemoryEvent;
use typst_ts_core::debug_loc::SourceSpanOffset;
use typst_ts_core::Error;
use super::CompileActor;
#[cfg(feature = "preview")]
impl SourceFileServer for CompileActor {
async fn resolve_source_span(
&mut self,
loc: Location,
) -> Result<Option<SourceSpanOffset>, Error> {
let Location::Src(src_loc) = loc;
self.inner().resolve_src_location(src_loc).await
}
async fn resolve_document_position(
&mut self,
loc: Location,
) -> Result<Option<Position>, Error> {
let Location::Src(src_loc) = loc;
let path = Path::new(&src_loc.filepath).to_owned();
let line = src_loc.pos.line;
let column = src_loc.pos.column;
self.inner()
.resolve_src_to_doc_jump(path, line, column)
.await
}
async fn resolve_source_location(
&mut self,
s: Span,
offset: Option<usize>,
) -> Result<Option<DocToSrcJumpInfo>, Error> {
Ok(self
.inner()
.resolve_span_and_offset(s, offset)
.await
.map_err(|err| {
log::error!("TypstActor: failed to resolve span and offset: {:#}", err);
})
.ok()
.flatten()
.map(|e| DocToSrcJumpInfo {
filepath: e.filepath,
start: e.start,
end: e.end,
}))
}
}
#[cfg(feature = "preview")]
impl EditorServer for CompileActor {
async fn update_memory_files(
&mut self,
files: MemoryFiles,
reset_shadow: bool,
) -> Result<(), Error> {
// todo: is it safe to believe that the path is normalized?
let now = std::time::SystemTime::now();
let files = FileChangeSet::new_inserts(
files
.files
.into_iter()
.map(|(path, content)| {
let content = content.as_bytes().into();
// todo: cloning PathBuf -> Arc<Path>
(path.into(), Ok((now, content)).into())
})
.collect(),
);
self.inner().add_memory_changes(if reset_shadow {
MemoryEvent::Sync(files)
} else {
MemoryEvent::Update(files)
});
Ok(())
}
async fn remove_shadow_files(&mut self, files: MemoryFilesShort) -> Result<(), Error> {
// todo: is it safe to believe that the path is normalized?
let files =
FileChangeSet::new_removes(files.files.into_iter().map(From::from).collect());
self.inner().add_memory_changes(MemoryEvent::Update(files));
Ok(())
}
}
#[cfg(feature = "preview")]
impl CompileHost for CompileActor {}
}