diff --git a/gpui/src/app.rs b/gpui/src/app.rs index 9312d6b3f3480f6e78093625111d5553bc752139..96ed1ee2c02779ac7007e8f2d8ebf3b6c6c71b77 100644 --- a/gpui/src/app.rs +++ b/gpui/src/app.rs @@ -23,7 +23,7 @@ use std::{ fmt::{self, Debug}, hash::{Hash, Hasher}, marker::PhantomData, - ops::Deref, + ops::{Deref, DerefMut}, path::{Path, PathBuf}, rc::{self, Rc}, sync::{Arc, Weak}, @@ -2110,6 +2110,12 @@ impl Deref for ViewContext<'_, M> { } } +impl DerefMut for ViewContext<'_, M> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.app + } +} + impl AsMut for ViewContext<'_, M> { fn as_mut(&mut self) -> &mut MutableAppContext { self.app diff --git a/zed/src/editor.rs b/zed/src/editor.rs index cccad713ef69049d13bf3432b1c8464c473ea17e..f004828e1bc05105f2e50e359d9cbedcea424b89 100644 --- a/zed/src/editor.rs +++ b/zed/src/editor.rs @@ -4,7 +4,7 @@ mod element; pub mod movement; use crate::{ - settings::{Settings, StyleId}, + settings::{Settings, StyleId, Theme}, util::{post_inc, Bias}, workspace, worktree::{File, Worktree}, @@ -15,10 +15,10 @@ pub use display_map::DisplayPoint; use display_map::*; pub use element::*; use gpui::{ - color::ColorU, fonts::Properties as FontProperties, geometry::vector::Vector2F, - keymap::Binding, text_layout, AppContext, ClipboardItem, Element, ElementBox, Entity, - FontCache, ModelHandle, MutableAppContext, Task, TextLayoutCache, View, ViewContext, - WeakViewHandle, + color::ColorU, font_cache::FamilyId, fonts::Properties as FontProperties, + geometry::vector::Vector2F, keymap::Binding, text_layout, AppContext, ClipboardItem, Element, + ElementBox, Entity, FontCache, ModelHandle, MutableAppContext, Task, TextLayoutCache, View, + ViewContext, WeakViewHandle, }; use parking_lot::Mutex; use postage::{prelude::Stream, watch}; @@ -384,6 +384,15 @@ pub struct Editor { single_line: bool, } +struct Snapshot { + display_snapshot: DisplayMapSnapshot, + gutter_visible: bool, + scroll_position: Vector2F, + theme: Arc, + font_family: FamilyId, + font_size: f32, +} + struct AddSelectionsState { above: bool, stack: Vec, @@ -410,8 +419,7 @@ impl Editor { ) -> Self { cx.observe_model(&buffer, Self::on_buffer_changed); cx.subscribe_to_model(&buffer, Self::on_buffer_event); - let display_map = - DisplayMap::new(buffer.clone(), settings.borrow().clone(), None, cx.as_ref()); + let display_map = DisplayMap::new(buffer.clone(), settings.borrow().clone(), None, cx); let mut notifications = display_map.notifications(); cx.spawn(|this, mut cx| async move { @@ -458,8 +466,17 @@ impl Editor { &self.buffer } - pub fn is_gutter_visible(&self) -> bool { - !self.single_line + pub fn snapshot(&mut self, cx: &mut MutableAppContext) -> Snapshot { + let settings = self.settings.borrow(); + + Snapshot { + display_snapshot: self.display_map.snapshot(cx), + gutter_visible: !self.single_line, + scroll_position: *self.scroll_position.lock(), + theme: settings.theme.clone(), + font_family: settings.buffer_font_family, + font_size: settings.buffer_font_size, + } } fn scroll(&mut self, scroll_position: &Vector2F, cx: &mut ViewContext) { @@ -481,7 +498,7 @@ impl Editor { &self, viewport_height: f32, line_height: f32, - cx: &AppContext, + cx: &mut MutableAppContext, ) -> bool { let display_map = self.display_map.snapshot(cx); let mut scroll_position = self.scroll_position.lock(); @@ -541,7 +558,7 @@ impl Editor { scroll_width: f32, max_glyph_width: f32, layouts: &[text_layout::Line], - cx: &AppContext, + cx: &mut MutableAppContext, ) { let display_map = self.display_map.snapshot(cx); let mut target_left = std::f32::INFINITY; @@ -591,7 +608,7 @@ impl Editor { cx.emit(Event::Activate); } - let display_map = self.display_map.snapshot(cx.as_ref()); + let display_map = self.display_map.snapshot(cx); let cursor = display_map.anchor_before(position, Bias::Left); let selection = Selection { id: post_inc(&mut self.next_selection_id), @@ -616,7 +633,7 @@ impl Editor { cx: &mut ViewContext, ) { let buffer = self.buffer.read(cx); - let display_map = self.display_map.snapshot(cx.as_ref()); + let display_map = self.display_map.snapshot(cx); let cursor = display_map.anchor_before(position, Bias::Left); if let Some(selection) = self.pending_selection.as_mut() { selection.set_head(buffer, cursor); @@ -694,7 +711,7 @@ impl Editor { T: IntoIterator>, { let mut selections = Vec::new(); - let display_map = self.display_map.snapshot(cx.as_ref()); + let display_map = self.display_map.snapshot(cx); for range in ranges { let mut start = range.start; let mut end = range.end; @@ -769,7 +786,7 @@ impl Editor { pub fn backspace(&mut self, _: &(), cx: &mut ViewContext) { self.start_transaction(cx); let mut selections = self.selections(cx.as_ref()).to_vec(); - let display_map = self.display_map.snapshot(cx.as_ref()); + let display_map = self.display_map.snapshot(cx); { let buffer = self.buffer.read(cx); for selection in &mut selections { @@ -791,7 +808,7 @@ impl Editor { pub fn delete(&mut self, _: &(), cx: &mut ViewContext) { self.start_transaction(cx); - let display_map = self.display_map.snapshot(cx.as_ref()); + let display_map = self.display_map.snapshot(cx); let mut selections = self.selections(cx.as_ref()).to_vec(); { let buffer = self.buffer.read(cx); @@ -821,7 +838,7 @@ impl Editor { let mut new_cursors = Vec::new(); let mut edit_ranges = Vec::new(); - let display_map = self.display_map.snapshot(cx.as_ref()); + let display_map = self.display_map.snapshot(cx); let mut selections = self.selections(app).iter().peekable(); while let Some(selection) = selections.next() { let (mut rows, _) = selection.buffer_rows_for_display_rows(false, &display_map); @@ -902,7 +919,7 @@ impl Editor { self.update_selections(selections.clone(), false, cx); let buffer = self.buffer.read(cx); - let display_map = self.display_map.snapshot(cx.as_ref()); + let display_map = self.display_map.snapshot(cx); let mut edits = Vec::new(); let mut selections_iter = selections.iter_mut().peekable(); @@ -952,7 +969,7 @@ impl Editor { let app = cx.as_ref(); let buffer = self.buffer.read(cx); - let display_map = self.display_map.snapshot(cx.as_ref()); + let display_map = self.display_map.snapshot(cx); let mut edits = Vec::new(); let mut new_selection_ranges = Vec::new(); @@ -1037,7 +1054,7 @@ impl Editor { let app = cx.as_ref(); let buffer = self.buffer.read(cx); - let display_map = self.display_map.snapshot(cx.as_ref()); + let display_map = self.display_map.snapshot(cx); let mut edits = Vec::new(); let mut new_selection_ranges = Vec::new(); @@ -1250,8 +1267,8 @@ impl Editor { } pub fn move_left(&mut self, _: &(), cx: &mut ViewContext) { + let display_map = self.display_map.snapshot(cx); let app = cx.as_ref(); - let display_map = self.display_map.snapshot(app); let mut selections = self.selections(app).to_vec(); { for selection in &mut selections { @@ -1274,7 +1291,7 @@ impl Editor { } pub fn select_left(&mut self, _: &(), cx: &mut ViewContext) { - let display_map = self.display_map.snapshot(cx.as_ref()); + let display_map = self.display_map.snapshot(cx); let mut selections = self.selections(cx.as_ref()).to_vec(); { let buffer = self.buffer.read(cx); @@ -1290,7 +1307,7 @@ impl Editor { } pub fn move_right(&mut self, _: &(), cx: &mut ViewContext) { - let display_map = self.display_map.snapshot(cx.as_ref()); + let display_map = self.display_map.snapshot(cx); let mut selections = self.selections(cx.as_ref()).to_vec(); { for selection in &mut selections { @@ -1313,7 +1330,7 @@ impl Editor { } pub fn select_right(&mut self, _: &(), cx: &mut ViewContext) { - let display_map = self.display_map.snapshot(cx.as_ref()); + let display_map = self.display_map.snapshot(cx); let mut selections = self.selections(cx.as_ref()).to_vec(); { let app = cx.as_ref(); @@ -1330,7 +1347,7 @@ impl Editor { } pub fn move_up(&mut self, _: &(), cx: &mut ViewContext) { - let display_map = self.display_map.snapshot(cx.as_ref()); + let display_map = self.display_map.snapshot(cx); if self.single_line { cx.propagate_action(); } else { @@ -1356,7 +1373,7 @@ impl Editor { } pub fn select_up(&mut self, _: &(), cx: &mut ViewContext) { - let display_map = self.display_map.snapshot(cx.as_ref()); + let display_map = self.display_map.snapshot(cx); let mut selections = self.selections(cx.as_ref()).to_vec(); { let app = cx.as_ref(); @@ -1375,7 +1392,7 @@ impl Editor { if self.single_line { cx.propagate_action(); } else { - let display_map = self.display_map.snapshot(cx.as_ref()); + let display_map = self.display_map.snapshot(cx); let mut selections = self.selections(cx.as_ref()).to_vec(); { for selection in &mut selections { @@ -1398,8 +1415,8 @@ impl Editor { } pub fn select_down(&mut self, _: &(), cx: &mut ViewContext) { - let display_map = self.display_map.snapshot(cx.as_ref()); - let mut selections = self.selections(cx.as_ref()).to_vec(); + let display_map = self.display_map.snapshot(cx); + let mut selections = self.selections(cx).to_vec(); { let app = cx.as_ref(); let buffer = self.buffer.read(app); @@ -1414,9 +1431,8 @@ impl Editor { } pub fn move_to_previous_word_boundary(&mut self, _: &(), cx: &mut ViewContext) { - let app = cx.as_ref(); - let display_map = self.display_map.snapshot(app); - let mut selections = self.selections(app).to_vec(); + let display_map = self.display_map.snapshot(cx); + let mut selections = self.selections(cx).to_vec(); { for selection in &mut selections { let head = selection.head().to_display_point(&display_map); @@ -1432,9 +1448,8 @@ impl Editor { } pub fn select_to_previous_word_boundary(&mut self, _: &(), cx: &mut ViewContext) { - let app = cx.as_ref(); - let display_map = self.display_map.snapshot(app); - let mut selections = self.selections(app).to_vec(); + let display_map = self.display_map.snapshot(cx); + let mut selections = self.selections(cx).to_vec(); { let buffer = self.buffer.read(cx); for selection in &mut selections { @@ -1456,9 +1471,8 @@ impl Editor { } pub fn move_to_next_word_boundary(&mut self, _: &(), cx: &mut ViewContext) { - let app = cx.as_ref(); - let display_map = self.display_map.snapshot(app); - let mut selections = self.selections(app).to_vec(); + let display_map = self.display_map.snapshot(cx); + let mut selections = self.selections(cx).to_vec(); { for selection in &mut selections { let head = selection.head().to_display_point(&display_map); @@ -1474,9 +1488,8 @@ impl Editor { } pub fn select_to_next_word_boundary(&mut self, _: &(), cx: &mut ViewContext) { - let app = cx.as_ref(); - let display_map = self.display_map.snapshot(app); - let mut selections = self.selections(app).to_vec(); + let display_map = self.display_map.snapshot(cx); + let mut selections = self.selections(cx).to_vec(); { let buffer = self.buffer.read(cx); for selection in &mut selections { @@ -1498,9 +1511,8 @@ impl Editor { } pub fn move_to_beginning_of_line(&mut self, _: &(), cx: &mut ViewContext) { - let app = cx.as_ref(); - let display_map = self.display_map.snapshot(app); - let mut selections = self.selections(app).to_vec(); + let display_map = self.display_map.snapshot(cx); + let mut selections = self.selections(cx).to_vec(); { for selection in &mut selections { let head = selection.head().to_display_point(&display_map); @@ -1520,9 +1532,8 @@ impl Editor { toggle_indent: &bool, cx: &mut ViewContext, ) { - let app = cx.as_ref(); - let display_map = self.display_map.snapshot(app); - let mut selections = self.selections(app).to_vec(); + let display_map = self.display_map.snapshot(cx); + let mut selections = self.selections(cx).to_vec(); { let buffer = self.buffer.read(cx); for selection in &mut selections { @@ -1545,9 +1556,8 @@ impl Editor { } pub fn move_to_end_of_line(&mut self, _: &(), cx: &mut ViewContext) { - let app = cx.as_ref(); - let display_map = self.display_map.snapshot(app); - let mut selections = self.selections(app).to_vec(); + let display_map = self.display_map.snapshot(cx); + let mut selections = self.selections(cx).to_vec(); { for selection in &mut selections { let head = selection.head().to_display_point(&display_map); @@ -1563,9 +1573,8 @@ impl Editor { } pub fn select_to_end_of_line(&mut self, _: &(), cx: &mut ViewContext) { - let app = cx.as_ref(); - let display_map = self.display_map.snapshot(app); - let mut selections = self.selections(app).to_vec(); + let display_map = self.display_map.snapshot(cx); + let mut selections = self.selections(cx).to_vec(); { let buffer = self.buffer.read(cx); for selection in &mut selections { @@ -1643,10 +1652,9 @@ impl Editor { } pub fn select_line(&mut self, _: &(), cx: &mut ViewContext) { - let app = cx.as_ref(); - let buffer = self.buffer.read(app); - let display_map = self.display_map.snapshot(app); - let mut selections = self.selections(app).to_vec(); + let display_map = self.display_map.snapshot(cx); + let buffer = self.buffer.read(cx); + let mut selections = self.selections(cx).to_vec(); let max_point = buffer.max_point(); for selection in &mut selections { let (rows, _) = selection.buffer_rows_for_display_rows(true, &display_map); @@ -1706,9 +1714,8 @@ impl Editor { } fn add_selection(&mut self, above: bool, cx: &mut ViewContext) { - let app = cx.as_ref(); - let display_map = self.display_map.snapshot(app); - let mut selections = self.selections(app).to_vec(); + let display_map = self.display_map.snapshot(cx); + let mut selections = self.selections(cx).to_vec(); let mut state = self.add_selections_state.take().unwrap_or_else(|| { let oldest_selection = selections.iter().min_by_key(|s| s.id).unwrap().clone(); let range = oldest_selection.display_range(&display_map).sorted(); @@ -1800,13 +1807,12 @@ impl Editor { } pub fn select_larger_syntax_node(&mut self, _: &(), cx: &mut ViewContext) { - let app = cx.as_ref(); - let buffer = self.buffer.read(app); - let display_map = self.display_map.snapshot(app); + let display_map = self.display_map.snapshot(cx); + let buffer = self.buffer.read(cx); let mut stack = mem::take(&mut self.select_larger_syntax_node_stack); let mut selected_larger_node = false; - let old_selections = self.selections(app).to_vec(); + let old_selections = self.selections(cx).to_vec(); let mut new_selection_ranges = Vec::new(); for selection in &old_selections { let old_range = selection.start.to_offset(buffer)..selection.end.to_offset(buffer); @@ -1916,10 +1922,10 @@ impl Editor { &'a self, set_id: SelectionSetId, range: Range, - cx: &'a AppContext, + cx: &'a mut MutableAppContext, ) -> impl 'a + Iterator> { - let buffer = self.buffer.read(cx); let display_map = self.display_map.snapshot(cx); + let buffer = self.buffer.read(cx); let selections = &buffer.selection_set(set_id).unwrap().selections; let start = display_map.anchor_before(range.start, Bias::Left); let start_index = self.selection_insertion_index(selections, &start, cx); @@ -2042,9 +2048,8 @@ impl Editor { pub fn fold(&mut self, _: &(), cx: &mut ViewContext) { let mut fold_ranges = Vec::new(); - let app = cx.as_ref(); - let display_map = self.display_map.snapshot(app); - for selection in self.selections(app) { + let display_map = self.display_map.snapshot(cx); + for selection in self.selections(cx) { let range = selection.display_range(&display_map).sorted(); let buffer_start_row = range.start.to_buffer_point(&display_map, Bias::Left).row; @@ -2065,11 +2070,10 @@ impl Editor { } pub fn unfold(&mut self, _: &(), cx: &mut ViewContext) { - let app = cx.as_ref(); - let buffer = self.buffer.read(app); - let display_map = self.display_map.snapshot(app); + let display_map = self.display_map.snapshot(cx); + let buffer = self.buffer.read(cx); let ranges = self - .selections(app) + .selections(cx) .iter() .map(|s| { let range = s.display_range(&display_map).sorted(); @@ -2138,7 +2142,7 @@ impl Editor { fn fold_ranges(&mut self, ranges: Vec>, cx: &mut ViewContext) { if !ranges.is_empty() { - self.display_map.fold(ranges, cx.as_ref()); + self.display_map.fold(ranges, cx); *self.autoscroll_requested.lock() = true; cx.notify(); } @@ -2146,25 +2150,25 @@ impl Editor { fn unfold_ranges(&mut self, ranges: Vec>, cx: &mut ViewContext) { if !ranges.is_empty() { - self.display_map.unfold(ranges, cx.as_ref()); + self.display_map.unfold(ranges, cx); *self.autoscroll_requested.lock() = true; cx.notify(); } } - pub fn line_len(&self, display_row: u32, cx: &AppContext) -> u32 { + pub fn line_len(&self, display_row: u32, cx: &mut MutableAppContext) -> u32 { self.display_map.snapshot(cx).line_len(display_row) } - pub fn longest_row(&self, cx: &AppContext) -> u32 { + pub fn longest_row(&self, cx: &mut MutableAppContext) -> u32 { self.display_map.snapshot(cx).longest_row() } - pub fn max_point(&self, cx: &AppContext) -> DisplayPoint { + pub fn max_point(&self, cx: &mut MutableAppContext) -> DisplayPoint { self.display_map.snapshot(cx).max_point() } - pub fn text(&self, cx: &AppContext) -> String { + pub fn text(&self, cx: &mut MutableAppContext) -> String { self.display_map.snapshot(cx).text() } @@ -2172,34 +2176,104 @@ impl Editor { self.settings.borrow().buffer_font_size } + pub fn set_wrap_width(&self, width: f32, cx: &mut MutableAppContext) { + self.display_map.set_wrap_width(Some(width), cx); + } + + fn next_blink_epoch(&mut self) -> usize { + self.blink_epoch += 1; + self.blink_epoch + } + + fn pause_cursor_blinking(&mut self, cx: &mut ViewContext) { + self.cursors_visible = true; + cx.notify(); + + let epoch = self.next_blink_epoch(); + cx.spawn(|this, mut cx| { + let this = this.downgrade(); + async move { + Timer::after(CURSOR_BLINK_INTERVAL).await; + if let Some(this) = cx.read(|cx| this.upgrade(cx)) { + this.update(&mut cx, |this, cx| this.resume_cursor_blinking(epoch, cx)) + } + } + }) + .detach(); + } + + fn resume_cursor_blinking(&mut self, epoch: usize, cx: &mut ViewContext) { + if epoch == self.blink_epoch { + self.blinking_paused = false; + self.blink_cursors(epoch, cx); + } + } + + fn blink_cursors(&mut self, epoch: usize, cx: &mut ViewContext) { + if epoch == self.blink_epoch && self.focused && !self.blinking_paused { + self.cursors_visible = !self.cursors_visible; + cx.notify(); + + let epoch = self.next_blink_epoch(); + cx.spawn(|this, mut cx| { + let this = this.downgrade(); + async move { + Timer::after(CURSOR_BLINK_INTERVAL).await; + if let Some(this) = cx.read(|cx| this.upgrade(cx)) { + this.update(&mut cx, |this, cx| this.blink_cursors(epoch, cx)); + } + } + }) + .detach(); + } + } + + pub fn cursors_visible(&self) -> bool { + self.cursors_visible + } + + fn on_buffer_changed(&mut self, _: ModelHandle, cx: &mut ViewContext) { + cx.notify(); + } + + fn on_buffer_event( + &mut self, + _: ModelHandle, + event: &buffer::Event, + cx: &mut ViewContext, + ) { + match event { + buffer::Event::Edited => cx.emit(Event::Edited), + buffer::Event::Dirtied => cx.emit(Event::Dirtied), + buffer::Event::Saved => cx.emit(Event::Saved), + buffer::Event::FileHandleChanged => cx.emit(Event::FileHandleChanged), + buffer::Event::Reloaded => cx.emit(Event::FileHandleChanged), + buffer::Event::Reparsed => {} + } + } +} + +impl Snapshot { pub fn font_ascent(&self, font_cache: &FontCache) -> f32 { - let settings = self.settings.borrow(); - let font_id = font_cache.default_font(settings.buffer_font_family); + let font_id = font_cache.default_font(self.font_family); let ascent = font_cache.metric(font_id, |m| m.ascent); - font_cache.scale_metric(ascent, font_id, settings.buffer_font_size) + font_cache.scale_metric(ascent, font_id, self.font_size) } pub fn font_descent(&self, font_cache: &FontCache) -> f32 { - let settings = self.settings.borrow(); - let font_id = font_cache.default_font(settings.buffer_font_family); - let ascent = font_cache.metric(font_id, |m| m.descent); - font_cache.scale_metric(ascent, font_id, settings.buffer_font_size) + let font_id = font_cache.default_font(self.font_family); + let descent = font_cache.metric(font_id, |m| m.descent); + font_cache.scale_metric(descent, font_id, self.font_size) } pub fn line_height(&self, font_cache: &FontCache) -> f32 { - let settings = self.settings.borrow(); - let font_id = font_cache.default_font(settings.buffer_font_family); - font_cache.line_height(font_id, settings.buffer_font_size) + let font_id = font_cache.default_font(self.font_family); + font_cache.line_height(font_id, self.font_size) } pub fn em_width(&self, font_cache: &FontCache) -> f32 { - let settings = self.settings.borrow(); - let font_id = font_cache.default_font(settings.buffer_font_family); - font_cache.em_width(font_id, settings.buffer_font_size) - } - - pub fn set_wrap_width(&self, width: f32, cx: &AppContext) { - self.display_map.set_wrap_width(Some(width), cx); + let font_id = font_cache.default_font(self.font_family); + font_cache.em_width(font_id, self.font_size) } // TODO: Can we make this not return a result? @@ -2209,11 +2283,12 @@ impl Editor { layout_cache: &TextLayoutCache, cx: &AppContext, ) -> Result { - let settings = self.settings.borrow(); - let font_size = settings.buffer_font_size; - let font_id = - font_cache.select_font(settings.buffer_font_family, &FontProperties::new())?; - let digit_count = (self.buffer.read(cx).row_count() as f32).log10().floor() as usize + 1; + let font_size = self.font_size; + let font_id = font_cache.select_font(self.font_family, &FontProperties::new())?; + let digit_count = (self.display_snapshot.buffer_row_count() as f32) + .log10() + .floor() as usize + + 1; Ok(layout_cache .layout_str( @@ -2229,16 +2304,13 @@ impl Editor { viewport_height: f32, font_cache: &FontCache, layout_cache: &TextLayoutCache, - cx: &AppContext, + cx: &mut MutableAppContext, ) -> Result> { - let settings = self.settings.borrow(); - let font_size = settings.buffer_font_size; - let font_id = - font_cache.select_font(settings.buffer_font_family, &FontProperties::new())?; + let font_id = font_cache.select_font(self.font_family, &FontProperties::new())?; - let start_row = self.scroll_position().y() as usize; + let start_row = self.scroll_position.y() as usize; let end_row = cmp::min( - self.max_point(cx).row() as usize, + self.display_snapshot.max_point().row() as usize, start_row + (viewport_height / self.line_height(font_cache)).ceil() as usize, ); let line_count = end_row - start_row + 1; @@ -2246,8 +2318,7 @@ impl Editor { let mut layouts = Vec::with_capacity(line_count); let mut line_number = String::new(); for buffer_row in self - .display_map - .snapshot(cx) + .display_snapshot .buffer_rows(start_row as u32) .take(line_count) { @@ -2255,7 +2326,7 @@ impl Editor { write!(&mut line_number, "{}", buffer_row + 1).unwrap(); layouts.push(layout_cache.layout_str( &line_number, - font_size, + self.font_size, &[(line_number.len(), font_id, ColorU::black())], )); } @@ -2268,17 +2339,13 @@ impl Editor { mut rows: Range, font_cache: &FontCache, layout_cache: &TextLayoutCache, - cx: &AppContext, + cx: &mut MutableAppContext, ) -> Result> { - let mut display_map = self.display_map.snapshot(cx); - rows.end = cmp::min(rows.end, display_map.max_point().row() + 1); + rows.end = cmp::min(rows.end, self.display_snapshot.max_point().row() + 1); if rows.start >= rows.end { return Ok(Vec::new()); } - let settings = self.settings.borrow(); - let font_size = settings.buffer_font_size; - let font_family = settings.buffer_font_family; let mut prev_font_properties = FontProperties::new(); let mut prev_font_id = font_cache .select_font(font_family, &prev_font_properties) @@ -2288,13 +2355,14 @@ impl Editor { let mut line = String::new(); let mut styles = Vec::new(); let mut row = rows.start; - let chunks = display_map.highlighted_chunks_for_rows(rows.clone()); - let theme = settings.theme.clone(); + let chunks = self + .display_snapshot + .highlighted_chunks_for_rows(rows.clone()); 'outer: for (chunk, style_ix) in chunks.chain(Some(("\n", StyleId::default()))) { for (ix, line_chunk) in chunk.split('\n').enumerate() { if ix > 0 { - layouts.push(layout_cache.layout_str(&line, font_size, &styles)); + layouts.push(layout_cache.layout_str(&line, self.font_size, &styles)); line.clear(); styles.clear(); row += 1; @@ -2304,12 +2372,12 @@ impl Editor { } if !line_chunk.is_empty() { - let (color, font_properties) = theme.syntax_style(style_ix); + let (color, font_properties) = self.theme.syntax_style(style_ix); // Avoid a lookup if the font properties match the previous ones. let font_id = if font_properties == prev_font_properties { prev_font_id } else { - font_cache.select_font(font_family, &font_properties)? + font_cache.select_font(self.font_family, &font_properties)? }; line.push_str(line_chunk); styles.push((line_chunk.len(), font_id, color)); @@ -2327,93 +2395,22 @@ impl Editor { row: u32, font_cache: &FontCache, layout_cache: &TextLayoutCache, - cx: &AppContext, + cx: &mut MutableAppContext, ) -> Result { - let settings = self.settings.borrow(); - let display_map = self.display_map.snapshot(cx); - let font_id = - font_cache.select_font(settings.buffer_font_family, &FontProperties::new())?; + let font_id = font_cache.select_font(self.font_family, &FontProperties::new())?; - let line = display_map.line(row); + let line = self.display_snapshot.line(row); Ok(layout_cache.layout_str( &line, - settings.buffer_font_size, - &[(display_map.line_len(row) as usize, font_id, ColorU::black())], + self.font_size, + &[( + self.display_snapshot.line_len(row) as usize, + font_id, + ColorU::black(), + )], )) } - - fn next_blink_epoch(&mut self) -> usize { - self.blink_epoch += 1; - self.blink_epoch - } - - fn pause_cursor_blinking(&mut self, cx: &mut ViewContext) { - self.cursors_visible = true; - cx.notify(); - - let epoch = self.next_blink_epoch(); - cx.spawn(|this, mut cx| { - let this = this.downgrade(); - async move { - Timer::after(CURSOR_BLINK_INTERVAL).await; - if let Some(this) = cx.read(|cx| this.upgrade(cx)) { - this.update(&mut cx, |this, cx| this.resume_cursor_blinking(epoch, cx)) - } - } - }) - .detach(); - } - - fn resume_cursor_blinking(&mut self, epoch: usize, cx: &mut ViewContext) { - if epoch == self.blink_epoch { - self.blinking_paused = false; - self.blink_cursors(epoch, cx); - } - } - - fn blink_cursors(&mut self, epoch: usize, cx: &mut ViewContext) { - if epoch == self.blink_epoch && self.focused && !self.blinking_paused { - self.cursors_visible = !self.cursors_visible; - cx.notify(); - - let epoch = self.next_blink_epoch(); - cx.spawn(|this, mut cx| { - let this = this.downgrade(); - async move { - Timer::after(CURSOR_BLINK_INTERVAL).await; - if let Some(this) = cx.read(|cx| this.upgrade(cx)) { - this.update(&mut cx, |this, cx| this.blink_cursors(epoch, cx)); - } - } - }) - .detach(); - } - } - - pub fn cursors_visible(&self) -> bool { - self.cursors_visible - } - - fn on_buffer_changed(&mut self, _: ModelHandle, cx: &mut ViewContext) { - cx.notify(); - } - - fn on_buffer_event( - &mut self, - _: ModelHandle, - event: &buffer::Event, - cx: &mut ViewContext, - ) { - match event { - buffer::Event::Edited => cx.emit(Event::Edited), - buffer::Event::Dirtied => cx.emit(Event::Dirtied), - buffer::Event::Saved => cx.emit(Event::Saved), - buffer::Event::FileHandleChanged => cx.emit(Event::FileHandleChanged), - buffer::Event::Reloaded => cx.emit(Event::FileHandleChanged), - buffer::Event::Reparsed => {} - } - } } pub enum Event { @@ -2571,7 +2568,7 @@ mod tests { let view = buffer_view.read(cx); assert_eq!( - view.selection_ranges(cx.as_ref()), + view.selection_ranges(cx), [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)] ); @@ -2581,7 +2578,7 @@ mod tests { let view = buffer_view.read(cx); assert_eq!( - view.selection_ranges(cx.as_ref()), + view.selection_ranges(cx), [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)] ); @@ -2591,7 +2588,7 @@ mod tests { let view = buffer_view.read(cx); assert_eq!( - view.selection_ranges(cx.as_ref()), + view.selection_ranges(cx), [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)] ); @@ -2602,7 +2599,7 @@ mod tests { let view = buffer_view.read(cx); assert_eq!( - view.selection_ranges(cx.as_ref()), + view.selection_ranges(cx), [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)] ); @@ -2613,7 +2610,7 @@ mod tests { let view = buffer_view.read(cx); assert_eq!( - view.selection_ranges(cx.as_ref()), + view.selection_ranges(cx), [ DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1), DisplayPoint::new(3, 3)..DisplayPoint::new(0, 0) @@ -2626,7 +2623,7 @@ mod tests { let view = buffer_view.read(cx); assert_eq!( - view.selection_ranges(cx.as_ref()), + view.selection_ranges(cx), [DisplayPoint::new(3, 3)..DisplayPoint::new(0, 0)] ); } @@ -2641,7 +2638,7 @@ mod tests { view.begin_selection(DisplayPoint::new(2, 2), false, cx); }); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)] ); @@ -2649,7 +2646,7 @@ mod tests { view.update_selection(DisplayPoint::new(3, 3), Vector2F::zero(), cx); }); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)] ); @@ -2658,7 +2655,7 @@ mod tests { view.update_selection(DisplayPoint::new(1, 1), Vector2F::zero(), cx); }); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)] ); } @@ -2679,7 +2676,7 @@ mod tests { view.end_selection(cx); }); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), [ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3), DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1), @@ -2688,13 +2685,13 @@ mod tests { view.update(cx, |view, cx| view.cancel(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), [DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1)] ); view.update(cx, |view, cx| view.cancel(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), [DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1)] ); } @@ -2711,7 +2708,7 @@ mod tests { let layouts = view .read(cx) - .layout_line_numbers(1000.0, &font_cache, &layout_cache, cx.as_ref()) + .layout_line_numbers(1000.0, &font_cache, &layout_cache, cx) .unwrap(); assert_eq!(layouts.len(), 6); } @@ -2750,7 +2747,7 @@ mod tests { .unwrap(); view.fold(&(), cx); assert_eq!( - view.text(cx.as_ref()), + view.text(cx), " impl Foo { // Hello! @@ -2771,7 +2768,7 @@ mod tests { view.fold(&(), cx); assert_eq!( - view.text(cx.as_ref()), + view.text(cx), " impl Foo {… } @@ -2781,7 +2778,7 @@ mod tests { view.unfold(&(), cx); assert_eq!( - view.text(cx.as_ref()), + view.text(cx), " impl Foo { // Hello! @@ -2801,7 +2798,7 @@ mod tests { ); view.unfold(&(), cx); - assert_eq!(view.text(cx.as_ref()), buffer.read(cx).text()); + assert_eq!(view.text(cx), buffer.read(cx).text()); }); } @@ -2824,43 +2821,43 @@ mod tests { view.update(cx, |view, cx| { assert_eq!( - view.selection_ranges(cx.as_ref()), + view.selection_ranges(cx), &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)] ); view.move_down(&(), cx); assert_eq!( - view.selection_ranges(cx.as_ref()), + view.selection_ranges(cx), &[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)] ); view.move_right(&(), cx); assert_eq!( - view.selection_ranges(cx.as_ref()), + view.selection_ranges(cx), &[DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4)] ); view.move_left(&(), cx); assert_eq!( - view.selection_ranges(cx.as_ref()), + view.selection_ranges(cx), &[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)] ); view.move_up(&(), cx); assert_eq!( - view.selection_ranges(cx.as_ref()), + view.selection_ranges(cx), &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)] ); view.move_to_end(&(), cx); assert_eq!( - view.selection_ranges(cx.as_ref()), + view.selection_ranges(cx), &[DisplayPoint::new(5, 6)..DisplayPoint::new(5, 6)] ); view.move_to_beginning(&(), cx); assert_eq!( - view.selection_ranges(cx.as_ref()), + view.selection_ranges(cx), &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)] ); @@ -2868,13 +2865,13 @@ mod tests { .unwrap(); view.select_to_beginning(&(), cx); assert_eq!( - view.selection_ranges(cx.as_ref()), + view.selection_ranges(cx), &[DisplayPoint::new(0, 1)..DisplayPoint::new(0, 0)] ); view.select_to_end(&(), cx); assert_eq!( - view.selection_ranges(cx.as_ref()), + view.selection_ranges(cx), &[DisplayPoint::new(0, 1)..DisplayPoint::new(5, 6)] ); }); @@ -2898,86 +2895,41 @@ mod tests { ], cx, ); - assert_eq!(view.text(cx.as_ref()), "ⓐⓑ…ⓔ\nab…e\nαβ…ε\n"); + assert_eq!(view.text(cx), "ⓐⓑ…ⓔ\nab…e\nαβ…ε\n"); view.move_right(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(0, "ⓐ".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐ".len())]); view.move_right(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(0, "ⓐⓑ".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐⓑ".len())]); view.move_right(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(0, "ⓐⓑ…".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐⓑ…".len())]); view.move_down(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(1, "ab…".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(1, "ab…".len())]); view.move_left(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(1, "ab".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(1, "ab".len())]); view.move_left(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(1, "a".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(1, "a".len())]); view.move_down(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(2, "α".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(2, "α".len())]); view.move_right(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(2, "αβ".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(2, "αβ".len())]); view.move_right(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(2, "αβ…".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(2, "αβ…".len())]); view.move_right(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(2, "αβ…ε".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(2, "αβ…ε".len())]); view.move_up(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(1, "ab…e".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(1, "ab…e".len())]); view.move_up(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(0, "ⓐⓑ…ⓔ".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐⓑ…ⓔ".len())]); view.move_left(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(0, "ⓐⓑ…".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐⓑ…".len())]); view.move_left(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(0, "ⓐⓑ".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐⓑ".len())]); view.move_left(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(0, "ⓐ".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(0, "ⓐ".len())]); }); } @@ -2991,40 +2943,22 @@ mod tests { .unwrap(); view.move_down(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(1, "abcd".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(1, "abcd".len())]); view.move_down(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(2, "αβγ".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(2, "αβγ".len())]); view.move_down(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(3, "abcd".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(3, "abcd".len())]); view.move_down(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(4, "ⓐⓑⓒⓓⓔ".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(4, "ⓐⓑⓒⓓⓔ".len())]); view.move_up(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(3, "abcd".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(3, "abcd".len())]); view.move_up(&(), cx); - assert_eq!( - view.selection_ranges(cx.as_ref()), - &[empty_range(2, "αβγ".len())] - ); + assert_eq!(view.selection_ranges(cx), &[empty_range(2, "αβγ".len())]); }); } @@ -3046,7 +2980,7 @@ mod tests { view.update(cx, |view, cx| view.move_to_beginning_of_line(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2), @@ -3055,7 +2989,7 @@ mod tests { view.update(cx, |view, cx| view.move_to_beginning_of_line(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0), @@ -3064,7 +2998,7 @@ mod tests { view.update(cx, |view, cx| view.move_to_beginning_of_line(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2), @@ -3073,7 +3007,7 @@ mod tests { view.update(cx, |view, cx| view.move_to_end_of_line(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5), @@ -3083,7 +3017,7 @@ mod tests { // Moving to the end of line again is a no-op. view.update(cx, |view, cx| view.move_to_end_of_line(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5), @@ -3095,7 +3029,7 @@ mod tests { view.select_to_beginning_of_line(&true, cx); }); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 2), @@ -3104,7 +3038,7 @@ mod tests { view.update(cx, |view, cx| view.select_to_beginning_of_line(&true, cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 0), @@ -3113,7 +3047,7 @@ mod tests { view.update(cx, |view, cx| view.select_to_beginning_of_line(&true, cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 2), @@ -3122,7 +3056,7 @@ mod tests { view.update(cx, |view, cx| view.select_to_end_of_line(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 5), @@ -3130,9 +3064,9 @@ mod tests { ); view.update(cx, |view, cx| view.delete_to_end_of_line(&(), cx)); - assert_eq!(view.read(cx).text(cx.as_ref()), "ab\n de"); + assert_eq!(view.read(cx).text(cx), "ab\n de"); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4), @@ -3140,9 +3074,9 @@ mod tests { ); view.update(cx, |view, cx| view.delete_to_beginning_of_line(&(), cx)); - assert_eq!(view.read(cx).text(cx.as_ref()), "\n"); + assert_eq!(view.read(cx).text(cx), "\n"); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0), @@ -3169,7 +3103,7 @@ mod tests { view.update(cx, |view, cx| view.move_to_previous_word_boundary(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 9)..DisplayPoint::new(0, 9), DisplayPoint::new(2, 3)..DisplayPoint::new(2, 3), @@ -3178,7 +3112,7 @@ mod tests { view.update(cx, |view, cx| view.move_to_previous_word_boundary(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 7)..DisplayPoint::new(0, 7), DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2), @@ -3187,7 +3121,7 @@ mod tests { view.update(cx, |view, cx| view.move_to_previous_word_boundary(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 4)..DisplayPoint::new(0, 4), DisplayPoint::new(2, 0)..DisplayPoint::new(2, 0), @@ -3196,7 +3130,7 @@ mod tests { view.update(cx, |view, cx| view.move_to_previous_word_boundary(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0), @@ -3205,7 +3139,7 @@ mod tests { view.update(cx, |view, cx| view.move_to_previous_word_boundary(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(0, 24)..DisplayPoint::new(0, 24), @@ -3214,7 +3148,7 @@ mod tests { view.update(cx, |view, cx| view.move_to_previous_word_boundary(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(0, 23)..DisplayPoint::new(0, 23), @@ -3223,7 +3157,7 @@ mod tests { view.update(cx, |view, cx| view.move_to_next_word_boundary(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(0, 24)..DisplayPoint::new(0, 24), @@ -3232,7 +3166,7 @@ mod tests { view.update(cx, |view, cx| view.move_to_next_word_boundary(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 4)..DisplayPoint::new(0, 4), DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0), @@ -3241,7 +3175,7 @@ mod tests { view.update(cx, |view, cx| view.move_to_next_word_boundary(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 7)..DisplayPoint::new(0, 7), DisplayPoint::new(2, 0)..DisplayPoint::new(2, 0), @@ -3250,7 +3184,7 @@ mod tests { view.update(cx, |view, cx| view.move_to_next_word_boundary(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 9)..DisplayPoint::new(0, 9), DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2), @@ -3262,7 +3196,7 @@ mod tests { view.select_to_previous_word_boundary(&(), cx); }); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 10)..DisplayPoint::new(0, 9), DisplayPoint::new(2, 3)..DisplayPoint::new(2, 2), @@ -3273,7 +3207,7 @@ mod tests { view.select_to_previous_word_boundary(&(), cx) }); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 10)..DisplayPoint::new(0, 7), DisplayPoint::new(2, 3)..DisplayPoint::new(2, 0), @@ -3282,7 +3216,7 @@ mod tests { view.update(cx, |view, cx| view.select_to_next_word_boundary(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 10)..DisplayPoint::new(0, 9), DisplayPoint::new(2, 3)..DisplayPoint::new(2, 2), @@ -3291,11 +3225,11 @@ mod tests { view.update(cx, |view, cx| view.delete_to_next_word_boundary(&(), cx)); assert_eq!( - view.read(cx).text(cx.as_ref()), + view.read(cx).text(cx), "use std::s::{foo, bar}\n\n {az.qux()}" ); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 10)..DisplayPoint::new(0, 10), DisplayPoint::new(2, 3)..DisplayPoint::new(2, 3), @@ -3306,11 +3240,11 @@ mod tests { view.delete_to_previous_word_boundary(&(), cx) }); assert_eq!( - view.read(cx).text(cx.as_ref()), + view.read(cx).text(cx), "use std::::{foo, bar}\n\n az.qux()}" ); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 9)..DisplayPoint::new(0, 9), DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2), @@ -3403,9 +3337,9 @@ mod tests { .unwrap(); view.delete_line(&(), cx); }); - assert_eq!(view.read(cx).text(cx.as_ref()), "ghi"); + assert_eq!(view.read(cx).text(cx), "ghi"); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0), DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1) @@ -3420,9 +3354,9 @@ mod tests { .unwrap(); view.delete_line(&(), cx); }); - assert_eq!(view.read(cx).text(cx.as_ref()), "ghi\n"); + assert_eq!(view.read(cx).text(cx), "ghi\n"); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)] ); } @@ -3445,12 +3379,9 @@ mod tests { .unwrap(); view.duplicate_line(&(), cx); }); + assert_eq!(view.read(cx).text(cx), "abc\nabc\ndef\ndef\nghi\n\n"); assert_eq!( - view.read(cx).text(cx.as_ref()), - "abc\nabc\ndef\ndef\nghi\n\n" - ); - assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(1, 0)..DisplayPoint::new(1, 1), DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2), @@ -3473,12 +3404,9 @@ mod tests { .unwrap(); view.duplicate_line(&(), cx); }); + assert_eq!(view.read(cx).text(cx), "abc\ndef\nghi\nabc\ndef\nghi\n"); assert_eq!( - view.read(cx).text(cx.as_ref()), - "abc\ndef\nghi\nabc\ndef\nghi\n" - ); - assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(3, 1)..DisplayPoint::new(4, 1), DisplayPoint::new(4, 2)..DisplayPoint::new(5, 1), @@ -3512,17 +3440,17 @@ mod tests { .unwrap(); }); assert_eq!( - view.read(cx).text(cx.as_ref()), + view.read(cx).text(cx), "aa…bbb\nccc…eeee\nfffff\nggggg\n…i\njjjjj" ); view.update(cx, |view, cx| view.move_line_up(&(), cx)); assert_eq!( - view.read(cx).text(cx.as_ref()), + view.read(cx).text(cx), "aa…bbb\nccc…eeee\nggggg\n…i\njjjjj\nfffff" ); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1), @@ -3533,11 +3461,11 @@ mod tests { view.update(cx, |view, cx| view.move_line_down(&(), cx)); assert_eq!( - view.read(cx).text(cx.as_ref()), + view.read(cx).text(cx), "ccc…eeee\naa…bbb\nfffff\nggggg\n…i\njjjjj" ); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1), DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1), @@ -3548,11 +3476,11 @@ mod tests { view.update(cx, |view, cx| view.move_line_down(&(), cx)); assert_eq!( - view.read(cx).text(cx.as_ref()), + view.read(cx).text(cx), "ccc…eeee\nfffff\naa…bbb\nggggg\n…i\njjjjj" ); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1), DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1), @@ -3563,11 +3491,11 @@ mod tests { view.update(cx, |view, cx| view.move_line_up(&(), cx)); assert_eq!( - view.read(cx).text(cx.as_ref()), + view.read(cx).text(cx), "ccc…eeee\naa…bbb\nggggg\n…i\njjjjj\nfffff" ); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1), DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1), @@ -3590,19 +3518,16 @@ mod tests { view.select_ranges(vec![0..4, 8..14, 19..24], false, cx); view.cut(&(), cx); }); - assert_eq!(view.read(cx).text(cx.as_ref()), "two four six "); + assert_eq!(view.read(cx).text(cx), "two four six "); // Paste with three cursors. Each cursor pastes one slice of the clipboard text. view.update(cx, |view, cx| { view.select_ranges(vec![4..4, 9..9, 13..13], false, cx); view.paste(&(), cx); }); + assert_eq!(view.read(cx).text(cx), "two one four three six five "); assert_eq!( - view.read(cx).text(cx.as_ref()), - "two one four three six five " - ); - assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 8)..DisplayPoint::new(0, 8), DisplayPoint::new(0, 19)..DisplayPoint::new(0, 19), @@ -3620,7 +3545,7 @@ mod tests { view.insert(&") ".to_string(), cx); }); assert_eq!( - view.read(cx).text(cx.as_ref()), + view.read(cx).text(cx), "( one three five ) two one four three six five ( one three five ) " ); @@ -3629,7 +3554,7 @@ mod tests { view.insert(&"123\n4567\n89\n".to_string(), cx); }); assert_eq!( - view.read(cx).text(cx.as_ref()), + view.read(cx).text(cx), "123\n4567\n89\n( one three five ) two one four three six five ( one three five ) " ); @@ -3647,7 +3572,7 @@ mod tests { view.cut(&(), cx); }); assert_eq!( - view.read(cx).text(cx.as_ref()), + view.read(cx).text(cx), "13\n9\n( one three five ) two one four three six five ( one three five ) " ); @@ -3666,11 +3591,11 @@ mod tests { view.paste(&(), cx); }); assert_eq!( - view.read(cx).text(cx.as_ref()), + view.read(cx).text(cx), "123\n4567\n9\n( 8ne three five ) two one four three six five ( one three five ) " ); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1), @@ -3700,11 +3625,11 @@ mod tests { view.paste(&(), cx); }); assert_eq!( - view.read(cx).text(cx.as_ref()), + view.read(cx).text(cx), "123\n123\n123\n67\n123\n9\n( 8ne three five ) two one four three six five ( one three five ) " ); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1), DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0), @@ -3720,7 +3645,7 @@ mod tests { let (_, view) = cx.add_window(|cx| Editor::for_buffer(buffer, settings, cx)); view.update(cx, |b, cx| b.select_all(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), &[DisplayPoint::new(0, 0)..DisplayPoint::new(2, 3)] ); } @@ -3744,7 +3669,7 @@ mod tests { view.select_line(&(), cx); }); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(0, 0)..DisplayPoint::new(2, 0), DisplayPoint::new(4, 0)..DisplayPoint::new(5, 0), @@ -3753,7 +3678,7 @@ mod tests { view.update(cx, |view, cx| view.select_line(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(0, 0)..DisplayPoint::new(3, 0), DisplayPoint::new(4, 0)..DisplayPoint::new(5, 5), @@ -3762,7 +3687,7 @@ mod tests { view.update(cx, |view, cx| view.select_line(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![DisplayPoint::new(0, 0)..DisplayPoint::new(5, 5)] ); } @@ -3792,18 +3717,12 @@ mod tests { ) .unwrap(); }); - assert_eq!( - view.read(cx).text(cx.as_ref()), - "aa…bbb\nccc…eeee\nfffff\nggggg\n…i" - ); + assert_eq!(view.read(cx).text(cx), "aa…bbb\nccc…eeee\nfffff\nggggg\n…i"); view.update(cx, |view, cx| view.split_selection_into_lines(&(), cx)); + assert_eq!(view.read(cx).text(cx), "aa…bbb\nccc…eeee\nfffff\nggggg\n…i"); assert_eq!( - view.read(cx).text(cx.as_ref()), - "aa…bbb\nccc…eeee\nfffff\nggggg\n…i" - ); - assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), [ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), @@ -3818,11 +3737,11 @@ mod tests { view.split_selection_into_lines(&(), cx); }); assert_eq!( - view.read(cx).text(cx.as_ref()), + view.read(cx).text(cx), "aaaaa\nbbbbb\nccccc\nddddd\neeeee\nfffff\nggggg\n…i" ); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), [ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5), @@ -3848,7 +3767,7 @@ mod tests { }); view.update(cx, |view, cx| view.add_selection_above(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3) @@ -3857,7 +3776,7 @@ mod tests { view.update(cx, |view, cx| view.add_selection_above(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3) @@ -3866,13 +3785,13 @@ mod tests { view.update(cx, |view, cx| view.add_selection_below(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)] ); view.update(cx, |view, cx| view.add_selection_below(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3), DisplayPoint::new(4, 3)..DisplayPoint::new(4, 3) @@ -3881,7 +3800,7 @@ mod tests { view.update(cx, |view, cx| view.add_selection_below(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3), DisplayPoint::new(4, 3)..DisplayPoint::new(4, 3) @@ -3894,7 +3813,7 @@ mod tests { }); view.update(cx, |view, cx| view.add_selection_below(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3), DisplayPoint::new(4, 4)..DisplayPoint::new(4, 3) @@ -3903,7 +3822,7 @@ mod tests { view.update(cx, |view, cx| view.add_selection_below(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3), DisplayPoint::new(4, 4)..DisplayPoint::new(4, 3) @@ -3912,13 +3831,13 @@ mod tests { view.update(cx, |view, cx| view.add_selection_above(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3)] ); view.update(cx, |view, cx| view.add_selection_above(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![DisplayPoint::new(1, 4)..DisplayPoint::new(1, 3)] ); @@ -3928,7 +3847,7 @@ mod tests { }); view.update(cx, |view, cx| view.add_selection_below(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 1)..DisplayPoint::new(1, 4), @@ -3938,7 +3857,7 @@ mod tests { view.update(cx, |view, cx| view.add_selection_below(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 1)..DisplayPoint::new(1, 4), @@ -3949,7 +3868,7 @@ mod tests { view.update(cx, |view, cx| view.add_selection_above(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3), DisplayPoint::new(1, 1)..DisplayPoint::new(1, 4), @@ -3963,7 +3882,7 @@ mod tests { }); view.update(cx, |view, cx| view.add_selection_above(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(0, 3)..DisplayPoint::new(0, 1), DisplayPoint::new(1, 3)..DisplayPoint::new(1, 1), @@ -3974,7 +3893,7 @@ mod tests { view.update(cx, |view, cx| view.add_selection_below(&(), cx)); assert_eq!( - view.read(cx).selection_ranges(cx.as_ref()), + view.update(cx, |view, cx| view.selection_ranges(cx)), vec![ DisplayPoint::new(1, 3)..DisplayPoint::new(1, 1), DisplayPoint::new(3, 2)..DisplayPoint::new(3, 1), @@ -4017,7 +3936,7 @@ mod tests { view.select_larger_syntax_node(&(), cx); }); assert_eq!( - view.read_with(&cx, |view, cx| view.selection_ranges(cx)), + view.update(&mut cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 23)..DisplayPoint::new(0, 27), DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7), @@ -4029,7 +3948,7 @@ mod tests { view.select_larger_syntax_node(&(), cx); }); assert_eq!( - view.read_with(&cx, |view, cx| view.selection_ranges(cx)), + view.update(&mut cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28), DisplayPoint::new(4, 1)..DisplayPoint::new(2, 0), @@ -4040,7 +3959,7 @@ mod tests { view.select_larger_syntax_node(&(), cx); }); assert_eq!( - view.read_with(&cx, |view, cx| view.selection_ranges(cx)), + view.update(&mut cx, |view, cx| view.selection_ranges(cx)), &[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 0)] ); @@ -4049,7 +3968,7 @@ mod tests { view.select_larger_syntax_node(&(), cx); }); assert_eq!( - view.read_with(&cx, |view, cx| view.selection_ranges(cx)), + view.update(&mut cx, |view, cx| view.selection_ranges(cx)), &[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 0)] ); @@ -4057,7 +3976,7 @@ mod tests { view.select_smaller_syntax_node(&(), cx); }); assert_eq!( - view.read_with(&cx, |view, cx| view.selection_ranges(cx)), + view.update(&mut cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28), DisplayPoint::new(4, 1)..DisplayPoint::new(2, 0), @@ -4068,7 +3987,7 @@ mod tests { view.select_smaller_syntax_node(&(), cx); }); assert_eq!( - view.read_with(&cx, |view, cx| view.selection_ranges(cx)), + view.update(&mut cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 23)..DisplayPoint::new(0, 27), DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7), @@ -4080,7 +3999,7 @@ mod tests { view.select_smaller_syntax_node(&(), cx); }); assert_eq!( - view.read_with(&cx, |view, cx| view.selection_ranges(cx)), + view.update(&mut cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25), DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12), @@ -4093,7 +4012,7 @@ mod tests { view.select_smaller_syntax_node(&(), cx); }); assert_eq!( - view.read_with(&cx, |view, cx| view.selection_ranges(cx)), + view.update(&mut cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25), DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12), @@ -4114,7 +4033,7 @@ mod tests { view.select_larger_syntax_node(&(), cx); }); assert_eq!( - view.read_with(&cx, |view, cx| view.selection_ranges(cx)), + view.update(&mut cx, |view, cx| view.selection_ranges(cx)), &[ DisplayPoint::new(0, 16)..DisplayPoint::new(0, 28), DisplayPoint::new(2, 35)..DisplayPoint::new(2, 7), @@ -4124,7 +4043,7 @@ mod tests { } impl Editor { - fn selection_ranges(&self, cx: &AppContext) -> Vec> { + fn selection_ranges(&self, cx: &mut MutableAppContext) -> Vec> { self.selections_in_range( self.selection_set_id, DisplayPoint::zero()..self.max_point(cx), diff --git a/zed/src/editor/display_map.rs b/zed/src/editor/display_map.rs index 6e33f4c4152a0fcbc2f2bc84bc0e217e5b7f4947..8004bb7b1850fbccf62cbb854f8908cb03165795 100644 --- a/zed/src/editor/display_map.rs +++ b/zed/src/editor/display_map.rs @@ -5,7 +5,7 @@ mod wrap_map; use super::{buffer, Anchor, Bias, Buffer, Point, Settings, ToOffset, ToPoint}; use fold_map::FoldMap; -use gpui::{AppContext, ModelHandle}; +use gpui::{ModelHandle, MutableAppContext}; use postage::prelude::Stream; use std::ops::Range; use tab_map::TabMap; @@ -24,7 +24,7 @@ impl DisplayMap { buffer: ModelHandle, settings: Settings, wrap_width: Option, - cx: &AppContext, + cx: &mut MutableAppContext, ) -> Self { let (fold_map, snapshot) = FoldMap::new(buffer.clone(), cx); let (tab_map, snapshot) = TabMap::new(snapshot, settings.tab_size); @@ -37,7 +37,7 @@ impl DisplayMap { } } - pub fn snapshot(&self, cx: &AppContext) -> DisplayMapSnapshot { + pub fn snapshot(&self, cx: &mut MutableAppContext) -> DisplayMapSnapshot { let (folds_snapshot, edits) = self.fold_map.read(cx); let (tabs_snapshot, edits) = self.tab_map.sync(folds_snapshot.clone(), edits); let wraps_snapshot = self.wrap_map.sync(tabs_snapshot.clone(), edits, cx); @@ -52,7 +52,7 @@ impl DisplayMap { pub fn fold( &mut self, ranges: impl IntoIterator>, - cx: &AppContext, + cx: &mut MutableAppContext, ) { let (mut fold_map, snapshot, edits) = self.fold_map.write(cx); let (snapshot, edits) = self.tab_map.sync(snapshot, edits); @@ -65,7 +65,7 @@ impl DisplayMap { pub fn unfold( &mut self, ranges: impl IntoIterator>, - cx: &AppContext, + cx: &mut MutableAppContext, ) { let (mut fold_map, snapshot, edits) = self.fold_map.write(cx); let (snapshot, edits) = self.tab_map.sync(snapshot, edits); @@ -75,7 +75,7 @@ impl DisplayMap { self.wrap_map.sync(snapshot, edits, cx); } - pub fn set_wrap_width(&self, width: Option, cx: &AppContext) { + pub fn set_wrap_width(&self, width: Option, cx: &mut MutableAppContext) { self.wrap_map.set_wrap_width(width, cx); } @@ -96,6 +96,10 @@ impl DisplayMapSnapshot { self.wraps_snapshot.buffer_rows(start_row) } + pub fn buffer_row_count(&self) -> u32 { + self.buffer_snapshot.max_point().row + 1 + } + pub fn max_point(&self) -> DisplayPoint { DisplayPoint(self.wraps_snapshot.max_point()) } @@ -317,11 +321,11 @@ mod tests { Buffer::new(0, text, cx) }); let wrap_width = Some(rng.gen_range(20.0..=100.0)); - let map = cx.read(|cx| DisplayMap::new(buffer.clone(), settings, wrap_width, cx)); + let map = cx.update(|cx| DisplayMap::new(buffer.clone(), settings, wrap_width, cx)); for _op_ix in 0..operations { buffer.update(&mut cx, |buffer, cx| buffer.randomly_mutate(&mut rng, cx)); - let snapshot = cx.read(|cx| map.snapshot(cx)); + let snapshot = cx.update(|cx| map.snapshot(cx)); let expected_buffer_rows = (0..=snapshot.max_point().row()) .map(|display_row| { DisplayPoint::new(display_row, 0) @@ -362,9 +366,9 @@ mod tests { let text = "one two three four five\nsix seven eight"; let buffer = cx.add_model(|cx| Buffer::new(0, text.to_string(), cx)); - let map = cx.read(|cx| DisplayMap::new(buffer.clone(), settings, wrap_width, cx)); + let map = cx.update(|cx| DisplayMap::new(buffer.clone(), settings, wrap_width, cx)); - let snapshot = cx.read(|cx| map.snapshot(cx)); + let snapshot = cx.update(|cx| map.snapshot(cx)); assert_eq!( snapshot .chunks_at(DisplayPoint::new(0, 3)) @@ -385,7 +389,7 @@ mod tests { buffer.edit(vec![ix..ix], "and ", cx); }); - let snapshot = cx.read(|cx| map.snapshot(cx)); + let snapshot = cx.update(|cx| map.snapshot(cx)); assert_eq!( snapshot .chunks_at(DisplayPoint::new(1, 0)) @@ -402,7 +406,7 @@ mod tests { buffer.clone(), Settings::new(cx.font_cache()).unwrap().with_tab_size(4), None, - cx.as_ref(), + cx, ); buffer.update(cx, |buffer, cx| { buffer.edit( @@ -417,19 +421,19 @@ mod tests { }); assert_eq!( - &map.snapshot(cx.as_ref()) + &map.snapshot(cx) .chunks_at(DisplayPoint::new(1, 0)) .collect::()[0..10], " b bb" ); assert_eq!( - &map.snapshot(cx.as_ref()) + &map.snapshot(cx) .chunks_at(DisplayPoint::new(1, 2)) .collect::()[0..10], " b bbbb" ); assert_eq!( - &map.snapshot(cx.as_ref()) + &map.snapshot(cx) .chunks_at(DisplayPoint::new(1, 6)) .collect::()[0..13], " bbbbb\nc c" @@ -480,7 +484,7 @@ mod tests { }); buffer.condition(&cx, |buf, _| !buf.is_parsing()).await; - let mut map = cx.read(|cx| { + let mut map = cx.update(|cx| { DisplayMap::new( buffer, Settings::new(cx.font_cache()).unwrap().with_tab_size(2), @@ -489,7 +493,7 @@ mod tests { ) }); assert_eq!( - cx.read(|cx| highlighted_chunks(0..5, &map, &theme, cx)), + cx.update(|cx| highlighted_chunks(0..5, &map, &theme, cx)), vec![ ("fn ".to_string(), None), ("outer".to_string(), Some("fn.name")), @@ -500,7 +504,7 @@ mod tests { ] ); assert_eq!( - cx.read(|cx| highlighted_chunks(3..5, &map, &theme, cx)), + cx.update(|cx| highlighted_chunks(3..5, &map, &theme, cx)), vec![ (" fn ".to_string(), Some("mod.body")), ("inner".to_string(), Some("fn.name")), @@ -508,9 +512,9 @@ mod tests { ] ); - cx.read(|cx| map.fold(vec![Point::new(0, 6)..Point::new(3, 2)], cx)); + cx.update(|cx| map.fold(vec![Point::new(0, 6)..Point::new(3, 2)], cx)); assert_eq!( - cx.read(|cx| highlighted_chunks(0..2, &map, &theme, cx)), + cx.update(|cx| highlighted_chunks(0..2, &map, &theme, cx)), vec![ ("fn ".to_string(), None), ("out".to_string(), Some("fn.name")), @@ -575,9 +579,9 @@ mod tests { buffer_font_size: 16.0, ..Settings::new(&font_cache).unwrap() }; - let mut map = cx.read(|cx| DisplayMap::new(buffer, settings, Some(40.0), cx)); + let mut map = cx.update(|cx| DisplayMap::new(buffer, settings, Some(40.0), cx)); assert_eq!( - cx.read(|cx| highlighted_chunks(0..5, &map, &theme, cx)), + cx.update(|cx| highlighted_chunks(0..5, &map, &theme, cx)), [ ("fn \n".to_string(), None), ("oute\nr".to_string(), Some("fn.name")), @@ -585,13 +589,13 @@ mod tests { ] ); assert_eq!( - cx.read(|cx| highlighted_chunks(3..5, &map, &theme, cx)), + cx.update(|cx| highlighted_chunks(3..5, &map, &theme, cx)), [("{}\n\n".to_string(), None)] ); - cx.read(|cx| map.fold(vec![Point::new(0, 6)..Point::new(3, 2)], cx)); + cx.update(|cx| map.fold(vec![Point::new(0, 6)..Point::new(3, 2)], cx)); assert_eq!( - cx.read(|cx| highlighted_chunks(1..4, &map, &theme, cx)), + cx.update(|cx| highlighted_chunks(1..4, &map, &theme, cx)), [ ("out".to_string(), Some("fn.name")), ("…\n".to_string(), None), @@ -607,7 +611,6 @@ mod tests { let text = "\n'a', 'α',\t'✋',\t'❎', '🍐'\n"; let display_text = "\n'a', 'α', '✋', '❎', '🍐'\n"; let buffer = cx.add_model(|cx| Buffer::new(0, text, cx)); - let cx = cx.as_ref(); let map = DisplayMap::new( buffer.clone(), Settings::new(cx.font_cache()).unwrap().with_tab_size(4), @@ -647,7 +650,6 @@ mod tests { fn test_tabs_with_multibyte_chars(cx: &mut gpui::MutableAppContext) { let text = "✅\t\tα\nβ\t\n🏀β\t\tγ"; let buffer = cx.add_model(|cx| Buffer::new(0, text, cx)); - let cx = cx.as_ref(); let map = DisplayMap::new( buffer.clone(), Settings::new(cx.font_cache()).unwrap().with_tab_size(4), @@ -718,19 +720,16 @@ mod tests { buffer.clone(), Settings::new(cx.font_cache()).unwrap().with_tab_size(4), None, - cx.as_ref(), + cx, ); - assert_eq!( - map.snapshot(cx.as_ref()).max_point(), - DisplayPoint::new(1, 11) - ) + assert_eq!(map.snapshot(cx).max_point(), DisplayPoint::new(1, 11)) } fn highlighted_chunks<'a>( rows: Range, map: &DisplayMap, theme: &'a Theme, - cx: &AppContext, + cx: &mut MutableAppContext, ) -> Vec<(String, Option<&'a str>)> { let mut chunks: Vec<(String, Option<&str>)> = Vec::new(); for (chunk, style_id) in map.snapshot(cx).highlighted_chunks_for_rows(rows) { diff --git a/zed/src/editor/display_map/line_wrapper.rs b/zed/src/editor/display_map/line_wrapper.rs index 2fe054e6b2991c9fe65272627fbbca2e34023030..7f2c2145f03255990f72ae1741f4c0d89f16e974 100644 --- a/zed/src/editor/display_map/line_wrapper.rs +++ b/zed/src/editor/display_map/line_wrapper.rs @@ -126,7 +126,7 @@ mod tests { ..Settings::new(&font_cache).unwrap() }; - let mut wrapper = LineWrapper::new(font_system, font_cache, settings); + let wrapper = LineWrapper::new(font_system, font_cache, settings); assert_eq!( wrapper.wrap_line_with_shaping("aa bbb cccc ddddd eeee", 72.0), diff --git a/zed/src/editor/display_map/wrap_map.rs b/zed/src/editor/display_map/wrap_map.rs index daff0a3de9d0295891507b4ba2c4888cf9077cc3..fd2522661e1dd907fc79e6cede3febde45569093 100644 --- a/zed/src/editor/display_map/wrap_map.rs +++ b/zed/src/editor/display_map/wrap_map.rs @@ -12,7 +12,7 @@ use crate::{ util::Bias, Settings, }; -use gpui::{executor::Background, AppContext, Task}; +use gpui::{executor::Background, MutableAppContext, Task}; use parking_lot::Mutex; use postage::{prelude::Stream, sink::Sink, watch}; use smol::future::yield_now; @@ -80,7 +80,7 @@ impl WrapMap { tab_snapshot: TabSnapshot, settings: Settings, wrap_width: Option, - cx: &AppContext, + cx: &mut MutableAppContext, ) -> Self { let this = Self(Arc::new(Mutex::new(WrapMapState { background_task: None, @@ -116,14 +116,14 @@ impl WrapMap { &self, tab_snapshot: TabSnapshot, edits: Vec, - cx: &AppContext, + cx: &mut MutableAppContext, ) -> Snapshot { self.0.lock().pending_edits.push_back((tab_snapshot, edits)); self.flush_edits(cx.background()); self.0.lock().snapshot.clone() } - pub fn set_wrap_width(&self, wrap_width: Option, cx: &AppContext) { + pub fn set_wrap_width(&self, wrap_width: Option, cx: &mut MutableAppContext) { let mut state = self.0.lock(); if wrap_width == state.wrap_width { return; @@ -814,7 +814,7 @@ mod tests { folds_snapshot.text() ); log::info!("Unwrapped text (expanded tabs): {:?}", tabs_snapshot.text()); - let wrap_map = cx.read(|cx| { + let wrap_map = cx.update(|cx| { WrapMap::new( tabs_snapshot.clone(), settings.clone(), @@ -832,7 +832,7 @@ mod tests { notifications.recv().await; } - let snapshot = cx.read(|cx| wrap_map.sync(tabs_snapshot, Vec::new(), cx)); + let snapshot = cx.update(|cx| wrap_map.sync(tabs_snapshot, Vec::new(), cx)); let actual_text = snapshot.text(); assert_eq!( actual_text, expected_text, @@ -856,12 +856,12 @@ mod tests { let unwrapped_text = tabs_snapshot.text(); let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper); - let mut snapshot = cx.read(|cx| wrap_map.sync(tabs_snapshot.clone(), edits, cx)); + let mut snapshot = cx.update(|cx| wrap_map.sync(tabs_snapshot.clone(), edits, cx)); snapshot.check_invariants(&mut rng); if wrap_map.is_rewrapping() { notifications.recv().await; - snapshot = cx.read(|cx| wrap_map.sync(tabs_snapshot, Vec::new(), cx)); + snapshot = cx.update(|cx| wrap_map.sync(tabs_snapshot, Vec::new(), cx)); } snapshot.check_invariants(&mut rng); diff --git a/zed/src/editor/element.rs b/zed/src/editor/element.rs index 8bc98c21aca1d7862ddd185c679ba80affc03b2a..5916d7d1575550b760a2dc2a9baebfa90a1bfb23 100644 --- a/zed/src/editor/element.rs +++ b/zed/src/editor/element.rs @@ -1,3 +1,5 @@ +use crate::time::ReplicaId; + use super::{DisplayPoint, Editor, SelectAction}; use gpui::{ color::ColorU, @@ -9,12 +11,15 @@ use gpui::{ json::{self, ToJson}, text_layout::{self, TextLayoutCache}, AfterLayoutContext, AppContext, Border, Element, Event, EventContext, FontCache, LayoutContext, - PaintContext, Quad, Scene, SizeConstraint, WeakViewHandle, + MutableAppContext, PaintContext, Quad, Scene, SizeConstraint, ViewContext, WeakViewHandle, }; use json::json; use smallvec::SmallVec; -use std::cmp::Ordering; -use std::cmp::{self}; +use std::{cmp::Ordering, ops::Range}; +use std::{ + cmp::{self}, + collections::HashMap, +}; pub struct EditorElement { view: WeakViewHandle, @@ -29,6 +34,13 @@ impl EditorElement { self.view.upgrade(cx).unwrap().read(cx) } + fn update_view(&self, cx: &mut MutableAppContext, f: F) -> T + where + F: FnOnce(&mut Editor, &mut ViewContext) -> T, + { + self.view.upgrade(cx).unwrap().update(cx, f) + } + fn mouse_down( &self, position: Vector2F, @@ -38,9 +50,10 @@ impl EditorElement { cx: &mut EventContext, ) -> bool { if paint.text_bounds.contains_point(position) { - let view = self.view(cx.app.as_ref()); - let position = - paint.point_for_position(view, layout, position, cx.font_cache, cx.app.as_ref()); + let position = self.update_view(cx.app, |view, cx| { + let font_cache = cx.font_cache().clone(); + paint.point_for_position(view, layout, position, &font_cache, cx) + }); cx.dispatch_action("buffer:select", SelectAction::Begin { position, add: cmd }); true } else { @@ -94,19 +107,15 @@ impl EditorElement { )) } - let action = SelectAction::Update { - position: paint.point_for_position( - view, - layout, - position, - cx.font_cache, - cx.app.as_ref(), - ), + let font_cache = cx.font_cache.clone(); + let text_layout_cache = cx.text_layout_cache.clone(); + let action = self.update_view(cx.app, |view, cx| SelectAction::Update { + position: paint.point_for_position(view, layout, position, &font_cache, cx), scroll_position: (view.scroll_position() + scroll_delta).clamp( Vector2F::zero(), - layout.scroll_max(view, cx.font_cache, cx.text_layout_cache, cx.app), + layout.scroll_max(view, &font_cache, &text_layout_cache, cx), ), - }; + }); cx.dispatch_action("buffer:select", action); true @@ -160,7 +169,9 @@ impl EditorElement { let y = (view.scroll_position().y() * line_height - delta.y()) / line_height; let scroll_position = vec2f(x, y).clamp( Vector2F::zero(), - layout.scroll_max(view, font_cache, layout_cache, cx.app), + self.update_view(cx.app, |view, cx| { + layout.scroll_max(view, font_cache, layout_cache, cx) + }), ); cx.dispatch_action("buffer:scroll", scroll_position); @@ -226,14 +237,11 @@ impl EditorElement { let mut cursors = SmallVec::<[Cursor; 32]>::new(); let content_origin = bounds.origin() + layout.text_offset; - for selection_set_id in view.active_selection_sets(cx.app) { - let (selection_color, cursor_color) = - colors[selection_set_id.replica_id as usize % colors.len()]; - for selection in view.selections_in_range( - selection_set_id, - DisplayPoint::new(start_row, 0)..DisplayPoint::new(end_row, 0), - cx.app, - ) { + + for (replica_id, selections) in &layout.selections { + let (selection_color, cursor_color) = colors[*replica_id as usize % colors.len()]; + + for selection in selections { if selection.start != selection.end { let range_start = cmp::min(selection.start, selection.end); let range_end = cmp::max(selection.start, selection.end); @@ -326,17 +334,12 @@ impl Element for EditorElement { constraint: SizeConstraint, cx: &mut LayoutContext, ) -> (Vector2F, Self::LayoutState) { - let app = &mut cx.app; let mut size = constraint.max; - if size.y().is_infinite() { - let view = self.view(app); - size.set_y((view.max_point(app).row() + 1) as f32 * view.line_height(cx.font_cache)); - } if size.x().is_infinite() { unimplemented!("we don't yet handle an infinite width constraint on buffer elements"); } - let view = self.view(app); + let view = self.view(cx.app); let font_cache = &cx.font_cache; let layout_cache = &cx.text_layout_cache; @@ -346,7 +349,7 @@ impl Element for EditorElement { let gutter_width; if view.is_gutter_visible() { gutter_padding = view.em_width(cx.font_cache); - match view.max_line_number_width(cx.font_cache, cx.text_layout_cache, app) { + match view.max_line_number_width(cx.font_cache, cx.text_layout_cache, cx.app) { Err(error) => { log::error!("error computing max line number width: {}", error); return (size, None); @@ -366,12 +369,18 @@ impl Element for EditorElement { let wrap_width = text_size.x() - text_offset.x() - overscroll.x(); // TODO: Core text doesn't seem to be keeping our lines below the specified wrap width. Find out why. let wrap_width = wrap_width - em_width; - view.set_wrap_width(wrap_width, app); + self.update_view(cx.app, |view, cx| { + view.set_wrap_width(wrap_width, cx); + }); + + if size.y().is_infinite() { + size.set_y((view.max_point(cx.app).row() + 1) as f32 * view.line_height(cx.font_cache)); + } - let autoscroll_horizontally = view.autoscroll_vertically(size.y(), line_height, app); + let autoscroll_horizontally = view.autoscroll_vertically(size.y(), line_height, cx.app); let line_number_layouts = if view.is_gutter_visible() { - match view.layout_line_numbers(size.y(), cx.font_cache, cx.text_layout_cache, app) { + match view.layout_line_numbers(size.y(), cx.font_cache, cx.text_layout_cache, cx.app) { Err(error) => { log::error!("error laying out line numbers: {}", error); return (size, None); @@ -388,7 +397,7 @@ impl Element for EditorElement { let mut max_visible_line_width = 0.0; let line_layouts = - match view.layout_lines(start_row..end_row, font_cache, layout_cache, app) { + match view.layout_lines(start_row..end_row, font_cache, layout_cache, cx.app) { Err(error) => { log::error!("error laying out lines: {}", error); return (size, None); @@ -404,21 +413,34 @@ impl Element for EditorElement { } }; - ( + let mut selections = HashMap::new(); + for selection_set_id in view.active_selection_sets(cx.app) { + selections.insert( + selection_set_id.replica_id, + view.selections_in_range( + selection_set_id, + DisplayPoint::new(start_row, 0)..DisplayPoint::new(end_row, 0), + cx.app, + ) + .collect(), + ); + } + + let layout_state = Some(LayoutState { size, - Some(LayoutState { - size, - gutter_size, - gutter_padding, - text_size, - overscroll, - text_offset, - line_layouts, - line_number_layouts, - max_visible_line_width, - autoscroll_horizontally, - }), - ) + gutter_size, + gutter_padding, + text_size, + overscroll, + text_offset, + line_layouts, + line_number_layouts, + selections, + max_visible_line_width, + autoscroll_horizontally, + }); + + (size, layout_state) } fn after_layout( @@ -428,12 +450,10 @@ impl Element for EditorElement { cx: &mut AfterLayoutContext, ) { if let Some(layout) = layout { - let app = cx.app.as_ref(); - - let view = self.view(app); + let view = self.view(cx.app); view.clamp_scroll_left( layout - .scroll_max(view, cx.font_cache, cx.text_layout_cache, app) + .scroll_max(view, cx.font_cache, cx.text_layout_cache, cx.app) .x(), ); @@ -441,10 +461,10 @@ impl Element for EditorElement { view.autoscroll_horizontally( view.scroll_position().y() as u32, layout.text_size.x(), - layout.scroll_width(view, cx.font_cache, cx.text_layout_cache, app), + layout.scroll_width(view, cx.font_cache, cx.text_layout_cache, cx.app), view.em_width(cx.font_cache), &layout.line_layouts, - app, + cx.app, ); } } @@ -528,6 +548,7 @@ pub struct LayoutState { text_size: Vector2F, line_layouts: Vec, line_number_layouts: Vec, + selections: HashMap>>, overscroll: Vector2F, text_offset: Vector2F, max_visible_line_width: f32, @@ -540,7 +561,7 @@ impl LayoutState { view: &Editor, font_cache: &FontCache, layout_cache: &TextLayoutCache, - cx: &AppContext, + cx: &mut MutableAppContext, ) -> f32 { let row = view.longest_row(cx); let longest_line_width = view @@ -555,7 +576,7 @@ impl LayoutState { view: &Editor, font_cache: &FontCache, layout_cache: &TextLayoutCache, - cx: &AppContext, + cx: &mut MutableAppContext, ) -> Vector2F { vec2f( ((self.scroll_width(view, font_cache, layout_cache, cx) - self.text_size.x()) @@ -578,7 +599,7 @@ impl PaintState { layout: &LayoutState, position: Vector2F, font_cache: &FontCache, - cx: &AppContext, + cx: &mut MutableAppContext, ) -> DisplayPoint { let scroll_position = view.scroll_position(); let position = position - self.text_bounds.origin(); diff --git a/zed/src/file_finder.rs b/zed/src/file_finder.rs index 362ee34e65ce5f49053b49f92797603e169a3502..2595d5105db7bcb518ccef8b2113a46f7457a594 100644 --- a/zed/src/file_finder.rs +++ b/zed/src/file_finder.rs @@ -311,7 +311,7 @@ impl FileFinder { } fn workspace_updated(&mut self, _: ViewHandle, cx: &mut ViewContext) { - if let Some(task) = self.spawn_search(self.query_buffer.read(cx).text(cx.as_ref()), cx) { + if let Some(task) = self.spawn_search(self.query_buffer.read(cx).text(cx), cx) { task.detach(); } } @@ -324,7 +324,7 @@ impl FileFinder { ) { match event { editor::Event::Edited => { - let query = self.query_buffer.read(cx).text(cx.as_ref()); + let query = self.query_buffer.update(cx, |buffer, cx| buffer.text(cx)); if query.is_empty() { self.latest_search_id = util::post_inc(&mut self.search_count); self.matches.clear(); diff --git a/zed/src/workspace.rs b/zed/src/workspace.rs index 4086eddd8230201bad184f70d0750e9a95c9caac..aa61cb6842409bbd0a5f9c0214aff7dda4ed86ca 100644 --- a/zed/src/workspace.rs +++ b/zed/src/workspace.rs @@ -1329,7 +1329,7 @@ mod tests { .to_any() .downcast::() .unwrap(); - assert!(editor.read(cx).text(cx.as_ref()).is_empty()); + assert!(editor.update(cx, |editor, cx| editor.text(cx).is_empty())); }); }