@@ -147,7 +147,7 @@ impl App {
let cx = app.0.clone();
foreground_platform.on_menu_command(Box::new(move |command, arg| {
let mut cx = cx.borrow_mut();
- if let Some(key_window_id) = cx.platform.key_window_id() {
+ if let Some(key_window_id) = cx.cx.platform.key_window_id() {
if let Some((presenter, _)) = cx.presenters_and_platform_windows.get(&key_window_id)
{
let presenter = presenter.clone();
@@ -374,7 +374,7 @@ impl TestAppContext {
}
pub fn platform(&self) -> Arc<dyn platform::Platform> {
- self.cx.borrow().platform.clone()
+ self.cx.borrow().cx.platform.clone()
}
pub fn foreground(&self) -> Rc<executor::Foreground> {
@@ -566,7 +566,6 @@ type GlobalActionCallback = dyn FnMut(&dyn Any, &mut MutableAppContext);
pub struct MutableAppContext {
weak_self: Option<rc::Weak<RefCell<Self>>>,
foreground_platform: Rc<dyn platform::ForegroundPlatform>,
- platform: Arc<dyn platform::Platform>,
assets: Arc<AssetCache>,
cx: AppContext,
actions: HashMap<TypeId, HashMap<String, Vec<Box<ActionCallback>>>>,
@@ -598,7 +597,6 @@ impl MutableAppContext {
Self {
weak_self: None,
foreground_platform,
- platform,
assets: Arc::new(AssetCache::new(asset_source)),
cx: AppContext {
models: Default::default(),
@@ -608,6 +606,7 @@ impl MutableAppContext {
ref_counts: Arc::new(Mutex::new(RefCounts::default())),
background,
font_cache: Arc::new(FontCache::new(fonts)),
+ platform,
},
actions: HashMap::new(),
global_actions: HashMap::new(),
@@ -631,7 +630,7 @@ impl MutableAppContext {
}
pub fn platform(&self) -> Arc<dyn platform::Platform> {
- self.platform.clone()
+ self.cx.platform.clone()
}
pub fn font_cache(&self) -> &Arc<FontCache> {
@@ -992,7 +991,7 @@ impl MutableAppContext {
}
fn open_platform_window(&mut self, window_id: usize) {
- let mut window = self.platform.open_window(
+ let mut window = self.cx.platform.open_window(
window_id,
WindowOptions {
bounds: RectF::new(vec2f(0., 0.), vec2f(1024., 768.)),
@@ -1000,7 +999,7 @@ impl MutableAppContext {
},
self.foreground.clone(),
);
- let text_layout_cache = TextLayoutCache::new(self.platform.fonts());
+ let text_layout_cache = TextLayoutCache::new(self.cx.platform.fonts());
let presenter = Rc::new(RefCell::new(Presenter::new(
window_id,
self.cx.font_cache.clone(),
@@ -1387,11 +1386,11 @@ impl MutableAppContext {
}
pub fn write_to_clipboard(&self, item: ClipboardItem) {
- self.platform.write_to_clipboard(item);
+ self.cx.platform.write_to_clipboard(item);
}
pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
- self.platform.read_from_clipboard()
+ self.cx.platform.read_from_clipboard()
}
}
@@ -1485,6 +1484,7 @@ pub struct AppContext {
background: Arc<executor::Background>,
ref_counts: Arc<Mutex<RefCounts>>,
font_cache: Arc<FontCache>,
+ platform: Arc<dyn Platform>,
}
impl AppContext {
@@ -1524,10 +1524,14 @@ impl AppContext {
&self.background
}
- pub fn font_cache(&self) -> &FontCache {
+ pub fn font_cache(&self) -> &Arc<FontCache> {
&self.font_cache
}
+ pub fn platform(&self) -> &Arc<dyn Platform> {
+ &self.platform
+ }
+
pub fn value<Tag: 'static, T: 'static + Default>(&self, id: usize) -> ValueHandle<T> {
let key = (TypeId::of::<Tag>(), id);
let mut values = self.values.write();
@@ -25,7 +25,7 @@ pub mod json;
pub mod keymap;
mod platform;
pub use gpui_macros::test;
-pub use platform::{Event, PathPromptOptions, Platform, PromptLevel};
+pub use platform::{Event, FontSystem, PathPromptOptions, Platform, PromptLevel};
pub use presenter::{
AfterLayoutContext, Axis, DebugContext, EventContext, LayoutContext, PaintContext,
SizeConstraint, Vector2FExt,
@@ -1,9 +1,12 @@
+use std::sync::Arc;
+
use crate::{
editor::{display_map::fold_map, Point, TextSummary},
+ settings::Settings,
sum_tree::{self, SumTree},
util::Bias,
};
-use gpui::{AppContext, Task};
+use gpui::{font_cache::FamilyId, AppContext, FontCache, FontSystem, Task};
use parking_lot::Mutex;
use postage::{prelude::Sink, watch};
use smol::channel;
@@ -19,6 +22,12 @@ struct State {
interpolated_version: usize,
}
+pub struct Config {
+ pub wrap_width: f32,
+ pub font_family: FamilyId,
+ pub font_size: f32,
+}
+
pub struct WrapMap {
state: Mutex<State>,
edits_tx: channel::Sender<(fold_map::Snapshot, Vec<fold_map::Edit>)>,
@@ -27,7 +36,9 @@ pub struct WrapMap {
}
impl WrapMap {
- pub fn new(folds_snapshot: fold_map::Snapshot, cx: &AppContext) -> Self {
+ pub fn new(folds_snapshot: fold_map::Snapshot, config: Config, cx: &AppContext) -> Self {
+ let font_cache = cx.font_cache().clone();
+ let font_system = cx.platform().fonts();
let snapshot = Snapshot {
transforms: SumTree::from_item(
Transform {
@@ -45,8 +56,10 @@ impl WrapMap {
watch::channel_with(snapshot.clone());
let (edits_tx, edits_rx) = channel::unbounded();
let background_task = cx.background().spawn(async move {
- let mut wrapper = BackgroundWrapper::new(edits_rx, background_snapshots_tx);
- wrapper.run(folds_snapshot).await;
+ let mut wrapper = BackgroundWrapper::new(config, font_cache, font_system);
+ wrapper
+ .run(folds_snapshot, edits_rx, background_snapshots_tx)
+ .await;
});
Self {
@@ -68,19 +81,18 @@ impl WrapMap {
}
struct BackgroundWrapper {
- edits_rx: channel::Receiver<(fold_map::Snapshot, Vec<fold_map::Edit>)>,
- snapshots_tx: watch::Sender<Snapshot>,
+ config: Config,
+ font_cache: Arc<FontCache>,
+ font_system: Arc<dyn FontSystem>,
snapshot: Snapshot,
}
impl BackgroundWrapper {
- fn new(
- edits_rx: channel::Receiver<(fold_map::Snapshot, Vec<fold_map::Edit>)>,
- snapshots_tx: watch::Sender<Snapshot>,
- ) -> Self {
+ fn new(config: Config, font_cache: Arc<FontCache>, font_system: Arc<dyn FontSystem>) -> Self {
Self {
- edits_rx,
- snapshots_tx,
+ config,
+ font_cache,
+ font_system,
snapshot: Snapshot {
transforms: Default::default(),
version: Default::default(),
@@ -88,23 +100,30 @@ impl BackgroundWrapper {
}
}
- async fn run(&mut self, snapshot: fold_map::Snapshot) {
+ async fn run(
+ &mut self,
+ snapshot: fold_map::Snapshot,
+ edits_rx: channel::Receiver<(fold_map::Snapshot, Vec<fold_map::Edit>)>,
+ mut snapshots_tx: watch::Sender<Snapshot>,
+ ) {
let edit = fold_map::Edit {
old_bytes: 0..0,
new_bytes: 0..snapshot.len(),
};
- if !self.sync(snapshot, vec![edit]).await {
+ self.sync(snapshot, vec![edit]);
+ if snapshots_tx.send(self.snapshot.clone()).await.is_err() {
return;
}
- while let Ok((snapshot, edits)) = self.edits_rx.recv().await {
- if !self.sync(snapshot, edits).await {
+ while let Ok((snapshot, edits)) = edits_rx.recv().await {
+ self.sync(snapshot, edits);
+ if snapshots_tx.send(self.snapshot.clone()).await.is_err() {
break;
}
}
}
- async fn sync(&mut self, snapshot: fold_map::Snapshot, edits: Vec<fold_map::Edit>) -> bool {
+ fn sync(&mut self, snapshot: fold_map::Snapshot, edits: Vec<fold_map::Edit>) {
let mut new_transforms = SumTree::new();
{
// let mut old_cursor = self.snapshot.transforms.cursor::<Point, ()>();
@@ -118,7 +137,6 @@ impl BackgroundWrapper {
self.snapshot.transforms = new_transforms;
self.snapshot.version = snapshot.version;
- self.snapshots_tx.send(self.snapshot.clone()).await.is_ok()
}
}
@@ -156,3 +174,60 @@ impl<'a> sum_tree::Dimension<'a, TransformSummary> for Point {
*self += &summary.folded.lines;
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::editor::display_map::fold_map::FoldMap;
+ use crate::editor::{Buffer, ToPoint};
+ use crate::util::RandomCharIter;
+ use rand::prelude::*;
+ use std::env;
+ use Bias::{Left, Right};
+
+ #[gpui::test]
+ fn test_random_folds(cx: &mut gpui::MutableAppContext) {
+ let iterations = env::var("ITERATIONS")
+ .map(|i| i.parse().expect("invalid `ITERATIONS` variable"))
+ .unwrap_or(100);
+ let operations = env::var("OPERATIONS")
+ .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
+ .unwrap_or(10);
+ let seed_range = if let Ok(seed) = env::var("SEED") {
+ let seed = seed.parse().expect("invalid `SEED` variable");
+ seed..seed + 1
+ } else {
+ 0..iterations
+ };
+
+ for seed in seed_range {
+ dbg!(seed);
+ let mut rng = StdRng::seed_from_u64(seed);
+
+ let buffer = cx.add_model(|cx| {
+ let len = rng.gen_range(0..10);
+ let text = RandomCharIter::new(&mut rng).take(len).collect::<String>();
+ Buffer::new(0, text, cx)
+ });
+ let fold_map = FoldMap::new(buffer.clone(), cx.as_ref());
+ let (snapshot, _) = fold_map.read(cx.as_ref());
+ let font_cache = cx.font_cache().clone();
+ let font_system = cx.platform().fonts();
+ let config = Config {
+ wrap_width: rng.gen_range(100.0..=1000.0),
+ font_family: font_cache.load_family(&["Helvetica"]).unwrap(),
+ font_size: 14.0,
+ };
+ let mut wrapper = BackgroundWrapper::new(config, font_cache.clone(), font_system);
+ let edit = fold_map::Edit {
+ old_bytes: 0..0,
+ new_bytes: 0..snapshot.len(),
+ };
+ wrapper.sync(snapshot, vec![edit]);
+ // for line in wrapper.snapshot.text().lines() {
+ // font_cache.
+ // }
+ // assert_eq!(wrap_map.snapshot().text())
+ }
+ }
+}