diff --git a/src/server/formatting.rs b/src/server/formatting.rs index c3a1e6ba..6d39fce6 100644 --- a/src/server/formatting.rs +++ b/src/server/formatting.rs @@ -1,10 +1,15 @@ +use anyhow::anyhow; use tower_lsp::lsp_types::{Position, Range, Registration, TextEdit, Unregistration}; -use typst::syntax::Source; +use typst::syntax::{FileId, Source, VirtualPath}; +use typstfmt_lib::Config; + +use crate::workspace::project::Project; use super::TypstServer; const FORMATTING_REGISTRATION_ID: &str = "formatting"; const DOCUMENT_FORMATTING_METHOD_ID: &str = "textDocument/formatting"; +const CONFIG_PATH: &str = "typstfmt-config.toml"; pub fn get_formatting_registration() -> Registration { Registration { @@ -22,9 +27,14 @@ pub fn get_formatting_unregistration() -> Unregistration { } impl TypstServer { - pub fn format_document(&self, source: &Source) -> anyhow::Result> { + pub async fn format_document( + &self, + project: Project, + source: Source, + ) -> anyhow::Result> { + let config = get_config(&project).await?; let original_text = source.text(); - let res = typstfmt_lib::format(original_text, typstfmt_lib::Config::default()); + let res = typstfmt_lib::format(original_text, config); Ok(vec![TextEdit { new_text: res, @@ -41,3 +51,22 @@ impl TypstServer { }]) } } + +async fn get_config(project: &Project) -> anyhow::Result { + config_from_file(project) + .await + .unwrap_or_else(|| Ok(Config::default())) +} + +async fn config_from_file(project: &Project) -> Option> { + let file_id = FileId::new(None, VirtualPath::new(CONFIG_PATH)); + let file = project.read_bytes_by_id(file_id).await.ok()?; + let bytes = file.as_slice(); + Some(config_from_bytes(bytes)) +} + +fn config_from_bytes(bytes: &[u8]) -> anyhow::Result { + let string = std::str::from_utf8(bytes)?; + let config = Config::from_toml(string).map_err(|err| anyhow!("{err}"))?; + Ok(config) +} diff --git a/src/server/lsp.rs b/src/server/lsp.rs index 607960ff..ad8ff858 100644 --- a/src/server/lsp.rs +++ b/src/server/lsp.rs @@ -612,7 +612,8 @@ impl LanguageServer for TypstServer { error!(%err, %uri, "error getting document to format"); jsonrpc::Error::internal_error() })? - .run(|source, _| self.format_document(source)) + .run2(|source, project| self.format_document(project, source)) + .await .map_err(|err| { error!(%err, %uri, "error formatting document"); jsonrpc::Error::internal_error()