feat: forward const config

This commit is contained in:
Myriad-Dreamin 2024-03-07 16:12:49 +08:00
parent d49085338f
commit 0c7e67ed9a
12 changed files with 125 additions and 211 deletions

View file

@ -28,7 +28,6 @@ itertools = "0.12.0"
lazy_static = "1.4.0" lazy_static = "1.4.0"
env_logger = "0.11.1" env_logger = "0.11.1"
log = "0.4.17" log = "0.4.17"
percent-encoding = "2.3.0"
strum = { version = "0.25.0", features = ["derive"] } strum = { version = "0.25.0", features = ["derive"] }
async-trait = "0.1.73" async-trait = "0.1.73"
parking_lot = "0.12.1" parking_lot = "0.12.1"

View file

@ -4,7 +4,6 @@ use crate::prelude::*;
pub struct CompletionRequest { pub struct CompletionRequest {
pub path: PathBuf, pub path: PathBuf,
pub position: LspPosition, pub position: LspPosition,
pub position_encoding: PositionEncoding,
pub explicit: bool, pub explicit: bool,
} }
@ -12,16 +11,16 @@ pub fn completion(
world: &TypstSystemWorld, world: &TypstSystemWorld,
doc: Option<Arc<TypstDocument>>, doc: Option<Arc<TypstDocument>>,
req: CompletionRequest, req: CompletionRequest,
position_encoding: PositionEncoding,
) -> Option<CompletionResponse> { ) -> Option<CompletionResponse> {
let source = get_suitable_source_in_workspace(world, &req.path).ok()?; let source = get_suitable_source_in_workspace(world, &req.path).ok()?;
let typst_offset = let typst_offset = lsp_to_typst::position_to_offset(req.position, position_encoding, &source);
lsp_to_typst::position_to_offset(req.position, req.position_encoding, &source);
let (typst_start_offset, completions) = let (typst_start_offset, completions) =
typst_ide::autocomplete(world, doc.as_deref(), &source, typst_offset, req.explicit)?; typst_ide::autocomplete(world, doc.as_deref(), &source, typst_offset, req.explicit)?;
let lsp_start_position = let lsp_start_position =
typst_to_lsp::offset_to_position(typst_start_offset, req.position_encoding, &source); typst_to_lsp::offset_to_position(typst_start_offset, position_encoding, &source);
let replace_range = LspRawRange::new(lsp_start_position, req.position); let replace_range = LspRawRange::new(lsp_start_position, req.position);
Some(typst_to_lsp::completions(&completions, replace_range).into()) Some(typst_to_lsp::completions(&completions, replace_range).into())
} }

View file

@ -3,17 +3,17 @@ use crate::prelude::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DocumentSymbolRequest { pub struct DocumentSymbolRequest {
pub path: PathBuf, pub path: PathBuf,
pub position_encoding: PositionEncoding,
} }
pub fn document_symbol( pub fn document_symbol(
world: &TypstSystemWorld, world: &TypstSystemWorld,
req: DocumentSymbolRequest, req: DocumentSymbolRequest,
position_encoding: PositionEncoding,
) -> Option<DocumentSymbolResponse> { ) -> Option<DocumentSymbolResponse> {
let source = get_suitable_source_in_workspace(world, &req.path).ok()?; let source = get_suitable_source_in_workspace(world, &req.path).ok()?;
let uri = Url::from_file_path(req.path).unwrap(); let uri = Url::from_file_path(req.path).unwrap();
let symbols = get_document_symbols(source, uri, req.position_encoding); let symbols = get_document_symbols(source, uri, position_encoding);
symbols.map(DocumentSymbolResponse::Flat) symbols.map(DocumentSymbolResponse::Flat)
} }

View file

