WIP
This commit is contained in:
parent
b7d30fca2b
commit
aa3fb28f81
9 changed files with 161 additions and 42 deletions
|
@ -406,24 +406,6 @@ impl AppContext {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
|
|
||||||
where
|
|
||||||
G: 'static + Send + Sync,
|
|
||||||
{
|
|
||||||
let mut global = self
|
|
||||||
.global_stacks_by_type
|
|
||||||
.get_mut(&TypeId::of::<G>())
|
|
||||||
.and_then(|stack| stack.pop())
|
|
||||||
.ok_or_else(|| anyhow!("no state of type {} exists", type_name::<G>()))
|
|
||||||
.unwrap();
|
|
||||||
let result = f(global.downcast_mut().unwrap(), self);
|
|
||||||
self.global_stacks_by_type
|
|
||||||
.get_mut(&TypeId::of::<G>())
|
|
||||||
.unwrap()
|
|
||||||
.push(global);
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn default_global<G: 'static + Default + Sync + Send>(&mut self) -> &mut G {
|
pub fn default_global<G: 'static + Default + Sync + Send>(&mut self) -> &mut G {
|
||||||
let stack = self
|
let stack = self
|
||||||
.global_stacks_by_type
|
.global_stacks_by_type
|
||||||
|
@ -448,18 +430,20 @@ impl AppContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn push_global<T: Send + Sync + 'static>(&mut self, state: T) {
|
pub(crate) fn push_global<T: Send + Sync + 'static>(&mut self, global: T) {
|
||||||
self.global_stacks_by_type
|
self.global_stacks_by_type
|
||||||
.entry(TypeId::of::<T>())
|
.entry(TypeId::of::<T>())
|
||||||
.or_default()
|
.or_default()
|
||||||
.push(Box::new(state));
|
.push(Box::new(global));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn pop_global<T: 'static>(&mut self) {
|
pub(crate) fn pop_global<T: 'static>(&mut self) -> Box<T> {
|
||||||
self.global_stacks_by_type
|
self.global_stacks_by_type
|
||||||
.get_mut(&TypeId::of::<T>())
|
.get_mut(&TypeId::of::<T>())
|
||||||
.and_then(|stack| stack.pop())
|
.and_then(|stack| stack.pop())
|
||||||
.expect("state stack underflow");
|
.expect("state stack underflow")
|
||||||
|
.downcast()
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn push_text_style(&mut self, text_style: TextStyleRefinement) {
|
pub(crate) fn push_text_style(&mut self, text_style: TextStyleRefinement) {
|
||||||
|
@ -497,6 +481,10 @@ impl Context for AppContext {
|
||||||
type EntityContext<'a, 'w, T: Send + Sync + 'static> = ModelContext<'a, T>;
|
type EntityContext<'a, 'w, T: Send + Sync + 'static> = ModelContext<'a, T>;
|
||||||
type Result<T> = T;
|
type Result<T> = T;
|
||||||
|
|
||||||
|
fn refresh(&mut self) {
|
||||||
|
self.push_effect(Effect::Refresh);
|
||||||
|
}
|
||||||
|
|
||||||
fn entity<T: Send + Sync + 'static>(
|
fn entity<T: Send + Sync + 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
||||||
|
@ -524,6 +512,24 @@ impl Context for AppContext {
|
||||||
fn read_global<G: 'static + Send + Sync, R>(&self, read: impl FnOnce(&G, &Self) -> R) -> R {
|
fn read_global<G: 'static + Send + Sync, R>(&self, read: impl FnOnce(&G, &Self) -> R) -> R {
|
||||||
read(self.global(), self)
|
read(self.global(), self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
|
||||||
|
where
|
||||||
|
G: 'static + Send + Sync,
|
||||||
|
{
|
||||||
|
let mut global = self
|
||||||
|
.global_stacks_by_type
|
||||||
|
.get_mut(&TypeId::of::<G>())
|
||||||
|
.and_then(|stack| stack.pop())
|
||||||
|
.ok_or_else(|| anyhow!("no state of type {} exists", type_name::<G>()))
|
||||||
|
.unwrap();
|
||||||
|
let result = f(global.downcast_mut().unwrap(), self);
|
||||||
|
self.global_stacks_by_type
|
||||||
|
.get_mut(&TypeId::of::<G>())
|
||||||
|
.unwrap()
|
||||||
|
.push(global);
|
||||||
|
result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MainThread<AppContext> {
|
impl MainThread<AppContext> {
|
||||||
|
|
|
@ -13,6 +13,16 @@ impl Context for AsyncAppContext {
|
||||||
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ModelContext<'a, T>;
|
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ModelContext<'a, T>;
|
||||||
type Result<T> = Result<T>;
|
type Result<T> = Result<T>;
|
||||||
|
|
||||||
|
fn refresh(&mut self) -> Self::Result<()> {
|
||||||
|
let app = self
|
||||||
|
.0
|
||||||
|
.upgrade()
|
||||||
|
.ok_or_else(|| anyhow!("app was released"))?;
|
||||||
|
let mut lock = app.lock(); // Need this to compile
|
||||||
|
lock.refresh();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn entity<T: Send + Sync + 'static>(
|
fn entity<T: Send + Sync + 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
||||||
|
@ -21,7 +31,7 @@ impl Context for AsyncAppContext {
|
||||||
.0
|
.0
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.ok_or_else(|| anyhow!("app was released"))?;
|
.ok_or_else(|| anyhow!("app was released"))?;
|
||||||
let mut lock = app.lock();
|
let mut lock = app.lock(); // Need this to compile
|
||||||
Ok(lock.entity(build_entity))
|
Ok(lock.entity(build_entity))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +44,7 @@ impl Context for AsyncAppContext {
|
||||||
.0
|
.0
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.ok_or_else(|| anyhow!("app was released"))?;
|
.ok_or_else(|| anyhow!("app was released"))?;
|
||||||
let mut lock = app.lock();
|
let mut lock = app.lock(); // Need this to compile
|
||||||
Ok(lock.update_entity(handle, update))
|
Ok(lock.update_entity(handle, update))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,9 +56,21 @@ impl Context for AsyncAppContext {
|
||||||
.0
|
.0
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.ok_or_else(|| anyhow!("app was released"))?;
|
.ok_or_else(|| anyhow!("app was released"))?;
|
||||||
let mut lock = app.lock();
|
let lock = app.lock(); // Need this to compile
|
||||||
Ok(lock.read_global(read))
|
Ok(lock.read_global(read))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_global<G: 'static + Send + Sync, R>(
|
||||||
|
&mut self,
|
||||||
|
update: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R,
|
||||||
|
) -> Self::Result<R> {
|
||||||
|
let app = self
|
||||||
|
.0
|
||||||
|
.upgrade()
|
||||||
|
.ok_or_else(|| anyhow!("app was released"))?;
|
||||||
|
let mut lock = app.lock(); // Need this to compile
|
||||||
|
Ok(lock.update_global(update))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsyncAppContext {
|
impl AsyncAppContext {
|
||||||
|
@ -106,6 +128,10 @@ impl Context for AsyncWindowContext {
|
||||||
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>;
|
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>;
|
||||||
type Result<T> = Result<T>;
|
type Result<T> = Result<T>;
|
||||||
|
|
||||||
|
fn refresh(&mut self) -> Self::Result<()> {
|
||||||
|
self.app.refresh()
|
||||||
|
}
|
||||||
|
|
||||||
fn entity<R: Send + Sync + 'static>(
|
fn entity<R: Send + Sync + 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, R>) -> R,
|
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, R>) -> R,
|
||||||
|
@ -129,4 +155,12 @@ impl Context for AsyncWindowContext {
|
||||||
) -> Result<R> {
|
) -> Result<R> {
|
||||||
self.app.read_window(self.window, |cx| cx.read_global(read))
|
self.app.read_window(self.window, |cx| cx.read_global(read))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_global<G: 'static + Send + Sync, R>(
|
||||||
|
&mut self,
|
||||||
|
update: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R,
|
||||||
|
) -> Result<R> {
|
||||||
|
self.app
|
||||||
|
.update_window(self.window, |cx| cx.update_global(update))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,6 +136,10 @@ impl<'a, T: 'static> Context for ModelContext<'a, T> {
|
||||||
type EntityContext<'b, 'c, U: Send + Sync + 'static> = ModelContext<'b, U>;
|
type EntityContext<'b, 'c, U: Send + Sync + 'static> = ModelContext<'b, U>;
|
||||||
type Result<U> = U;
|
type Result<U> = U;
|
||||||
|
|
||||||
|
fn refresh(&mut self) {
|
||||||
|
self.app.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
fn entity<U: Send + Sync + 'static>(
|
fn entity<U: Send + Sync + 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, U>) -> U,
|
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, U>) -> U,
|
||||||
|
@ -157,4 +161,14 @@ impl<'a, T: 'static> Context for ModelContext<'a, T> {
|
||||||
) -> R {
|
) -> R {
|
||||||
read(self.app.global(), self)
|
read(self.app.global(), self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
|
||||||
|
where
|
||||||
|
G: 'static + Send + Sync,
|
||||||
|
{
|
||||||
|
let mut global = self.app.pop_global::<G>();
|
||||||
|
let result = f(global.as_mut(), self);
|
||||||
|
self.app.push_global(global);
|
||||||
|
result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,11 @@ impl Executor {
|
||||||
Task::Spawned(task)
|
Task::Spawned(task)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn block<R>(&self, future: impl Future<Output = R>) -> R {
|
||||||
|
// todo!("integrate with deterministic dispatcher")
|
||||||
|
futures::executor::block_on(future)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_main_thread(&self) -> bool {
|
pub fn is_main_thread(&self) -> bool {
|
||||||
self.dispatcher.is_main_thread()
|
self.dispatcher.is_main_thread()
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,8 @@ pub trait Context {
|
||||||
type EntityContext<'a, 'w, T: 'static + Send + Sync>;
|
type EntityContext<'a, 'w, T: 'static + Send + Sync>;
|
||||||
type Result<T>;
|
type Result<T>;
|
||||||
|
|
||||||
|
fn refresh(&mut self) -> Self::Result<()>;
|
||||||
|
|
||||||
fn entity<T: Send + Sync + 'static>(
|
fn entity<T: Send + Sync + 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
||||||
|
@ -85,6 +87,13 @@ pub trait Context {
|
||||||
&self,
|
&self,
|
||||||
read: impl FnOnce(&G, &Self::BorrowedContext<'_, '_>) -> R,
|
read: impl FnOnce(&G, &Self::BorrowedContext<'_, '_>) -> R,
|
||||||
) -> Self::Result<R>;
|
) -> Self::Result<R>;
|
||||||
|
|
||||||
|
fn update_global<G, R>(
|
||||||
|
&mut self,
|
||||||
|
f: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R,
|
||||||
|
) -> Self::Result<R>
|
||||||
|
where
|
||||||
|
G: 'static + Send + Sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum GlobalKey {
|
pub enum GlobalKey {
|
||||||
|
@ -115,6 +124,10 @@ impl<C: Context> Context for MainThread<C> {
|
||||||
type EntityContext<'a, 'w, T: 'static + Send + Sync> = MainThread<C::EntityContext<'a, 'w, T>>;
|
type EntityContext<'a, 'w, T: 'static + Send + Sync> = MainThread<C::EntityContext<'a, 'w, T>>;
|
||||||
type Result<T> = C::Result<T>;
|
type Result<T> = C::Result<T>;
|
||||||
|
|
||||||
|
fn refresh(&mut self) -> Self::Result<()> {
|
||||||
|
self.0.refresh()
|
||||||
|
}
|
||||||
|
|
||||||
fn entity<T: Send + Sync + 'static>(
|
fn entity<T: Send + Sync + 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
||||||
|
@ -160,6 +173,21 @@ impl<C: Context> Context for MainThread<C> {
|
||||||
read(global, cx)
|
read(global, cx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_global<G: 'static + Send + Sync, R>(
|
||||||
|
&mut self,
|
||||||
|
update: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R,
|
||||||
|
) -> Self::Result<R> {
|
||||||
|
self.0.update_global(|global, cx| {
|
||||||
|
let cx = unsafe {
|
||||||
|
mem::transmute::<
|
||||||
|
&mut C::BorrowedContext<'_, '_>,
|
||||||
|
&mut MainThread<C::BorrowedContext<'_, '_>>,
|
||||||
|
>(cx)
|
||||||
|
};
|
||||||
|
update(global, cx)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait BorrowAppContext {
|
pub trait BorrowAppContext {
|
||||||
|
|
|
@ -1060,6 +1060,10 @@ impl Context for WindowContext<'_, '_> {
|
||||||
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>;
|
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>;
|
||||||
type Result<T> = T;
|
type Result<T> = T;
|
||||||
|
|
||||||
|
fn refresh(&mut self) {
|
||||||
|
self.app.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
fn entity<T: Send + Sync + 'static>(
|
fn entity<T: Send + Sync + 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
|
||||||
|
@ -1090,6 +1094,16 @@ impl Context for WindowContext<'_, '_> {
|
||||||
fn read_global<G: 'static + Send + Sync, R>(&self, read: impl FnOnce(&G, &Self) -> R) -> R {
|
fn read_global<G: 'static + Send + Sync, R>(&self, read: impl FnOnce(&G, &Self) -> R) -> R {
|
||||||
read(self.app.global(), self)
|
read(self.app.global(), self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
|
||||||
|
where
|
||||||
|
G: 'static + Send + Sync,
|
||||||
|
{
|
||||||
|
let mut global = self.app.pop_global::<G>();
|
||||||
|
let result = f(global.as_mut(), self);
|
||||||
|
self.app.push_global(global);
|
||||||
|
result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'w> std::ops::Deref for WindowContext<'a, 'w> {
|
impl<'a, 'w> std::ops::Deref for WindowContext<'a, 'w> {
|
||||||
|
@ -1540,6 +1554,10 @@ where
|
||||||
type EntityContext<'b, 'c, U: 'static + Send + Sync> = ViewContext<'b, 'c, U>;
|
type EntityContext<'b, 'c, U: 'static + Send + Sync> = ViewContext<'b, 'c, U>;
|
||||||
type Result<U> = U;
|
type Result<U> = U;
|
||||||
|
|
||||||
|
fn refresh(&mut self) {
|
||||||
|
self.app.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
fn entity<T2: Send + Sync + 'static>(
|
fn entity<T2: Send + Sync + 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T2>) -> T2,
|
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T2>) -> T2,
|
||||||
|
@ -1561,6 +1579,16 @@ where
|
||||||
) -> R {
|
) -> R {
|
||||||
read(self.global(), self)
|
read(self.global(), self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
|
||||||
|
where
|
||||||
|
G: 'static + Send + Sync,
|
||||||
|
{
|
||||||
|
let mut global = self.app.pop_global::<G>();
|
||||||
|
let result = f(global.as_mut(), self);
|
||||||
|
self.app.push_global(global);
|
||||||
|
result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'w, S: 'static> std::ops::Deref for ViewContext<'a, 'w, S> {
|
impl<'a, 'w, S: 'static> std::ops::Deref for ViewContext<'a, 'w, S> {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::{settings_store::SettingsStore, Setting};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use futures::{channel::mpsc, StreamExt};
|
use futures::{channel::mpsc, StreamExt};
|
||||||
use gpui2::{AppContext, Context};
|
use gpui2::{AppContext, Context, Executor};
|
||||||
use std::{
|
use std::{
|
||||||
io::ErrorKind,
|
io::ErrorKind,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
@ -48,7 +48,7 @@ pub fn test_settings() -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn watch_config_file(
|
pub fn watch_config_file(
|
||||||
executor: Arc<Background>,
|
executor: &Executor,
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
) -> mpsc::UnboundedReceiver<String> {
|
) -> mpsc::UnboundedReceiver<String> {
|
||||||
|
@ -83,7 +83,7 @@ pub fn handle_settings_file_changes(
|
||||||
mut user_settings_file_rx: mpsc::UnboundedReceiver<String>,
|
mut user_settings_file_rx: mpsc::UnboundedReceiver<String>,
|
||||||
cx: &mut AppContext,
|
cx: &mut AppContext,
|
||||||
) {
|
) {
|
||||||
let user_settings_content = cx.background().block(user_settings_file_rx.next()).unwrap();
|
let user_settings_content = cx.executor().block(user_settings_file_rx.next()).unwrap();
|
||||||
cx.update_global(|store: &mut SettingsStore, cx| {
|
cx.update_global(|store: &mut SettingsStore, cx| {
|
||||||
store
|
store
|
||||||
.set_user_settings(&user_settings_content, cx)
|
.set_user_settings(&user_settings_content, cx)
|
||||||
|
@ -91,14 +91,15 @@ pub fn handle_settings_file_changes(
|
||||||
});
|
});
|
||||||
cx.spawn(move |mut cx| async move {
|
cx.spawn(move |mut cx| async move {
|
||||||
while let Some(user_settings_content) = user_settings_file_rx.next().await {
|
while let Some(user_settings_content) = user_settings_file_rx.next().await {
|
||||||
cx.update(|cx| {
|
let result = cx.update_global(|store: &mut SettingsStore, cx| {
|
||||||
cx.update_global(|store: &mut SettingsStore, cx| {
|
store
|
||||||
store
|
.set_user_settings(&user_settings_content, cx)
|
||||||
.set_user_settings(&user_settings_content, cx)
|
.log_err();
|
||||||
.log_err();
|
cx.refresh();
|
||||||
});
|
|
||||||
cx.refresh_windows();
|
|
||||||
});
|
});
|
||||||
|
if result.is_err() {
|
||||||
|
break; // App dropped
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
|
@ -124,10 +125,10 @@ pub fn update_settings_file<T: Setting>(
|
||||||
update: impl 'static + Send + FnOnce(&mut T::FileContent),
|
update: impl 'static + Send + FnOnce(&mut T::FileContent),
|
||||||
) {
|
) {
|
||||||
cx.spawn(|cx| async move {
|
cx.spawn(|cx| async move {
|
||||||
let old_text = load_settings(&fs).await;
|
let old_text = load_settings(&fs).await?;
|
||||||
let new_text = cx.read_global(|store: &SettingsStore, cx| {
|
let new_text = cx.read_global(|store: &SettingsStore, _cx| {
|
||||||
store.new_text_for_update::<T>(old_text, update)
|
store.new_text_for_update::<T>(old_text, update)
|
||||||
});
|
})?;
|
||||||
fs.atomic_write(paths::SETTINGS.clone(), new_text).await?;
|
fs.atomic_write(paths::SETTINGS.clone(), new_text).await?;
|
||||||
anyhow::Ok(())
|
anyhow::Ok(())
|
||||||
})
|
})
|
||||||
|
|
|
@ -18,7 +18,7 @@ use util::{merge_non_null_json_value_into, RangeExt, ResultExt as _};
|
||||||
/// A value that can be defined as a user setting.
|
/// A value that can be defined as a user setting.
|
||||||
///
|
///
|
||||||
/// Settings can be loaded from a combination of multiple JSON files.
|
/// Settings can be loaded from a combination of multiple JSON files.
|
||||||
pub trait Setting: 'static {
|
pub trait Setting: 'static + Send + Sync {
|
||||||
/// The name of a key within the JSON file from which this setting should
|
/// The name of a key within the JSON file from which this setting should
|
||||||
/// be deserialized. If this is `None`, then the setting will be deserialized
|
/// be deserialized. If this is `None`, then the setting will be deserialized
|
||||||
/// from the root object.
|
/// from the root object.
|
||||||
|
@ -89,7 +89,10 @@ pub struct SettingsStore {
|
||||||
raw_default_settings: serde_json::Value,
|
raw_default_settings: serde_json::Value,
|
||||||
raw_user_settings: serde_json::Value,
|
raw_user_settings: serde_json::Value,
|
||||||
raw_local_settings: BTreeMap<(usize, Arc<Path>), serde_json::Value>,
|
raw_local_settings: BTreeMap<(usize, Arc<Path>), serde_json::Value>,
|
||||||
tab_size_callback: Option<(TypeId, Box<dyn Fn(&dyn Any) -> Option<usize>>)>,
|
tab_size_callback: Option<(
|
||||||
|
TypeId,
|
||||||
|
Box<dyn Fn(&dyn Any) -> Option<usize> + Send + Sync + 'static>,
|
||||||
|
)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SettingsStore {
|
impl Default for SettingsStore {
|
||||||
|
@ -110,7 +113,7 @@ struct SettingValue<T> {
|
||||||
local_values: Vec<(usize, Arc<Path>, T)>,
|
local_values: Vec<(usize, Arc<Path>, T)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
trait AnySettingValue {
|
trait AnySettingValue: 'static + Send + Sync {
|
||||||
fn key(&self) -> Option<&'static str>;
|
fn key(&self) -> Option<&'static str>;
|
||||||
fn setting_type_name(&self) -> &'static str;
|
fn setting_type_name(&self) -> &'static str;
|
||||||
fn deserialize_setting(&self, json: &serde_json::Value) -> Result<DeserializedSetting>;
|
fn deserialize_setting(&self, json: &serde_json::Value) -> Result<DeserializedSetting>;
|
||||||
|
|
|
@ -14,7 +14,7 @@ use log::LevelFilter;
|
||||||
|
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use settings::{default_settings, handle_settings_file_changes, watch_config_file, SettingsStore};
|
use settings2::{default_settings, handle_settings_file_changes, watch_config_file, SettingsStore};
|
||||||
use simplelog::ConfigBuilder;
|
use simplelog::ConfigBuilder;
|
||||||
use smol::process::Command;
|
use smol::process::Command;
|
||||||
use std::{
|
use std::{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue