fix: bad configuration initialization (#523)

This commit is contained in:
Myriad-Dreamin 2024-08-10 20:58:23 +08:00 committed by GitHub
parent 555da7e5a5
commit 3a6ace59a7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 47 additions and 48 deletions

View file

@ -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(&params);
let mut config = Config {
const_config: ConstConfig::from(&params),
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);
}
}

View file

@ -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(),

View file

@ -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))
})

View file

@ -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,