@ -4,22 +4,21 @@ use crate::prelude::*;
pub struct HoverRequest { pub struct HoverRequest {
pub path: PathBuf, pub path: PathBuf,
pub position: LspPosition, pub position: LspPosition,
pub position_encoding: PositionEncoding,
} }
pub fn hover( pub fn hover(
world: &TypstSystemWorld, world: &TypstSystemWorld,
doc: Option<Arc<TypstDocument>>, doc: Option<Arc<TypstDocument>>,
req: HoverRequest, req: HoverRequest,
position_encoding: PositionEncoding,
) -> Option<Hover> { ) -> Option<Hover> {
let source = get_suitable_source_in_workspace(world, &req.path).ok()?; let source = get_suitable_source_in_workspace(world, &req.path).ok()?;
let typst_offset = let typst_offset = lsp_to_typst::position_to_offset(req.position, position_encoding, &source);
lsp_to_typst::position_to_offset(req.position, req.position_encoding, &source);
let typst_tooltip = typst_ide::tooltip(world, doc.as_deref(), &source, typst_offset)?; let typst_tooltip = typst_ide::tooltip(world, doc.as_deref(), &source, typst_offset)?;
let ast_node = LinkedNode::new(source.root()).leaf_at(typst_offset)?; let ast_node = LinkedNode::new(source.root()).leaf_at(typst_offset)?;
let range = typst_to_lsp::range(ast_node.range(), &source, req.position_encoding); let range = typst_to_lsp::range(ast_node.range(), &source, position_encoding);
Some(Hover { Some(Hover {
contents: typst_to_lsp::tooltip(&typst_tooltip), contents: typst_to_lsp::tooltip(&typst_tooltip),

View file

@ -4,22 +4,21 @@ use crate::prelude::*;
pub struct SelectionRangeRequest { pub struct SelectionRangeRequest {
pub path: PathBuf, pub path: PathBuf,
pub positions: Vec<LspPosition>, pub positions: Vec<LspPosition>,
pub position_encoding: PositionEncoding,
} }
pub fn selection_range( pub fn selection_range(
world: &TypstSystemWorld, world: &TypstSystemWorld,
req: SelectionRangeRequest, req: SelectionRangeRequest,
position_encoding: PositionEncoding,
) -> Option<Vec<SelectionRange>> { ) -> Option<Vec<SelectionRange>> {
let source = get_suitable_source_in_workspace(world, &req.path).ok()?; let source = get_suitable_source_in_workspace(world, &req.path).ok()?;
let mut ranges = Vec::new(); let mut ranges = Vec::new();
for position in req.positions { for position in req.positions {
let typst_offset = let typst_offset = lsp_to_typst::position_to_offset(position, position_encoding, &source);
lsp_to_typst::position_to_offset(position, req.position_encoding, &source);
let tree = LinkedNode::new(source.root()); let tree = LinkedNode::new(source.root());
let leaf = tree.leaf_at(typst_offset)?; let leaf = tree.leaf_at(typst_offset)?;
ranges.push(range_for_node(&source, req.position_encoding, &leaf)); ranges.push(range_for_node(&source, position_encoding, &leaf));
} }
Some(ranges) Some(ranges)

View file

@ -15,7 +15,7 @@ use self::modifier_set::ModifierSet;
use self::token_encode::encode_tokens; use self::token_encode::encode_tokens;
use self::typst_tokens::{Modifier, TokenType}; use self::typst_tokens::{Modifier, TokenType};
pub use self::delta::CacheInner as TokenCacheInner; use self::delta::CacheInner as TokenCacheInner;
mod delta; mod delta;
mod modifier_set; mod modifier_set;

View file

@ -4,18 +4,18 @@ use crate::{prelude::*, SemanticTokenCache};
pub struct SemanticTokensDeltaRequest { pub struct SemanticTokensDeltaRequest {
pub path: PathBuf, pub path: PathBuf,
pub previous_result_id: String, pub previous_result_id: String,
pub position_encoding: PositionEncoding,
} }
pub fn semantic_tokens_delta( pub fn semantic_tokens_delta(
cache: &SemanticTokenCache, cache: &SemanticTokenCache,
source: Source, source: Source,
req: SemanticTokensDeltaRequest, req: SemanticTokensDeltaRequest,
position_encoding: PositionEncoding,
) -> Option<SemanticTokensFullDeltaResult> { ) -> Option<SemanticTokensFullDeltaResult> {
let (tokens, result_id) = cache.try_semantic_tokens_delta_from_result_id( let (tokens, result_id) = cache.try_semantic_tokens_delta_from_result_id(
&source, &source,
&req.previous_result_id, &req.previous_result_id,
req.position_encoding, position_encoding,
); );
match tokens { match tokens {

View file

@ -3,15 +3,15 @@ use crate::{prelude::*, SemanticTokenCache};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct SemanticTokensFullRequest { pub struct SemanticTokensFullRequest {
pub path: PathBuf, pub path: PathBuf,
pub position_encoding: PositionEncoding,
} }
pub fn semantic_tokens_full( pub fn semantic_tokens_full(
cache: &SemanticTokenCache, cache: &SemanticTokenCache,
source: Source, source: Source,
req: SemanticTokensFullRequest, _req: SemanticTokensFullRequest,
position_encoding: PositionEncoding,
) -> Option<SemanticTokensResult> { ) -> Option<SemanticTokensResult> {
let (tokens, result_id) = cache.get_semantic_tokens_full(&source, req.position_encoding); let (tokens, result_id) = cache.get_semantic_tokens_full(&source, position_encoding);
Some( Some(
SemanticTokens { SemanticTokens {

View file

@ -4,16 +4,12 @@ use crate::prelude::*;
pub struct SignatureHelpRequest { pub struct SignatureHelpRequest {
pub path: PathBuf, pub path: PathBuf,
pub position: LspPosition, pub position: LspPosition,
pub position_encoding: PositionEncoding,
} }
pub fn signature_help( pub fn signature_help(
world: &TypstSystemWorld, world: &TypstSystemWorld,
SignatureHelpRequest { SignatureHelpRequest { path, position }: SignatureHelpRequest,
path, position_encoding: PositionEncoding,
position,
position_encoding,
}: SignatureHelpRequest,
) -> Option<SignatureHelp> { ) -> Option<SignatureHelp> {
let source = get_suitable_source_in_workspace(world, &path).ok()?; let source = get_suitable_source_in_workspace(world, &path).ok()?;
let typst_offset = lsp_to_typst::position_to_offset(position, position_encoding, &source); let typst_offset = lsp_to_typst::position_to_offset(position, position_encoding, &source);

View file

@ -6,15 +6,12 @@ use crate::prelude::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct SymbolRequest { pub struct SymbolRequest {
pub pattern: Option<String>, pub pattern: Option<String>,
pub position_encoding: PositionEncoding,
} }
pub fn symbol( pub fn symbol(
world: &TypstSystemWorld, world: &TypstSystemWorld,
SymbolRequest { SymbolRequest { pattern }: SymbolRequest,
pattern, position_encoding: PositionEncoding,
position_encoding,
}: SymbolRequest,
) -> Option<Vec<SymbolInformation>> { ) -> Option<Vec<SymbolInformation>> {
// todo: expose source // todo: expose source

View file

@ -31,12 +31,12 @@ use typst_ts_compiler::vfs::notify::{FileChangeSet, MemoryEvent};
use typst_ts_compiler::{Time, TypstSystemWorld}; use typst_ts_compiler::{Time, TypstSystemWorld};
use typst_ts_core::{ use typst_ts_core::{
config::CompileOpts, debug_loc::SourceSpanOffset, error::prelude::*, typst::prelude::EcoVec, config::CompileOpts, debug_loc::SourceSpanOffset, error::prelude::*, typst::prelude::EcoVec,
Bytes, DynExporter, Error, ImmutPath, TypstDocument, Bytes, Error, ImmutPath,
}; };
use crate::actor::render::PdfExportActor;
use crate::actor::render::RenderActorRequest; use crate::actor::render::RenderActorRequest;
use crate::LspHost; use crate::LspHost;
use crate::{actor::render::PdfExportActor, ConstConfig};
type CompileService<H> = CompileActor<Reporter<CompileExporter<CompileDriver>, H>>; type CompileService<H> = CompileActor<Reporter<CompileExporter<CompileDriver>, H>>;
type CompileClient<H> = TsCompileClient<CompileService<H>>; type CompileClient<H> = TsCompileClient<CompileService<H>>;
@ -44,18 +44,33 @@ type CompileClient<H> = TsCompileClient<CompileService<H>>;
type DiagnosticsSender = mpsc::UnboundedSender<(String, DiagnosticsMap)>; type DiagnosticsSender = mpsc::UnboundedSender<(String, DiagnosticsMap)>;
type DiagnosticsMap = HashMap<Url, Vec<LspDiagnostic>>; type DiagnosticsMap = HashMap<Url, Vec<LspDiagnostic>>;
type Client = TypstClient<CompileHandler>; // type Client = TypstClient<CompileHandler>;
pub fn create_cluster(host: LspHost, roots: Vec<PathBuf>, opts: CompileOpts) -> CompileCluster { pub struct CompileCluster {
position_encoding: PositionEncoding,
memory_changes: RwLock<HashMap<Arc<Path>, MemoryFileMeta>>,
primary: CompileNode<CompileHandler>,
pub tokens_cache: SemanticTokenCache,
actor: Option<CompileClusterActor>,
}
pub fn create_cluster(
host: LspHost,
cfg: &ConstConfig,
roots: Vec<PathBuf>,
opts: CompileOpts,
) -> CompileCluster {
let (diag_tx, diag_rx) = mpsc::unbounded_channel(); let (diag_tx, diag_rx) = mpsc::unbounded_channel();
let primary = create_server( let primary = create_server(
"primary".to_owned(), "primary".to_owned(),
cfg,
create_compiler(roots.clone(), opts.clone()), create_compiler(roots.clone(), opts.clone()),
diag_tx, diag_tx,
); );
CompileCluster { CompileCluster {
position_encoding: cfg.position_encoding,
memory_changes: RwLock::new(HashMap::new()), memory_changes: RwLock::new(HashMap::new()),
primary, primary,
tokens_cache: Default::default(), tokens_cache: Default::default(),
@ -75,32 +90,48 @@ fn create_compiler(roots: Vec<PathBuf>, opts: CompileOpts) -> CompileDriver {
fn create_server( fn create_server(
diag_group: String, diag_group: String,
cfg: &ConstConfig,
compiler_driver: CompileDriver, compiler_driver: CompileDriver,
diag_tx: DiagnosticsSender, diag_tx: DiagnosticsSender,
) -> CompileNode { ) -> CompileNode<CompileHandler> {
let (doc_sender, doc_recv) = watch::channel(None); let (doc_sender, doc_recv) = watch::channel(None);
let (render_tx, render_rx) = broadcast::channel(1024); let (render_tx, render_rx) = broadcast::channel(1024);
let exporter: DynExporter<TypstDocument> = Box::new(move |_w: &dyn World, doc| {
let _ = doc_sender.send(Some(doc)); // it is ok to ignore the error here
// todo: is it right that ignore zero broadcast receiver?
let _ = render_tx.send(RenderActorRequest::Render);
Ok(())
});
tokio::spawn(PdfExportActor::new(doc_recv, render_rx).run()); tokio::spawn(PdfExportActor::new(doc_recv, render_rx).run());
let root = compiler_driver.inner.world.root.as_ref().to_owned();
let handler: CompileHandler = compiler_driver.handler.clone(); let handler: CompileHandler = compiler_driver.handler.clone();
let compile_server = CompileServer::new(
diag_group,
compiler_driver,
handler.clone(),
diag_tx,
exporter,
);
CompileNode::new(handler, compile_server.spawn().unwrap()) let driver = CompileExporter::new(compiler_driver).with_exporter(Box::new(
move |_w: &dyn World, doc| {
let _ = doc_sender.send(Some(doc));
// todo: is it right that ignore zero broadcast receiver?
let _ = render_tx.send(RenderActorRequest::Render);
Ok(())
},
));
let driver = Reporter {
diag_group,
position_encoding: cfg.position_encoding,
diag_tx,
inner: driver,
cb: handler.clone(),
};
let driver = CompileActor::new(driver, root).with_watch(true);
let (server, client) = driver.split();
tokio::spawn(server.spawn());
CompileNode::new(cfg.position_encoding, handler, client)
}
impl CompileCluster {
pub fn split(mut self) -> (Self, CompileClusterActor) {
let actor = self.actor.take().expect("actor is poisoned");
(self, actor)
}
} }
pub struct CompileClusterActor { pub struct CompileClusterActor {
@ -111,20 +142,6 @@ pub struct CompileClusterActor {
affect_map: HashMap<String, Vec<Url>>, affect_map: HashMap<String, Vec<Url>>,
} }
pub struct CompileCluster {
memory_changes: RwLock<HashMap<Arc<Path>, MemoryFileMeta>>,
primary: CompileNode,
pub tokens_cache: SemanticTokenCache,
actor: Option<CompileClusterActor>,
}
impl CompileCluster {
pub fn split(mut self) -> (Self, CompileClusterActor) {
let actor = self.actor.take().expect("actor is poisoned");
(self, actor)
}
}
impl CompileClusterActor { impl CompileClusterActor {
pub async fn run(mut self) { pub async fn run(mut self) {
loop { loop {
@ -205,16 +222,13 @@ impl CompileCluster {
}, },
); );
let mut primary = self.primary.inner.lock().await;
let content: Bytes = content.as_bytes().into(); let content: Bytes = content.as_bytes().into();
primary.change_entry(path.clone()).await?; self.primary.change_entry(path.clone()).await?;
// todo: is it safe to believe that the path is normalized? // todo: is it safe to believe that the path is normalized?
let files = FileChangeSet::new_inserts(vec![(path, FileResult::Ok((now, content)).into())]); let files = FileChangeSet::new_inserts(vec![(path, FileResult::Ok((now, content)).into())]);
primary let iw = self.primary.inner.lock().await;
.inner() iw.add_memory_changes(MemoryEvent::Update(files));
.add_memory_changes(MemoryEvent::Update(files));
Ok(()) Ok(())
} }
@ -224,14 +238,11 @@ impl CompileCluster {
self.memory_changes.write().await.remove(&path); self.memory_changes.write().await.remove(&path);
let mut primary = self.primary.inner.lock().await;
// todo: is it safe to believe that the path is normalized? // todo: is it safe to believe that the path is normalized?
let files = FileChangeSet::new_removes(vec![path]); let files = FileChangeSet::new_removes(vec![path]);
// todo: change focus // todo: change focus
primary let iw = self.primary.inner.lock().await;
.inner() iw.add_memory_changes(MemoryEvent::Update(files));
.add_memory_changes(MemoryEvent::Update(files));
Ok(()) Ok(())
} }
@ -271,13 +282,10 @@ impl CompileCluster {
drop(memory_changes); drop(memory_changes);
let mut primary = self.primary.inner.lock().await; self.primary.change_entry(path.clone()).await?;
primary.change_entry(path.clone()).await?;
let files = FileChangeSet::new_inserts(vec![(path.clone(), snapshot)]); let files = FileChangeSet::new_inserts(vec![(path.clone(), snapshot)]);
primary let iw = self.primary.inner.lock().await;
.inner() iw.add_memory_changes(MemoryEvent::Update(files));
.add_memory_changes(MemoryEvent::Update(files));
Ok(()) Ok(())
} }
@ -317,14 +325,16 @@ pub enum CompilerQueryResponse {
macro_rules! query_state { macro_rules! query_state {
($self:ident, $method:ident, $query:expr, $req:expr) => {{ ($self:ident, $method:ident, $query:expr, $req:expr) => {{
let doc = $self.handler.result.lock().unwrap().clone().ok(); let doc = $self.handler.result.lock().unwrap().clone().ok();
let res = $self.steal_world(|w| $query(w, doc, $req)).await; let enc = $self.position_encoding;
let res = $self.steal_world(move |w| $query(w, doc, $req, enc)).await;
res.map(CompilerQueryResponse::$method) res.map(CompilerQueryResponse::$method)
}}; }};
} }
macro_rules! query_world { macro_rules! query_world {
($self:ident, $method:ident, $query:expr, $req:expr) => {{ ($self:ident, $method:ident, $query:expr, $req:expr) => {{
let res = $self.steal_world(|w| $query(w, $req)).await; let enc = $self.position_encoding;
let res = $self.steal_world(move |w| $query(w, $req, enc)).await;
res.map(CompilerQueryResponse::$method) res.map(CompilerQueryResponse::$method)
}}; }};
} }
@ -334,7 +344,10 @@ macro_rules! query_tokens_cache {
let path: ImmutPath = $req.path.clone().into(); let path: ImmutPath = $req.path.clone().into();
let vfs = $self.memory_changes.read().await; let vfs = $self.memory_changes.read().await;
let snapshot = vfs.get(&path).ok_or_else(|| anyhow!("file missing"))?; let snapshot = vfs.get(&path).ok_or_else(|| anyhow!("file missing"))?;
let res = $query(&$self.tokens_cache, snapshot.content.clone(), $req); let source = snapshot.content.clone();
let enc = $self.position_encoding;
let res = $query(&$self.tokens_cache, source, $req, enc);
Ok(CompilerQueryResponse::$method(res)) Ok(CompilerQueryResponse::$method(res))
}}; }};
} }
@ -441,50 +454,9 @@ impl CompileDriver {
} }
} }
pub struct CompileServer<H: CompilationHandle> {
inner: CompileService<H>,
client: TypstClient<H>,
}
impl<H: CompilationHandle> CompileServer<H> {
pub fn new(
diag_group: String,
compiler_driver: CompileDriver,
cb: H,
diag_tx: DiagnosticsSender,
exporter: DynExporter<TypstDocument>,
) -> Self {
let root = compiler_driver.inner.world.root.clone();
let driver = CompileExporter::new(compiler_driver).with_exporter(exporter);
let driver = Reporter {
diag_group,
diag_tx,
inner: driver,
cb,
};
let inner = CompileActor::new(driver, root.as_ref().to_owned()).with_watch(true);
Self {
inner,
client: TypstClient {
entry: Arc::new(SyncMutex::new(None)),
inner: once_cell::sync::OnceCell::new(),
},
}
}
pub fn spawn(self) -> Result<TypstClient<H>, Error> {
let (server, client) = self.inner.split();
tokio::spawn(server.spawn());
self.client.inner.set(client).ok().unwrap();
Ok(self.client)
}
}
pub struct Reporter<C, H> { pub struct Reporter<C, H> {
diag_group: String, diag_group: String,
position_encoding: PositionEncoding,
diag_tx: DiagnosticsSender, diag_tx: DiagnosticsSender,
inner: C, inner: C,
cb: H, cb: H,
@ -539,7 +511,7 @@ impl<C: Compiler<World = TypstSystemWorld>, H> Reporter<C, H> {
let diagnostics = tinymist_query::convert_diagnostics( let diagnostics = tinymist_query::convert_diagnostics(
self.inner.world(), self.inner.world(),
diagnostics.as_ref(), diagnostics.as_ref(),
PositionEncoding::Utf16, self.position_encoding,
); );
let err = self.diag_tx.send((self.diag_group.clone(), diagnostics)); let err = self.diag_tx.send((self.diag_group.clone(), diagnostics));
@ -549,29 +521,31 @@ impl<C: Compiler<World = TypstSystemWorld>, H> Reporter<C, H> {
} }
} }
pub struct TypstClient<H: CompilationHandle> { pub struct CompileNode<H: CompilationHandle> {
position_encoding: PositionEncoding,
handler: CompileHandler,
entry: Arc<SyncMutex<Option<ImmutPath>>>, entry: Arc<SyncMutex<Option<ImmutPath>>>,
inner: once_cell::sync::OnceCell<CompileClient<H>>, inner: Mutex<CompileClient<H>>,
} }
// todo: remove unsafe impl send // todo: remove unsafe impl send
unsafe impl<H: CompilationHandle> Send for TypstClient<H> {} unsafe impl<H: CompilationHandle> Send for CompileNode<H> {}
unsafe impl<H: CompilationHandle> Sync for TypstClient<H> {} unsafe impl<H: CompilationHandle> Sync for CompileNode<H> {}
impl<H: CompilationHandle> TypstClient<H> { impl<H: CompilationHandle> CompileNode<H> {
fn inner(&mut self) -> &mut CompileClient<H> { fn inner(&mut self) -> &mut CompileClient<H> {
self.inner.get_mut().unwrap() self.inner.get_mut()
} }
/// Steal the compiler thread and run the given function. /// Steal the compiler thread and run the given function.
pub async fn steal_async<Ret: Send + 'static>( pub async fn steal_async<Ret: Send + 'static>(
&mut self, &self,
f: impl FnOnce(&mut CompileService<H>, tokio::runtime::Handle) -> Ret + Send + 'static, f: impl FnOnce(&mut CompileService<H>, tokio::runtime::Handle) -> Ret + Send + 'static,
) -> ZResult<Ret> { ) -> ZResult<Ret> {
self.inner().steal_async(f).await self.inner.lock().await.steal_async(f).await
} }
async fn change_entry(&mut self, path: ImmutPath) -> Result<(), Error> { async fn change_entry(&self, path: ImmutPath) -> Result<(), Error> {
if !path.is_absolute() { if !path.is_absolute() {
return Err(error_once!("entry file must be absolute", path: path.display())); return Err(error_once!("entry file must be absolute", path: path.display()));
} }
@ -602,7 +576,7 @@ impl<H: CompilationHandle> TypstClient<H> {
} }
} }
impl<H: CompilationHandle> SourceFileServer for TypstClient<H> { impl<H: CompilationHandle> SourceFileServer for CompileNode<H> {
async fn resolve_source_span( async fn resolve_source_span(
&mut self, &mut self,
loc: Location, loc: Location,
@ -648,7 +622,7 @@ impl<H: CompilationHandle> SourceFileServer for TypstClient<H> {
} }
} }
impl<H: CompilationHandle> EditorServer for TypstClient<H> { impl<H: CompilationHandle> EditorServer for CompileNode<H> {
async fn update_memory_files( async fn update_memory_files(
&mut self, &mut self,
files: MemoryFiles, files: MemoryFiles,
@ -685,18 +659,19 @@ impl<H: CompilationHandle> EditorServer for TypstClient<H> {
} }
} }
impl<H: CompilationHandle> CompileHost for TypstClient<H> {} impl<H: CompilationHandle> CompileHost for CompileNode<H> {}
pub struct CompileNode { impl<H: CompilationHandle> CompileNode<H> {
handler: CompileHandler, fn new(
inner: Arc<Mutex<Client>>, position_encoding: PositionEncoding,
} handler: CompileHandler,
inner: CompileClient<H>,
impl CompileNode { ) -> Self {
fn new(handler: CompileHandler, unwrap: TypstClient<CompileHandler>) -> Self {
Self { Self {
position_encoding,
handler, handler,
inner: Arc::new(Mutex::new(unwrap)), entry: Arc::new(SyncMutex::new(None)),
inner: Mutex::new(inner),
} }
} }

View file

@ -252,11 +252,16 @@ impl LanguageServer for TypstServer {
async fn initialize(&self, params: InitializeParams) -> jsonrpc::Result<InitializeResult> { async fn initialize(&self, params: InitializeParams) -> jsonrpc::Result<InitializeResult> {
// self.tracing_init(); // self.tracing_init();
self.const_config
.set(ConstConfig::from(&params))
.expect("const config should not yet be initialized");
let cluster = { let cluster = {
let root_paths = params.root_paths(); let root_paths = params.root_paths();
let primary_root = root_paths.first().cloned().unwrap_or_default(); let primary_root = root_paths.first().cloned().unwrap_or_default();
actor::typst::create_cluster( actor::typst::create_cluster(
self.client.clone(), self.client.clone(),
self.const_config.get().unwrap(),
root_paths, root_paths,
CompileOpts { CompileOpts {
root_dir: primary_root, root_dir: primary_root,
@ -275,10 +280,6 @@ impl LanguageServer for TypstServer {
.map_err(|_| ()) .map_err(|_| ())
.expect("the cluster is already initialized"); .expect("the cluster is already initialized");
self.const_config
.set(ConstConfig::from(&params))
.expect("const config should not yet be initialized");
tokio::spawn(cluster_bg.run()); tokio::spawn(cluster_bg.run());
if let Some(init) = &params.initialization_options { if let Some(init) = &params.initialization_options {
@ -498,17 +499,8 @@ impl LanguageServer for TypstServer {
let uri = &params.text_document_position_params.text_document.uri; let uri = &params.text_document_position_params.text_document.uri;
let path = uri.to_file_path().unwrap(); let path = uri.to_file_path().unwrap();
let position = params.text_document_position_params.position; let position = params.text_document_position_params.position;
let position_encoding = self.const_config().position_encoding;
run_query!( run_query!(self, Hover, HoverRequest { path, position })
self,
Hover,
HoverRequest {
path,
position,
position_encoding,
}
)
} }
async fn completion( async fn completion(
@ -522,7 +514,6 @@ impl LanguageServer for TypstServer {
.context .context
.map(|context| context.trigger_kind == CompletionTriggerKind::INVOKED) .map(|context| context.trigger_kind == CompletionTriggerKind::INVOKED)
.unwrap_or(false); .unwrap_or(false);
let position_encoding = self.const_config().position_encoding;
run_query!( run_query!(
self, self,
@ -530,7 +521,6 @@ impl LanguageServer for TypstServer {
CompletionRequest { CompletionRequest {
path, path,
position, position,
position_encoding,
explicit, explicit,
} }
) )
@ -543,17 +533,8 @@ impl LanguageServer for TypstServer {
let uri = params.text_document_position_params.text_document.uri; let uri = params.text_document_position_params.text_document.uri;
let path = uri.to_file_path().unwrap(); let path = uri.to_file_path().unwrap();
let position = params.text_document_position_params.position; let position = params.text_document_position_params.position;
let position_encoding = self.const_config().position_encoding;
run_query!( run_query!(self, SignatureHelp, SignatureHelpRequest { path, position })
self,
SignatureHelp,
SignatureHelpRequest {
path,
position,
position_encoding,
}
)
} }
async fn document_symbol( async fn document_symbol(
@ -562,16 +543,8 @@ impl LanguageServer for TypstServer {
) -> jsonrpc::Result<Option<DocumentSymbolResponse>> { ) -> jsonrpc::Result<Option<DocumentSymbolResponse>> {
let uri = params.text_document.uri; let uri = params.text_document.uri;
let path = uri.to_file_path().unwrap(); let path = uri.to_file_path().unwrap();
let position_encoding = self.const_config().position_encoding;
run_query!( run_query!(self, DocumentSymbol, DocumentSymbolRequest { path })
self,
DocumentSymbol,
DocumentSymbolRequest {
path,
position_encoding
}
)
} }
async fn symbol( async fn symbol(
@ -579,16 +552,8 @@ impl LanguageServer for TypstServer {
params: WorkspaceSymbolParams, params: WorkspaceSymbolParams,
) -> jsonrpc::Result<Option<Vec<SymbolInformation>>> { ) -> jsonrpc::Result<Option<Vec<SymbolInformation>>> {
let pattern = (!params.query.is_empty()).then_some(params.query); let pattern = (!params.query.is_empty()).then_some(params.query);
let position_encoding = self.const_config().position_encoding;
run_query!( run_query!(self, Symbol, SymbolRequest { pattern })
self,
Symbol,
SymbolRequest {
pattern,
position_encoding
}
)
} }
async fn selection_range( async fn selection_range(
@ -598,16 +563,11 @@ impl LanguageServer for TypstServer {
let uri = params.text_document.uri; let uri = params.text_document.uri;
let path = uri.to_file_path().unwrap(); let path = uri.to_file_path().unwrap();
let positions = params.positions; let positions = params.positions;
let position_encoding = self.const_config().position_encoding;
run_query!( run_query!(
self, self,
SelectionRange, SelectionRange,
SelectionRangeRequest { SelectionRangeRequest { path, positions }
path,
positions,
position_encoding
}
) )
} }
@ -617,16 +577,8 @@ impl LanguageServer for TypstServer {
) -> jsonrpc::Result<Option<SemanticTokensResult>> { ) -> jsonrpc::Result<Option<SemanticTokensResult>> {
let uri = params.text_document.uri; let uri = params.text_document.uri;
let path = uri.to_file_path().unwrap(); let path = uri.to_file_path().unwrap();
let position_encoding = self.const_config().position_encoding;
run_query!( run_query!(self, SemanticTokensFull, SemanticTokensFullRequest { path })
self,
SemanticTokensFull,
SemanticTokensFullRequest {
path,
position_encoding
}
)
} }
async fn semantic_tokens_full_delta( async fn semantic_tokens_full_delta(
@ -636,7 +588,6 @@ impl LanguageServer for TypstServer {
let uri = params.text_document.uri; let uri = params.text_document.uri;
let path = uri.to_file_path().unwrap(); let path = uri.to_file_path().unwrap();
let previous_result_id = params.previous_result_id; let previous_result_id = params.previous_result_id;
let position_encoding = self.const_config().position_encoding;
run_query!( run_query!(
self, self,
@ -644,7 +595,6 @@ impl LanguageServer for TypstServer {
SemanticTokensDeltaRequest { SemanticTokensDeltaRequest {
path, path,
previous_result_id, previous_result_id,
position_encoding
} }
) )
} }