mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-08-01 17:02:15 +00:00
fix: bad configuration initialization (#523)
This commit is contained in:
parent
555da7e5a5
commit
3a6ace59a7
4 changed files with 47 additions and 48 deletions
|
@ -10,6 +10,7 @@ use once_cell::sync::{Lazy, OnceCell};
|
|||
use reflexo::path::PathClean;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{json, Map, Value as JsonValue};
|
||||
use task::FormatUserConfig;
|
||||
use tinymist_query::{get_semantic_tokens_options, PositionEncoding};
|
||||
use tinymist_render::PeriscopeArgs;
|
||||
use typst::foundations::IntoValue;
|
||||
|
@ -68,8 +69,8 @@ impl Initializer for RegularInit {
|
|||
/// Errors if the configuration could not be updated.
|
||||
fn initialize(mut self, params: InitializeParams) -> (LanguageState, AnySchedulableResponse) {
|
||||
// Initialize configurations
|
||||
let cc = ConstConfig::from(¶ms);
|
||||
let mut config = Config {
|
||||
const_config: ConstConfig::from(¶ms),
|
||||
compile: CompileConfig {
|
||||
roots: match params.workspace_folders.as_ref() {
|
||||
Some(roots) => roots
|
||||
|
@ -102,7 +103,6 @@ impl Initializer for RegularInit {
|
|||
client: self.client,
|
||||
exec_cmds: self.exec_cmds,
|
||||
config,
|
||||
cc,
|
||||
err,
|
||||
};
|
||||
|
||||
|
@ -118,8 +118,6 @@ pub struct SuperInit {
|
|||
pub exec_cmds: Vec<String>,
|
||||
/// The configuration for the server.
|
||||
pub config: Config,
|
||||
/// The constant configuration for the server.
|
||||
pub cc: ConstConfig,
|
||||
/// Whether an error occurred before super initialization.
|
||||
pub err: Option<ResponseError>,
|
||||
}
|
||||
|
@ -138,11 +136,11 @@ impl Initializer for SuperInit {
|
|||
client,
|
||||
exec_cmds,
|
||||
config,
|
||||
cc,
|
||||
err,
|
||||
} = self;
|
||||
let const_config = config.const_config.clone();
|
||||
// Bootstrap server
|
||||
let service = LanguageState::main(client, config, cc.clone(), err.is_none());
|
||||
let service = LanguageState::main(client, config, err.is_none());
|
||||
|
||||
if let Some(err) = err {
|
||||
return (service, Err(err));
|
||||
|
@ -152,14 +150,14 @@ impl Initializer for SuperInit {
|
|||
// Register these capabilities statically if the client does not support dynamic
|
||||
// registration
|
||||
let semantic_tokens_provider = match service.config.semantic_tokens {
|
||||
SemanticTokensMode::Enable if !cc.tokens_dynamic_registration => {
|
||||
SemanticTokensMode::Enable if !const_config.tokens_dynamic_registration => {
|
||||
Some(get_semantic_tokens_options().into())
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
let document_formatting_provider = match service.config.formatter {
|
||||
let document_formatting_provider = match service.config.formatter_mode {
|
||||
FormatterMode::Typstyle | FormatterMode::Typstfmt
|
||||
if !cc.doc_fmt_dynamic_registration =>
|
||||
if !const_config.doc_fmt_dynamic_registration =>
|
||||
{
|
||||
Some(OneOf::Left(true))
|
||||
}
|
||||
|
@ -272,14 +270,16 @@ const CONFIG_ITEMS: &[&str] = &[
|
|||
/// The user configuration read from the editor.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct Config {
|
||||
/// Constant configuration for the server.
|
||||
pub const_config: ConstConfig,
|
||||
/// The compile configurations
|
||||
pub compile: CompileConfig,
|
||||
/// Dynamic configuration for semantic tokens.
|
||||
pub semantic_tokens: SemanticTokensMode,
|
||||
/// Dynamic configuration for the experimental formatter.
|
||||
pub formatter: FormatterMode,
|
||||
pub formatter_mode: FormatterMode,
|
||||
/// Dynamic configuration for the experimental formatter.
|
||||
pub formatter_print_width: u32,
|
||||
pub formatter_print_width: Option<u32>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
|
@ -331,12 +331,21 @@ impl Config {
|
|||
try_(|| SemanticTokensMode::deserialize(update.get("semanticTokens")?).ok())
|
||||
.inspect(|v| self.semantic_tokens = *v);
|
||||
try_(|| FormatterMode::deserialize(update.get("formatterMode")?).ok())
|
||||
.inspect(|v| self.formatter = *v);
|
||||
.inspect(|v| self.formatter_mode = *v);
|
||||
try_(|| u32::deserialize(update.get("formatterPrintWidth")?).ok())
|
||||
.inspect(|v| self.formatter_print_width = *v);
|
||||
.inspect(|v| self.formatter_print_width = Some(*v));
|
||||
self.compile.update_by_map(update)?;
|
||||
self.compile.validate()
|
||||
}
|
||||
|
||||
/// Get the formatter configuration.
|
||||
pub fn formatter(&self) -> FormatUserConfig {
|
||||
FormatUserConfig {
|
||||
mode: self.formatter_mode,
|
||||
width: self.formatter_print_width.unwrap_or(120),
|
||||
position_encoding: self.const_config.position_encoding,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration set at initialization that won't change within a single
|
||||
|
@ -891,7 +900,7 @@ mod tests {
|
|||
assert_eq!(config.compile.export_pdf, ExportMode::OnSave);
|
||||
assert_eq!(config.compile.root_path, Some(PathBuf::from(root_path)));
|
||||
assert_eq!(config.semantic_tokens, SemanticTokensMode::Enable);
|
||||
assert_eq!(config.formatter, FormatterMode::Typstyle);
|
||||
assert_eq!(config.formatter_mode, FormatterMode::Typstyle);
|
||||
assert_eq!(
|
||||
config.compile.typst_extra_args,
|
||||
Some(CompileExtraOpts {
|
||||
|
@ -995,4 +1004,12 @@ mod tests {
|
|||
Some(PathBuf::from("/substitute/target/dir1/dir2/file.txt").into())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_formatting_config() {
|
||||
let config = Config::default().formatter();
|
||||
assert_eq!(config.mode, FormatterMode::Disable);
|
||||
assert_eq!(config.width, 120);
|
||||
assert_eq!(config.position_encoding, PositionEncoding::Utf16);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,7 @@ use lsp_server::RequestId;
|
|||
use once_cell::sync::Lazy;
|
||||
use serde_json::Value as JsonValue;
|
||||
use sync_lsp::{transport::with_stdio_transport, LspBuilder, LspClientRoot};
|
||||
use tinymist::{
|
||||
CompileConfig, Config, ConstConfig, LanguageState, LspWorld, RegularInit, SuperInit,
|
||||
};
|
||||
use tinymist::{CompileConfig, Config, LanguageState, LspWorld, RegularInit, SuperInit};
|
||||
use typst::World;
|
||||
use typst::{eval::Tracer, foundations::IntoValue, syntax::Span};
|
||||
use typst_ts_compiler::{CompileEnv, Compiler, TaskInputs};
|
||||
|
@ -134,7 +132,6 @@ pub fn trace_main(args: CompileArgs) -> anyhow::Result<()> {
|
|||
let client_root = LspClientRoot::new(RUNTIMES.tokio_runtime.handle().clone(), conn.sender);
|
||||
let client = client_root.weak();
|
||||
|
||||
let cc = ConstConfig::default();
|
||||
let config = Config {
|
||||
compile: CompileConfig {
|
||||
roots: vec![root_path],
|
||||
|
@ -149,7 +146,6 @@ pub fn trace_main(args: CompileArgs) -> anyhow::Result<()> {
|
|||
client: client.to_typed(),
|
||||
exec_cmds: Vec::new(),
|
||||
config,
|
||||
cc,
|
||||
err: None,
|
||||
},
|
||||
client.clone(),
|
||||
|
|
|
@ -71,9 +71,6 @@ pub struct LanguageState {
|
|||
// Configurations
|
||||
/// User configuration from the editor.
|
||||
pub config: Config,
|
||||
/// Const configuration initialized at the start of the session.
|
||||
/// For example, the position encoding.
|
||||
pub const_config: ConstConfig,
|
||||
|
||||
// Resources
|
||||
/// The semantic token context.
|
||||
|
@ -105,17 +102,17 @@ impl LanguageState {
|
|||
pub fn new(
|
||||
client: TypedLspClient<LanguageState>,
|
||||
config: Config,
|
||||
const_config: ConstConfig,
|
||||
editor_tx: mpsc::UnboundedSender<EditorRequest>,
|
||||
) -> Self {
|
||||
let const_config = &config.const_config;
|
||||
let tokens_ctx = SemanticTokenContext::new(
|
||||
const_config.position_encoding,
|
||||
const_config.tokens_overlapping_token_support,
|
||||
const_config.tokens_multiline_token_support,
|
||||
);
|
||||
let formatter = FormatTask::new(FormatUserConfig {
|
||||
mode: config.formatter,
|
||||
width: config.formatter_print_width,
|
||||
mode: config.formatter_mode,
|
||||
width: config.formatter_print_width.unwrap_or(120),
|
||||
position_encoding: const_config.position_encoding,
|
||||
});
|
||||
|
||||
|
@ -132,7 +129,6 @@ impl LanguageState {
|
|||
sema_tokens_registered: false,
|
||||
formatter_registered: false,
|
||||
config,
|
||||
const_config,
|
||||
|
||||
pinning: false,
|
||||
focusing: None,
|
||||
|
@ -144,19 +140,13 @@ impl LanguageState {
|
|||
}
|
||||
|
||||
/// The entry point for the language server.
|
||||
pub fn main(
|
||||
client: TypedLspClient<Self>,
|
||||
config: Config,
|
||||
cc: ConstConfig,
|
||||
start: bool,
|
||||
) -> Self {
|
||||
pub fn main(client: TypedLspClient<Self>, config: Config, start: bool) -> Self {
|
||||
info!("LanguageState: initialized with config {config:?}");
|
||||
info!("LanguageState: initialized with const_config {cc:?}");
|
||||
|
||||
// Bootstrap server
|
||||
let (editor_tx, editor_rx) = mpsc::unbounded_channel();
|
||||
|
||||
let mut service = LanguageState::new(client.clone(), config, cc.clone(), editor_tx);
|
||||
let mut service = LanguageState::new(client.clone(), config, editor_tx);
|
||||
|
||||
if start {
|
||||
let editor_actor = EditorActor::new(
|
||||
|
@ -176,7 +166,7 @@ impl LanguageState {
|
|||
|
||||
/// Get the const configuration.
|
||||
pub fn const_config(&self) -> &ConstConfig {
|
||||
&self.const_config
|
||||
&self.config.const_config
|
||||
}
|
||||
|
||||
/// Get the compile configuration.
|
||||
|
@ -398,7 +388,7 @@ impl LanguageState {
|
|||
}
|
||||
|
||||
if self.const_config().doc_fmt_dynamic_registration
|
||||
&& self.config.formatter != FormatterMode::Disable
|
||||
&& self.config.formatter_mode != FormatterMode::Disable
|
||||
{
|
||||
let err = self.enable_formatter_caps(true);
|
||||
if let Err(err) = err {
|
||||
|
@ -528,19 +518,15 @@ impl LanguageState {
|
|||
}
|
||||
}
|
||||
|
||||
if config.formatter != self.config.formatter
|
||||
|| config.formatter_print_width != self.config.formatter_print_width
|
||||
{
|
||||
let err = self.enable_formatter_caps(self.config.formatter != FormatterMode::Disable);
|
||||
let new_formatter_config = self.config.formatter();
|
||||
if config.formatter() != new_formatter_config {
|
||||
let err =
|
||||
self.enable_formatter_caps(new_formatter_config.mode != FormatterMode::Disable);
|
||||
if let Err(err) = err {
|
||||
error!("could not change formatter config: {err}");
|
||||
}
|
||||
|
||||
self.formatter.change_config(FormatUserConfig {
|
||||
mode: self.config.formatter,
|
||||
width: self.config.formatter_print_width,
|
||||
position_encoding: self.const_config.position_encoding,
|
||||
});
|
||||
self.formatter.change_config(new_formatter_config);
|
||||
}
|
||||
|
||||
info!("new settings applied");
|
||||
|
@ -682,7 +668,7 @@ impl LanguageState {
|
|||
req_id: RequestId,
|
||||
params: DocumentFormattingParams,
|
||||
) -> ScheduledResult {
|
||||
if matches!(self.config.formatter, FormatterMode::Disable) {
|
||||
if matches!(self.config.formatter_mode, FormatterMode::Disable) {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
|
@ -952,7 +938,7 @@ macro_rules! query_source {
|
|||
let path: ImmutPath = $req.path.clone().into();
|
||||
|
||||
$self.query_source(path, |source| {
|
||||
let enc = $self.const_config.position_encoding;
|
||||
let enc = $self.const_config().position_encoding;
|
||||
let res = $req.request(&source, enc);
|
||||
Ok(CompilerQueryResponse::$method(res))
|
||||
})
|
||||
|
|
|
@ -10,7 +10,7 @@ use typst::syntax::Source;
|
|||
use super::SyncTaskFactory;
|
||||
use crate::FormatterMode;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct FormatUserConfig {
|
||||
pub mode: FormatterMode,
|
||||
pub width: u32,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue