feat: hot update editor actor config (#1584)

* feat: hot update editor actor config

* feat: apply update
This commit is contained in:
Myriad-Dreamin 2025-03-27 17:05:18 +08:00 committed by GitHub
parent 8c4bfe21c7
commit c33542739c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 46 additions and 9 deletions

View file

@ -13,8 +13,15 @@ use tokio::sync::mpsc;
use crate::project::ProjectInsId;
use crate::{tool::word_count::WordsCount, LspClient};
#[derive(Debug, Clone)]
pub struct EditorActorConfig {
/// Whether to notify status to the editor.
pub notify_status: bool,
}
/// The request to the editor actor.
pub enum EditorRequest {
Config(EditorActorConfig),
/// Publishes diagnostics to the editor.
Diag(ProjVersion, Option<DiagnosticsMap>),
/// Updates compile status to the editor.
@ -30,8 +37,8 @@ pub struct EditorActor {
client: LspClient,
/// The channel receiving the [`EditorRequest`].
editor_rx: mpsc::UnboundedReceiver<EditorRequest>,
/// Whether to notify compile status to the editor.
notify_compile_status: bool,
/// The configuration of the editor actor.
config: EditorActorConfig,
/// Accumulated diagnostics per file.
/// The outer `HashMap` is indexed by the file's URL.
@ -47,14 +54,14 @@ impl EditorActor {
pub fn new(
client: LspClient,
editor_rx: mpsc::UnboundedReceiver<EditorRequest>,
notify_compile_status: bool,
notify_status: bool,
) -> Self {
Self {
client,
editor_rx,
diagnostics: HashMap::new(),
affect_map: HashMap::new(),
notify_compile_status,
config: EditorActorConfig { notify_status },
}
}
@ -70,6 +77,10 @@ impl EditorActor {
while let Some(req) = self.editor_rx.recv().await {
match req {
EditorRequest::Config(config) => {
log::info!("received config request: {config:?}");
self.config = config;
}
EditorRequest::Diag(version, diagnostics) => {
log::debug!(
"received diagnostics from {version:?}: diag({:?})",
@ -79,16 +90,16 @@ impl EditorActor {
self.publish(version.id, diagnostics).await;
}
EditorRequest::Status(compile_status) => {
log::debug!("received status request: {compile_status:?}");
if self.notify_compile_status && compile_status.id == ProjectInsId::PRIMARY {
log::trace!("received status request: {compile_status:?}");
if self.config.notify_status && compile_status.id == ProjectInsId::PRIMARY {
status.status = compile_status.status;
status.path = compile_status.path;
self.client.send_notification::<StatusAll>(&status);
}
}
EditorRequest::WordCount(id, count) => {
log::debug!("received word count request");
if self.notify_compile_status && id == ProjectInsId::PRIMARY {
log::trace!("received word count request");
if self.config.notify_status && id == ProjectInsId::PRIMARY {
status.words_count = Some(count);
self.client.send_notification::<StatusAll>(&status);
}

View file

@ -68,7 +68,7 @@ pub struct Config {
pub customized_show_document: bool,
/// Whether the configuration can have a default entry path.
pub has_default_entry_path: bool,
/// Whether to notify the compile status to the editor.
/// Whether to notify the status to the editor.
pub notify_status: bool,
/// Whether to remove HTML from markup content in responses.
pub support_html_in_markdown: bool,
@ -908,6 +908,23 @@ mod tests {
assert_eq!(config.export_pdf, TaskWhen::OnType);
}
#[test]
fn test_compile_status() {
let mut config = Config::default();
let update = json!({
"compileStatus": "enable",
});
good_config(&mut config, &update);
assert!(config.notify_status);
let update = json!({
"compileStatus": "disable",
});
good_config(&mut config, &update);
assert!(!config.notify_status);
}
#[test]
fn test_config_creation_timestamp() {
type Timestamp = Option<i64>;

View file

@ -10,6 +10,7 @@ use tinymist_std::error::{prelude::*, IgnoreLogging};
pub mod init;
pub(crate) mod query;
use crate::actor::editor::{EditorActorConfig, EditorRequest};
use crate::task::FormatterConfig;
use crate::*;
@ -139,6 +140,14 @@ impl ServerState {
self.change_export_config(new_export_config);
}
if old_config.notify_status != self.config.notify_status {
self.editor_tx
.send(EditorRequest::Config(EditorActorConfig {
notify_status: self.config.notify_status,
}))
.log_error("could not change editor actor configuration");
}
if old_config.primary_opts() != self.config.primary_opts() {
self.config.fonts = OnceCell::new(); // todo: don't reload fonts if not changed
self.reload_projects()