settings_file.rs

 1use crate::{settings_store::SettingsStore, Settings};
 2use fs::Fs;
 3use futures::{channel::mpsc, StreamExt};
 4use gpui::{App, BackgroundExecutor, ReadGlobal};
 5use std::{path::PathBuf, sync::Arc, time::Duration};
 6
 7pub const EMPTY_THEME_NAME: &str = "empty-theme";
 8
 9#[cfg(any(test, feature = "test-support"))]
10pub fn test_settings() -> String {
11    let mut value = crate::settings_store::parse_json_with_comments::<serde_json::Value>(
12        crate::default_settings().as_ref(),
13    )
14    .unwrap();
15    #[cfg(not(target_os = "windows"))]
16    util::merge_non_null_json_value_into(
17        serde_json::json!({
18            "ui_font_family": "Courier",
19            "ui_font_features": {},
20            "ui_font_size": 14,
21            "ui_font_fallback": [],
22            "buffer_font_family": "Courier",
23            "buffer_font_features": {},
24            "buffer_font_size": 14,
25            "buffer_font_fallback": [],
26            "theme": EMPTY_THEME_NAME,
27        }),
28        &mut value,
29    );
30    #[cfg(target_os = "windows")]
31    util::merge_non_null_json_value_into(
32        serde_json::json!({
33            "ui_font_family": "Courier New",
34            "ui_font_features": {},
35            "ui_font_size": 14,
36            "ui_font_fallback": [],
37            "buffer_font_family": "Courier New",
38            "buffer_font_features": {},
39            "buffer_font_size": 14,
40            "buffer_font_fallback": [],
41            "theme": EMPTY_THEME_NAME,
42        }),
43        &mut value,
44    );
45    value.as_object_mut().unwrap().remove("languages");
46    serde_json::to_string(&value).unwrap()
47}
48
49pub fn watch_config_file(
50    executor: &BackgroundExecutor,
51    fs: Arc<dyn Fs>,
52    path: PathBuf,
53) -> mpsc::UnboundedReceiver<String> {
54    let (tx, rx) = mpsc::unbounded();
55    executor
56        .spawn(async move {
57            let (events, _) = fs.watch(&path, Duration::from_millis(100)).await;
58            futures::pin_mut!(events);
59
60            let contents = fs.load(&path).await.unwrap_or_default();
61            if tx.unbounded_send(contents).is_err() {
62                return;
63            }
64
65            loop {
66                if events.next().await.is_none() {
67                    break;
68                }
69
70                if let Ok(contents) = fs.load(&path).await {
71                    if tx.unbounded_send(contents).is_err() {
72                        break;
73                    }
74                }
75            }
76        })
77        .detach();
78    rx
79}
80
81pub fn update_settings_file<T: Settings>(
82    fs: Arc<dyn Fs>,
83    cx: &App,
84    update: impl 'static + Send + FnOnce(&mut T::FileContent, &App),
85) {
86    SettingsStore::global(cx).update_settings_file::<T>(fs, update);
87}