mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-19 02:35:00 +00:00
refactor: move entry resolver to query crate (#944)
This commit is contained in:
parent
356fc2daad
commit
d5c07b1ae3
7 changed files with 223 additions and 214 deletions
211
crates/tinymist-query/src/entry.rs
Normal file
211
crates/tinymist-query/src/entry.rs
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
use anyhow::bail;
|
||||||
|
use reflexo_typst::{EntryState, ImmutPath, TypstFileId};
|
||||||
|
use typst::syntax::VirtualPath;
|
||||||
|
|
||||||
|
/// Entry resolver
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
pub struct EntryResolver {
|
||||||
|
/// Specifies the root path of the project manually.
|
||||||
|
pub root_path: Option<ImmutPath>,
|
||||||
|
/// The workspace roots from initialization.
|
||||||
|
pub roots: Vec<ImmutPath>,
|
||||||
|
/// Default entry path from the configuration.
|
||||||
|
pub entry: Option<ImmutPath>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntryResolver {
|
||||||
|
/// Resolves the root directory for the entry file.
|
||||||
|
pub fn root(&self, entry: Option<&ImmutPath>) -> Option<ImmutPath> {
|
||||||
|
if let Some(root) = &self.root_path {
|
||||||
|
return Some(root.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(entry) = entry {
|
||||||
|
for root in self.roots.iter() {
|
||||||
|
if entry.starts_with(root) {
|
||||||
|
return Some(root.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.roots.is_empty() {
|
||||||
|
log::warn!("entry is not in any set root directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(parent) = entry.parent() {
|
||||||
|
return Some(parent.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.roots.is_empty() {
|
||||||
|
return Some(self.roots[0].clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resolves the entry state.
|
||||||
|
pub fn resolve(&self, entry: Option<ImmutPath>) -> EntryState {
|
||||||
|
// todo: formalize untitled path
|
||||||
|
// let is_untitled = entry.as_ref().is_some_and(|p| p.starts_with("/untitled"));
|
||||||
|
// let root_dir = self.determine_root(if is_untitled { None } else {
|
||||||
|
// entry.as_ref() });
|
||||||
|
let root_dir = self.root(entry.as_ref());
|
||||||
|
|
||||||
|
let entry = match (entry, root_dir) {
|
||||||
|
// (Some(entry), Some(root)) if is_untitled => Some(EntryState::new_rooted(
|
||||||
|
// root,
|
||||||
|
// Some(FileId::new(None, VirtualPath::new(entry))),
|
||||||
|
// )),
|
||||||
|
(Some(entry), Some(root)) => match entry.strip_prefix(&root) {
|
||||||
|
Ok(stripped) => Some(EntryState::new_rooted(
|
||||||
|
root,
|
||||||
|
Some(TypstFileId::new(None, VirtualPath::new(stripped))),
|
||||||
|
)),
|
||||||
|
Err(err) => {
|
||||||
|
log::info!("Entry is not in root directory: err {err:?}: entry: {entry:?}, root: {root:?}");
|
||||||
|
EntryState::new_rootless(entry)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(Some(entry), None) => EntryState::new_rootless(entry),
|
||||||
|
(None, Some(root)) => Some(EntryState::new_workspace(root)),
|
||||||
|
(None, None) => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
entry.unwrap_or_else(|| match self.root(None) {
|
||||||
|
Some(root) => EntryState::new_workspace(root),
|
||||||
|
None => EntryState::new_detached(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determines the default entry path.
|
||||||
|
pub fn resolve_default(&self) -> Option<ImmutPath> {
|
||||||
|
let entry = self.entry.as_ref();
|
||||||
|
// todo: pre-compute this when updating config
|
||||||
|
if let Some(entry) = entry {
|
||||||
|
if entry.is_relative() {
|
||||||
|
let root = self.root(None)?;
|
||||||
|
return Some(root.join(entry).as_path().into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entry.cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Validates the configuration.
|
||||||
|
pub fn validate(&self) -> anyhow::Result<()> {
|
||||||
|
if let Some(root) = &self.root_path {
|
||||||
|
if !root.is_absolute() {
|
||||||
|
bail!("rootPath or typstExtraArgs.root must be an absolute path: {root:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[cfg(any(windows, unix, target_os = "macos"))]
|
||||||
|
mod entry_tests {
|
||||||
|
use super::*;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_entry_resolution() {
|
||||||
|
let root_path = Path::new(if cfg!(windows) { "C:\\root" } else { "/root" });
|
||||||
|
|
||||||
|
let entry = EntryResolver {
|
||||||
|
root_path: Some(ImmutPath::from(root_path)),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let entry = entry.resolve(if cfg!(windows) {
|
||||||
|
Some(Path::new("C:\\root\\main.typ").into())
|
||||||
|
} else {
|
||||||
|
Some(Path::new("/root/main.typ").into())
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(entry.root(), Some(ImmutPath::from(root_path)));
|
||||||
|
assert_eq!(
|
||||||
|
entry.main(),
|
||||||
|
Some(TypstFileId::new(None, VirtualPath::new("main.typ")))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_entry_resolution_multi_root() {
|
||||||
|
let root_path = Path::new(if cfg!(windows) { "C:\\root" } else { "/root" });
|
||||||
|
let root2_path = Path::new(if cfg!(windows) { "C:\\root2" } else { "/root2" });
|
||||||
|
|
||||||
|
let entry = EntryResolver {
|
||||||
|
root_path: Some(ImmutPath::from(root_path)),
|
||||||
|
roots: vec![ImmutPath::from(root_path), ImmutPath::from(root2_path)],
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let entry = entry.resolve(if cfg!(windows) {
|
||||||
|
Some(Path::new("C:\\root\\main.typ").into())
|
||||||
|
} else {
|
||||||
|
Some(Path::new("/root/main.typ").into())
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(entry.root(), Some(ImmutPath::from(root_path)));
|
||||||
|
assert_eq!(
|
||||||
|
entry.main(),
|
||||||
|
Some(TypstFileId::new(None, VirtualPath::new("main.typ")))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let entry = entry.resolve(if cfg!(windows) {
|
||||||
|
Some(Path::new("C:\\root2\\main.typ").into())
|
||||||
|
} else {
|
||||||
|
Some(Path::new("/root2/main.typ").into())
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(entry.root(), Some(ImmutPath::from(root2_path)));
|
||||||
|
assert_eq!(
|
||||||
|
entry.main(),
|
||||||
|
Some(TypstFileId::new(None, VirtualPath::new("main.typ")))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_entry_resolution_default_multi_root() {
|
||||||
|
let root_path = Path::new(if cfg!(windows) { "C:\\root" } else { "/root" });
|
||||||
|
let root2_path = Path::new(if cfg!(windows) { "C:\\root2" } else { "/root2" });
|
||||||
|
|
||||||
|
let mut entry = EntryResolver {
|
||||||
|
root_path: Some(ImmutPath::from(root_path)),
|
||||||
|
roots: vec![ImmutPath::from(root_path), ImmutPath::from(root2_path)],
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
entry.entry = if cfg!(windows) {
|
||||||
|
Some(Path::new("C:\\root\\main.typ").into())
|
||||||
|
} else {
|
||||||
|
Some(Path::new("/root/main.typ").into())
|
||||||
|
};
|
||||||
|
|
||||||
|
let default_entry = entry.resolve_default();
|
||||||
|
|
||||||
|
assert_eq!(default_entry, entry.entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
entry.entry = Some(Path::new("main.typ").into());
|
||||||
|
|
||||||
|
let default_entry = entry.resolve_default();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
default_entry,
|
||||||
|
if cfg!(windows) {
|
||||||
|
Some(Path::new("C:\\root\\main.typ").into())
|
||||||
|
} else {
|
||||||
|
Some(Path::new("/root/main.typ").into())
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,8 @@ mod upstream;
|
||||||
pub use analysis::{LocalContext, LocalContextGuard, LspWorldExt};
|
pub use analysis::{LocalContext, LocalContextGuard, LspWorldExt};
|
||||||
pub use upstream::{with_vm, CompletionFeat, PostfixSnippet};
|
pub use upstream::{with_vm, CompletionFeat, PostfixSnippet};
|
||||||
|
|
||||||
|
mod entry;
|
||||||
|
pub use entry::*;
|
||||||
mod diagnostics;
|
mod diagnostics;
|
||||||
pub use diagnostics::*;
|
pub use diagnostics::*;
|
||||||
mod code_action;
|
mod code_action;
|
||||||
|
|
|
@ -33,8 +33,8 @@ use reflexo_typst::{
|
||||||
use sync_lsp::{just_future, QueryFuture};
|
use sync_lsp::{just_future, QueryFuture};
|
||||||
use tinymist_query::{
|
use tinymist_query::{
|
||||||
analysis::{Analysis, AnalysisRevLock, LocalContextGuard},
|
analysis::{Analysis, AnalysisRevLock, LocalContextGuard},
|
||||||
CompilerQueryRequest, CompilerQueryResponse, DiagnosticsMap, OnExportRequest, SemanticRequest,
|
CompilerQueryRequest, CompilerQueryResponse, DiagnosticsMap, EntryResolver, OnExportRequest,
|
||||||
ServerInfoResponse, StatefulRequest, VersionedDocument,
|
SemanticRequest, ServerInfoResponse, StatefulRequest, VersionedDocument,
|
||||||
};
|
};
|
||||||
use tokio::sync::{mpsc, oneshot};
|
use tokio::sync::{mpsc, oneshot};
|
||||||
use typst::{diag::SourceDiagnostic, World};
|
use typst::{diag::SourceDiagnostic, World};
|
||||||
|
@ -49,7 +49,7 @@ use crate::{
|
||||||
stats::{CompilerQueryStats, QueryStatGuard},
|
stats::{CompilerQueryStats, QueryStatGuard},
|
||||||
task::{ExportTask, ExportUserConfig},
|
task::{ExportTask, ExportUserConfig},
|
||||||
world::{LspCompilerFeat, LspWorld},
|
world::{LspCompilerFeat, LspWorld},
|
||||||
CompileConfig, EntryResolver,
|
CompileConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
type EditorSender = mpsc::UnboundedSender<EditorRequest>;
|
type EditorSender = mpsc::UnboundedSender<EditorRequest>;
|
||||||
|
|
|
@ -15,10 +15,10 @@ use serde_json::{json, Map, Value as JsonValue};
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
use task::FormatUserConfig;
|
use task::FormatUserConfig;
|
||||||
use tinymist_query::analysis::{Modifier, TokenType};
|
use tinymist_query::analysis::{Modifier, TokenType};
|
||||||
use tinymist_query::{CompletionFeat, PositionEncoding};
|
use tinymist_query::{CompletionFeat, EntryResolver, PositionEncoding};
|
||||||
use tinymist_render::PeriscopeArgs;
|
use tinymist_render::PeriscopeArgs;
|
||||||
use typst::foundations::IntoValue;
|
use typst::foundations::IntoValue;
|
||||||
use typst::syntax::{FileId, VirtualPath};
|
use typst::syntax::FileId;
|
||||||
use typst_shim::utils::{Deferred, LazyHash};
|
use typst_shim::utils::{Deferred, LazyHash};
|
||||||
|
|
||||||
// todo: svelte-language-server responds to a Goto Definition request with
|
// todo: svelte-language-server responds to a Goto Definition request with
|
||||||
|
@ -469,106 +469,6 @@ impl From<&InitializeParams> for ConstConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Entry resolver
|
|
||||||
#[derive(Debug, Default, Clone)]
|
|
||||||
pub struct EntryResolver {
|
|
||||||
/// Specifies the root path of the project manually.
|
|
||||||
pub root_path: Option<ImmutPath>,
|
|
||||||
/// The workspace roots from initialization.
|
|
||||||
pub roots: Vec<ImmutPath>,
|
|
||||||
/// Default entry path from the configuration.
|
|
||||||
pub entry: Option<ImmutPath>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EntryResolver {
|
|
||||||
/// Resolves the root directory for the entry file.
|
|
||||||
pub fn root(&self, entry: Option<&ImmutPath>) -> Option<ImmutPath> {
|
|
||||||
if let Some(root) = &self.root_path {
|
|
||||||
return Some(root.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(entry) = entry {
|
|
||||||
for root in self.roots.iter() {
|
|
||||||
if entry.starts_with(root) {
|
|
||||||
return Some(root.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.roots.is_empty() {
|
|
||||||
log::warn!("entry is not in any set root directory");
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(parent) = entry.parent() {
|
|
||||||
return Some(parent.into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.roots.is_empty() {
|
|
||||||
return Some(self.roots[0].clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Resolves the entry state.
|
|
||||||
pub fn resolve(&self, entry: Option<ImmutPath>) -> EntryState {
|
|
||||||
// todo: formalize untitled path
|
|
||||||
// let is_untitled = entry.as_ref().is_some_and(|p| p.starts_with("/untitled"));
|
|
||||||
// let root_dir = self.determine_root(if is_untitled { None } else {
|
|
||||||
// entry.as_ref() });
|
|
||||||
let root_dir = self.root(entry.as_ref());
|
|
||||||
|
|
||||||
let entry = match (entry, root_dir) {
|
|
||||||
// (Some(entry), Some(root)) if is_untitled => Some(EntryState::new_rooted(
|
|
||||||
// root,
|
|
||||||
// Some(FileId::new(None, VirtualPath::new(entry))),
|
|
||||||
// )),
|
|
||||||
(Some(entry), Some(root)) => match entry.strip_prefix(&root) {
|
|
||||||
Ok(stripped) => Some(EntryState::new_rooted(
|
|
||||||
root,
|
|
||||||
Some(FileId::new(None, VirtualPath::new(stripped))),
|
|
||||||
)),
|
|
||||||
Err(err) => {
|
|
||||||
log::info!("Entry is not in root directory: err {err:?}: entry: {entry:?}, root: {root:?}");
|
|
||||||
EntryState::new_rootless(entry)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(Some(entry), None) => EntryState::new_rootless(entry),
|
|
||||||
(None, Some(root)) => Some(EntryState::new_workspace(root)),
|
|
||||||
(None, None) => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
entry.unwrap_or_else(|| match self.root(None) {
|
|
||||||
Some(root) => EntryState::new_workspace(root),
|
|
||||||
None => EntryState::new_detached(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Determines the default entry path.
|
|
||||||
pub fn resolve_default(&self) -> Option<ImmutPath> {
|
|
||||||
let entry = self.entry.as_ref();
|
|
||||||
// todo: pre-compute this when updating config
|
|
||||||
if let Some(entry) = entry {
|
|
||||||
if entry.is_relative() {
|
|
||||||
let root = self.root(None)?;
|
|
||||||
return Some(root.join(entry).as_path().into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entry.cloned()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Validates the configuration.
|
|
||||||
pub fn validate(&self) -> anyhow::Result<()> {
|
|
||||||
if let Some(root) = &self.root_path {
|
|
||||||
if !root.is_absolute() {
|
|
||||||
bail!("rootPath or typstExtraArgs.root must be an absolute path: {root:?}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The user configuration read from the editor.
|
/// The user configuration read from the editor.
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct CompileConfig {
|
pub struct CompileConfig {
|
||||||
|
@ -983,110 +883,7 @@ impl PathPattern {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
use typst::syntax::VirtualPath;
|
||||||
#[test]
|
|
||||||
#[cfg(any(windows, unix, target_os = "macos"))]
|
|
||||||
fn test_entry_resolution() {
|
|
||||||
let root_path = Path::new(if cfg!(windows) { "C:\\root" } else { "/root" });
|
|
||||||
|
|
||||||
let entry = EntryResolver {
|
|
||||||
root_path: Some(ImmutPath::from(root_path)),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let entry = entry.resolve(if cfg!(windows) {
|
|
||||||
Some(Path::new("C:\\root\\main.typ").into())
|
|
||||||
} else {
|
|
||||||
Some(Path::new("/root/main.typ").into())
|
|
||||||
});
|
|
||||||
|
|
||||||
assert_eq!(entry.root(), Some(ImmutPath::from(root_path)));
|
|
||||||
assert_eq!(
|
|
||||||
entry.main(),
|
|
||||||
Some(FileId::new(None, VirtualPath::new("main.typ")))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg(any(windows, unix, target_os = "macos"))]
|
|
||||||
fn test_entry_resolution_multi_root() {
|
|
||||||
let root_path = Path::new(if cfg!(windows) { "C:\\root" } else { "/root" });
|
|
||||||
let root2_path = Path::new(if cfg!(windows) { "C:\\root2" } else { "/root2" });
|
|
||||||
|
|
||||||
let entry = EntryResolver {
|
|
||||||
root_path: Some(ImmutPath::from(root_path)),
|
|
||||||
roots: vec![ImmutPath::from(root_path), ImmutPath::from(root2_path)],
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
{
|
|
||||||
let entry = entry.resolve(if cfg!(windows) {
|
|
||||||
Some(Path::new("C:\\root\\main.typ").into())
|
|
||||||
} else {
|
|
||||||
Some(Path::new("/root/main.typ").into())
|
|
||||||
});
|
|
||||||
|
|
||||||
assert_eq!(entry.root(), Some(ImmutPath::from(root_path)));
|
|
||||||
assert_eq!(
|
|
||||||
entry.main(),
|
|
||||||
Some(FileId::new(None, VirtualPath::new("main.typ")))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let entry = entry.resolve(if cfg!(windows) {
|
|
||||||
Some(Path::new("C:\\root2\\main.typ").into())
|
|
||||||
} else {
|
|
||||||
Some(Path::new("/root2/main.typ").into())
|
|
||||||
});
|
|
||||||
|
|
||||||
assert_eq!(entry.root(), Some(ImmutPath::from(root2_path)));
|
|
||||||
assert_eq!(
|
|
||||||
entry.main(),
|
|
||||||
Some(FileId::new(None, VirtualPath::new("main.typ")))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg(any(windows, unix, target_os = "macos"))]
|
|
||||||
fn test_entry_resolution_default_multi_root() {
|
|
||||||
let root_path = Path::new(if cfg!(windows) { "C:\\root" } else { "/root" });
|
|
||||||
let root2_path = Path::new(if cfg!(windows) { "C:\\root2" } else { "/root2" });
|
|
||||||
|
|
||||||
let mut entry = EntryResolver {
|
|
||||||
root_path: Some(ImmutPath::from(root_path)),
|
|
||||||
roots: vec![ImmutPath::from(root_path), ImmutPath::from(root2_path)],
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
{
|
|
||||||
entry.entry = if cfg!(windows) {
|
|
||||||
Some(Path::new("C:\\root\\main.typ").into())
|
|
||||||
} else {
|
|
||||||
Some(Path::new("/root/main.typ").into())
|
|
||||||
};
|
|
||||||
|
|
||||||
let default_entry = entry.resolve_default();
|
|
||||||
|
|
||||||
assert_eq!(default_entry, entry.entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
entry.entry = Some(Path::new("main.typ").into());
|
|
||||||
|
|
||||||
let default_entry = entry.resolve_default();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
default_entry,
|
|
||||||
if cfg!(windows) {
|
|
||||||
Some(Path::new("C:\\root\\main.typ").into())
|
|
||||||
} else {
|
|
||||||
Some(Path::new("/root/main.typ").into())
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_default_encoding() {
|
fn test_default_encoding() {
|
||||||
|
|
|
@ -32,6 +32,7 @@ mod utils;
|
||||||
pub use init::*;
|
pub use init::*;
|
||||||
pub use server::*;
|
pub use server::*;
|
||||||
pub use sync_lsp::LspClient;
|
pub use sync_lsp::LspClient;
|
||||||
|
pub use tinymist_query as query;
|
||||||
pub use tinymist_world as world;
|
pub use tinymist_world as world;
|
||||||
pub use world::*;
|
pub use world::*;
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,8 @@ use sync_lsp::{
|
||||||
transport::{with_stdio_transport, MirrorArgs},
|
transport::{with_stdio_transport, MirrorArgs},
|
||||||
LspBuilder, LspClientRoot, LspResult,
|
LspBuilder, LspClientRoot, LspResult,
|
||||||
};
|
};
|
||||||
use tinymist::{
|
use tinymist::{CompileConfig, Config, LanguageState, RegularInit, SuperInit, UserActionTask};
|
||||||
CompileConfig, Config, EntryResolver, LanguageState, RegularInit, SuperInit, UserActionTask,
|
use tinymist_query::{package::PackageInfo, EntryResolver};
|
||||||
};
|
|
||||||
use tinymist_query::package::PackageInfo;
|
|
||||||
use typst::foundations::IntoValue;
|
use typst::foundations::IntoValue;
|
||||||
use typst_shim::utils::LazyHash;
|
use typst_shim::utils::LazyHash;
|
||||||
|
|
||||||
|
|
|
@ -22,11 +22,11 @@ use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{Map, Value as JsonValue};
|
use serde_json::{Map, Value as JsonValue};
|
||||||
use sync_lsp::*;
|
use sync_lsp::*;
|
||||||
use task::{CacheTask, ExportUserConfig, FormatTask, FormatUserConfig, UserActionTask};
|
use task::{CacheTask, ExportUserConfig, FormatTask, FormatUserConfig, UserActionTask};
|
||||||
use tinymist_query::PageSelection;
|
|
||||||
use tinymist_query::{
|
use tinymist_query::{
|
||||||
lsp_to_typst, CompilerQueryRequest, CompilerQueryResponse, FoldRequestFeature,
|
lsp_to_typst, CompilerQueryRequest, CompilerQueryResponse, FoldRequestFeature,
|
||||||
PositionEncoding, SyntaxRequest,
|
PositionEncoding, SyntaxRequest,
|
||||||
};
|
};
|
||||||
|
use tinymist_query::{EntryResolver, PageSelection};
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use typst::{diag::FileResult, syntax::Source};
|
use typst::{diag::FileResult, syntax::Source};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue