From 3c73763b2e2b33692fc5acd84f4dca07e7c4f0b5 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Fri, 11 Oct 2024 21:37:21 +0800 Subject: [PATCH] The setting value should update when the settings file changes. (#3564) --- lapce-app/src/settings.rs | 210 +++++++++++++++++++++----------------- 1 file changed, 117 insertions(+), 93 deletions(-) diff --git a/lapce-app/src/settings.rs b/lapce-app/src/settings.rs index 392c8214..09f0e7c6 100644 --- a/lapce-app/src/settings.rs +++ b/lapce-app/src/settings.rs @@ -25,6 +25,7 @@ use lapce_rpc::plugin::VoltID; use lapce_xi_rope::Rope; use serde::Serialize; +use serde_json::Value; use crate::{ command::CommandExecuted, @@ -74,6 +75,7 @@ struct SettingsItem { description: String, filter_text: String, value: SettingsValue, + serde_value: Value, pos: RwSignal, size: RwSignal, // this is only the header that give an visual sepeartion between different type of settings @@ -82,8 +84,8 @@ struct SettingsItem { #[derive(Clone, Debug)] struct SettingsData { - items: im::Vector, - kinds: im::Vector<(String, RwSignal)>, + items: RwSignal>, + kinds: RwSignal)>>, plugin_items: RwSignal>, plugin_kinds: RwSignal)>>, filtered_items: RwSignal>, @@ -142,91 +144,104 @@ fn into_settings_map( } } - let config = common.config.get_untracked(); - let mut items = im::Vector::new(); - let mut kinds = im::Vector::new(); - let mut item_height_accum = 0.0; - - for (kind, fields, descs, mut settings_map) in [ - ( - "Core", - &CoreConfig::FIELDS[..], - &CoreConfig::DESCS[..], - into_settings_map(&config.core), - ), - ( - "Editor", - &EditorConfig::FIELDS[..], - &EditorConfig::DESCS[..], - into_settings_map(&config.editor), - ), - ( - "UI", - &UIConfig::FIELDS[..], - &UIConfig::DESCS[..], - into_settings_map(&config.ui), - ), - ( - "Terminal", - &TerminalConfig::FIELDS[..], - &TerminalConfig::DESCS[..], - into_settings_map(&config.terminal), - ), - ] { - let pos = cx.create_rw_signal(Point::new(0.0, item_height_accum)); - items.push_back(SettingsItem { - kind: kind.to_string(), - name: "".to_string(), - field: "".to_string(), - filter_text: "".to_string(), - description: "".to_string(), - value: SettingsValue::Empty, - pos, - size: cx.create_rw_signal(Size::ZERO), - header: true, - }); - kinds.push_back((kind.to_string(), pos)); - for (name, desc) in fields.iter().zip(descs.iter()) { - let field = name.replace('_', "-"); - - let value = if let Some(dropdown) = - config.get_dropdown_info(&kind.to_lowercase(), &field) - { - SettingsValue::Dropdown(dropdown) - } else { - let value = settings_map.remove(&field).unwrap(); - SettingsValue::from(value) - }; - - let name = - format!("{kind}: {}", name.replace('_', " ").to_title_case()); - let kind = kind.to_lowercase(); - let filter_text = format!("{kind} {name} {desc}").to_lowercase(); - let filter_text = - format!("{filter_text}{}", filter_text.replace(' ', "")); - items.push_back(SettingsItem { - kind, - name, - field, - filter_text, - description: desc.to_string(), - value, - pos: cx.create_rw_signal(Point::ZERO), - size: cx.create_rw_signal(Size::ZERO), - header: false, - }); - item_height_accum += 50.0; - } - } - + let config = common.config; let plugin_items = cx.create_rw_signal(im::Vector::new()); let plugin_kinds = cx.create_rw_signal(im::Vector::new()); - + let filtered_items = cx.create_rw_signal(im::Vector::new()); + let items = cx.create_rw_signal(im::Vector::new()); + let kinds = cx.create_rw_signal(im::Vector::new()); cx.create_effect(move |_| { - let mut item_height_accum = item_height_accum; + let config = config.get(); + + let mut data_items = im::Vector::new(); + let mut data_kinds = im::Vector::new(); + let mut item_height_accum = 0.0; + for (kind, fields, descs, mut settings_map) in [ + ( + "Core", + &CoreConfig::FIELDS[..], + &CoreConfig::DESCS[..], + into_settings_map(&config.core), + ), + ( + "Editor", + &EditorConfig::FIELDS[..], + &EditorConfig::DESCS[..], + into_settings_map(&config.editor), + ), + ( + "UI", + &UIConfig::FIELDS[..], + &UIConfig::DESCS[..], + into_settings_map(&config.ui), + ), + ( + "Terminal", + &TerminalConfig::FIELDS[..], + &TerminalConfig::DESCS[..], + into_settings_map(&config.terminal), + ), + ] { + let pos = cx.create_rw_signal(Point::new(0.0, item_height_accum)); + data_items.push_back(SettingsItem { + kind: kind.to_string(), + name: "".to_string(), + field: "".to_string(), + filter_text: "".to_string(), + description: "".to_string(), + value: SettingsValue::Empty, + serde_value: Value::Null, + pos, + size: cx.create_rw_signal(Size::ZERO), + header: true, + }); + data_kinds.push_back((kind.to_string(), pos)); + for (name, desc) in fields.iter().zip(descs.iter()) { + let field = name.replace('_', "-"); + + let (value, serde_value) = if let Some(dropdown) = + config.get_dropdown_info(&kind.to_lowercase(), &field) + { + let index = dropdown.active_index; + ( + SettingsValue::Dropdown(dropdown), + Value::Number(index.into()), + ) + } else { + let value = settings_map.remove(&field).unwrap(); + (SettingsValue::from(value.clone()), value) + }; + + let name = format!( + "{kind}: {}", + name.replace('_', " ").to_title_case() + ); + let kind = kind.to_lowercase(); + let filter_text = format!("{kind} {name} {desc}").to_lowercase(); + let filter_text = + format!("{filter_text}{}", filter_text.replace(' ', "")); + data_items.push_back(SettingsItem { + kind, + name, + field, + filter_text, + description: desc.to_string(), + value, + pos: cx.create_rw_signal(Point::ZERO), + size: cx.create_rw_signal(Size::ZERO), + serde_value, + header: false, + }); + item_height_accum += 50.0; + } + } + + filtered_items.set(data_items.clone()); + items.set(data_items); + let plugins = installed_plugin.get(); - let mut items = im::Vector::new(); - let mut kinds = im::Vector::new(); + let mut setting_items = im::Vector::new(); + let mut plugin_kinds_tmp = im::Vector::new(); for (_, volt) in plugins { let meta = volt.meta.get(); let kind = meta.name; @@ -234,18 +249,19 @@ fn into_settings_map( if let Some(config) = meta.config { let pos = cx.create_rw_signal(Point::new(0.0, item_height_accum)); - items.push_back(SettingsItem { + setting_items.push_back(SettingsItem { kind: meta.display_name.clone(), name: "".to_string(), field: "".to_string(), filter_text: "".to_string(), description: "".to_string(), value: SettingsValue::Empty, + serde_value: Value::Null, pos, size: cx.create_rw_signal(Size::ZERO), header: true, }); - kinds.push_back((meta.display_name.clone(), pos)); + plugin_kinds_tmp.push_back((meta.display_name.clone(), pos)); { let mut local_items = Vec::new(); @@ -279,22 +295,24 @@ fn into_settings_map( value, pos: cx.create_rw_signal(Point::ZERO), size: cx.create_rw_signal(Size::ZERO), + serde_value: Value::Null, header: false, }; local_items.push(item); item_height_accum += 50.0; } local_items.sort_by_key(|i| i.name.clone()); - items.extend(local_items.into_iter()); + setting_items.extend(local_items.into_iter()); } } } - plugin_items.set(items); - plugin_kinds.set(kinds); + plugin_items.set(setting_items); + plugin_kinds.set(plugin_kinds_tmp); + kinds.set(data_kinds); }); Self { - filtered_items: cx.create_rw_signal(items.clone()), + filtered_items, plugin_items, plugin_kinds, items, @@ -326,9 +344,8 @@ pub fn settings_view( let doc = doc.get(); let pattern = doc.buffer.with(|b| b.to_string().to_lowercase()); let plugin_items = settings_data.plugin_items.get(); - + let mut items = items.get(); if pattern.is_empty() { - let mut items = items.clone(); items.extend(plugin_items); filtered_items_signal.set(items); return; @@ -365,6 +382,7 @@ pub fn settings_view( } } + let kinds = kinds.get(); for (kind, pos) in kinds.iter().rev() { if pos.get_untracked().y < scroll_y { return kind.to_string(); @@ -416,7 +434,7 @@ pub fn settings_view( let switcher = || { stack(( dyn_stack( - move || kinds.clone(), + move || kinds.get().clone(), |(k, _)| k.clone(), move |(k, pos)| switcher_item(k, Box::new(move || Some(pos)), 0.0), ) @@ -488,7 +506,13 @@ pub fn settings_view( scroll({ dyn_stack( move || filtered_items_signal.get(), - |item| (item.kind.clone(), item.name.clone()), + |item| { + ( + item.kind.clone(), + item.name.clone(), + item.serde_value.clone(), + ) + }, move |item| { settings_item_view( editors,