diff --git a/zed/src/editor.rs b/zed/src/editor.rs index 5f6d537bf9b285d156ca2a57abb0b5ae4c33afc0..e06aa2a85849a2087d608e151fa090da9c968665 100644 --- a/zed/src/editor.rs +++ b/zed/src/editor.rs @@ -474,9 +474,11 @@ impl Editor { line_height: f32, cx: &AppContext, ) -> bool { + let display_map = self.display_map.snapshot(cx); let mut scroll_position = self.scroll_position.lock(); let scroll_top = scroll_position.y(); - scroll_position.set_y(scroll_top.min(self.max_point(cx).row().saturating_sub(1) as f32)); + scroll_position + .set_y(scroll_top.min(display_map.max_point().row().saturating_sub(1) as f32)); let mut autoscroll_requested = self.autoscroll_requested.lock(); if *autoscroll_requested { @@ -491,14 +493,14 @@ impl Editor { .first() .unwrap() .head() - .to_display_point(&self.display_map, cx) + .to_display_point(&display_map) .row() as f32; let last_cursor_bottom = self .selections(cx) .last() .unwrap() .head() - .to_display_point(&self.display_map, cx) + .to_display_point(&display_map) .row() as f32 + 1.0; @@ -532,12 +534,13 @@ impl Editor { layouts: &[text_layout::Line], cx: &AppContext, ) { + let display_map = self.display_map.snapshot(cx); let mut target_left = std::f32::INFINITY; let mut target_right = 0.0_f32; for selection in self.selections(cx) { - let head = selection.head().to_display_point(&self.display_map, cx); + let head = selection.head().to_display_point(&display_map); let start_column = head.column().saturating_sub(3); - let end_column = cmp::min(self.display_map.line_len(head.row(), cx), head.column() + 3); + let end_column = cmp::min(display_map.line_len(head.row()), head.column() + 3); target_left = target_left .min(layouts[(head.row() - start_row) as usize].x_for_index(start_column as usize)); target_right = target_right.max( @@ -579,9 +582,8 @@ impl Editor { cx.emit(Event::Activate); } - let cursor = self - .display_map - .anchor_before(position, Bias::Left, cx.as_ref()); + let display_map = self.display_map.snapshot(cx.as_ref()); + let cursor = display_map.anchor_before(position, Bias::Left); let selection = Selection { id: post_inc(&mut self.next_selection_id), start: cursor.clone(), @@ -605,9 +607,8 @@ impl Editor { cx: &mut ViewContext, ) { let buffer = self.buffer.read(cx); - let cursor = self - .display_map - .anchor_before(position, Bias::Left, cx.as_ref()); + let display_map = self.display_map.snapshot(cx.as_ref()); + let cursor = display_map.anchor_before(position, Bias::Left); if let Some(selection) = self.pending_selection.as_mut() { selection.set_head(buffer, cursor); } else { @@ -684,6 +685,7 @@ impl Editor { T: IntoIterator>, { let mut selections = Vec::new(); + let display_map = self.display_map.snapshot(cx.as_ref()); for range in ranges { let mut start = range.start; let mut end = range.end; @@ -696,10 +698,8 @@ impl Editor { selections.push(Selection { id: post_inc(&mut self.next_selection_id), - start: self - .display_map - .anchor_before(start, Bias::Left, cx.as_ref()), - end: self.display_map.anchor_before(end, Bias::Left, cx.as_ref()), + start: display_map.anchor_before(start, Bias::Left), + end: display_map.anchor_before(end, Bias::Left), reversed, goal: SelectionGoal::None, }); @@ -760,19 +760,15 @@ 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 buffer = self.buffer.read(cx); for selection in &mut selections { let range = selection.point_range(buffer); if range.start == range.end { - let head = selection - .head() - .to_display_point(&self.display_map, cx.as_ref()); - let cursor = self.display_map.anchor_before( - movement::left(&self.display_map, head, cx.as_ref()).unwrap(), - Bias::Left, - cx.as_ref(), - ); + let head = selection.head().to_display_point(&display_map); + let cursor = display_map + .anchor_before(movement::left(&display_map, head).unwrap(), Bias::Left); selection.set_head(&buffer, cursor); selection.goal = SelectionGoal::None; } @@ -786,20 +782,16 @@ 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 mut selections = self.selections(cx.as_ref()).to_vec(); { let buffer = self.buffer.read(cx); for selection in &mut selections { let range = selection.point_range(buffer); if range.start == range.end { - let head = selection - .head() - .to_display_point(&self.display_map, cx.as_ref()); - let cursor = self.display_map.anchor_before( - movement::right(&self.display_map, head, cx.as_ref()).unwrap(), - Bias::Right, - cx.as_ref(), - ); + let head = selection.head().to_display_point(&display_map); + let cursor = display_map + .anchor_before(movement::right(&display_map, head).unwrap(), Bias::Right); selection.set_head(&buffer, cursor); selection.goal = SelectionGoal::None; } @@ -820,19 +812,16 @@ 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 mut selections = self.selections(app).iter().peekable(); while let Some(selection) = selections.next() { - let (mut rows, _) = - selection.buffer_rows_for_display_rows(false, &self.display_map, app); - let goal_display_column = selection - .head() - .to_display_point(&self.display_map, app) - .column(); + let (mut rows, _) = selection.buffer_rows_for_display_rows(false, &display_map); + let goal_display_column = selection.head().to_display_point(&display_map).column(); // Accumulate contiguous regions of rows that we want to delete. while let Some(next_selection) = selections.peek() { let (next_rows, _) = - next_selection.buffer_rows_for_display_rows(false, &self.display_map, app); + next_selection.buffer_rows_for_display_rows(false, &display_map); if next_rows.start <= rows.end { rows.end = next_rows.end; selections.next().unwrap(); @@ -857,16 +846,13 @@ impl Editor { cursor_buffer_row = rows.start.saturating_sub(1); } - let mut cursor = - Point::new(cursor_buffer_row, 0).to_display_point(&self.display_map, app); - *cursor.column_mut() = cmp::min( - goal_display_column, - self.display_map.line_len(cursor.row(), app), - ); + let mut cursor = Point::new(cursor_buffer_row, 0).to_display_point(&display_map); + *cursor.column_mut() = + cmp::min(goal_display_column, display_map.line_len(cursor.row())); new_cursors.push(( selection.id, - cursor.to_buffer_point(&self.display_map, Bias::Left, app), + cursor.to_buffer_point(&display_map, Bias::Left), )); edit_ranges.push(edit_start..edit_end); } @@ -906,18 +892,17 @@ impl Editor { } self.update_selections(selections.clone(), false, cx); - let app = cx.as_ref(); let buffer = self.buffer.read(cx); + let display_map = self.display_map.snapshot(cx.as_ref()); let mut edits = Vec::new(); let mut selections_iter = selections.iter_mut().peekable(); while let Some(selection) = selections_iter.next() { // Avoid duplicating the same lines twice. - let (mut rows, _) = - selection.buffer_rows_for_display_rows(false, &self.display_map, app); + let (mut rows, _) = selection.buffer_rows_for_display_rows(false, &display_map); while let Some(next_selection) = selections_iter.peek() { let (next_rows, _) = - next_selection.buffer_rows_for_display_rows(false, &self.display_map, app); + next_selection.buffer_rows_for_display_rows(false, &display_map); if next_rows.start <= rows.end - 1 { rows.end = next_rows.end; selections_iter.next().unwrap(); @@ -971,10 +956,10 @@ impl Editor { // Accumulate contiguous regions of rows that we want to move. contiguous_selections.push(selection.point_range(buffer)); let (mut buffer_rows, mut display_rows) = - selection.buffer_rows_for_display_rows(false, &self.display_map, app); + selection.buffer_rows_for_display_rows(false, &display_map); while let Some(next_selection) = selections.peek() { let (next_buffer_rows, next_display_rows) = - next_selection.buffer_rows_for_display_rows(false, &self.display_map, app); + next_selection.buffer_rows_for_display_rows(false, &display_map); if next_buffer_rows.start <= buffer_rows.end { buffer_rows.end = next_buffer_rows.end; display_rows.end = next_display_rows.end; @@ -993,7 +978,7 @@ impl Editor { let prev_row_display_start = DisplayPoint::new(display_rows.start - 1, 0); let prev_row_start = - prev_row_display_start.to_buffer_offset(&self.display_map, Bias::Left, app); + prev_row_display_start.to_buffer_offset(&display_map, Bias::Left); let mut text = String::new(); text.extend(buffer.text_for_range(start..end)); @@ -1003,7 +988,7 @@ impl Editor { let row_delta = buffer_rows.start - prev_row_display_start - .to_buffer_point(&self.display_map, Bias::Left, app) + .to_buffer_point(&display_map, Bias::Left) .row; // Move selections up. @@ -1056,10 +1041,10 @@ impl Editor { // Accumulate contiguous regions of rows that we want to move. contiguous_selections.push(selection.point_range(buffer)); let (mut buffer_rows, mut display_rows) = - selection.buffer_rows_for_display_rows(false, &self.display_map, app); + selection.buffer_rows_for_display_rows(false, &display_map); while let Some(next_selection) = selections.peek() { let (next_buffer_rows, next_display_rows) = - next_selection.buffer_rows_for_display_rows(false, &self.display_map, app); + next_selection.buffer_rows_for_display_rows(false, &display_map); if next_buffer_rows.start <= buffer_rows.end { buffer_rows.end = next_buffer_rows.end; display_rows.end = next_display_rows.end; @@ -1071,17 +1056,14 @@ impl Editor { } // Cut the text from the selected rows and paste it at the end of the next line. - if display_rows.end <= self.display_map.max_point(app).row() { + if display_rows.end <= display_map.max_point().row() { let start = Point::new(buffer_rows.start, 0).to_offset(buffer); let end = Point::new(buffer_rows.end - 1, buffer.line_len(buffer_rows.end - 1)) .to_offset(buffer); - let next_row_display_end = DisplayPoint::new( - display_rows.end, - self.display_map.line_len(display_rows.end, app), - ); - let next_row_end = - next_row_display_end.to_buffer_offset(&self.display_map, Bias::Right, app); + let next_row_display_end = + DisplayPoint::new(display_rows.end, display_map.line_len(display_rows.end)); + let next_row_end = next_row_display_end.to_buffer_offset(&display_map, Bias::Right); let mut text = String::new(); text.push('\n'); @@ -1090,7 +1072,7 @@ impl Editor { edits.push((next_row_end..next_row_end, text)); let row_delta = next_row_display_end - .to_buffer_point(&self.display_map, Bias::Right, app) + .to_buffer_point(&display_map, Bias::Right) .row - buffer_rows.end + 1; @@ -1260,20 +1242,18 @@ impl Editor { pub fn move_left(&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(); { for selection in &mut selections { - let start = selection.start.to_display_point(&self.display_map, app); - let end = selection.end.to_display_point(&self.display_map, app); + let start = selection.start.to_display_point(&display_map); + let end = selection.end.to_display_point(&display_map); if start != end { selection.end = selection.start.clone(); } else { - let cursor = self.display_map.anchor_before( - movement::left(&self.display_map, start, app).unwrap(), - Bias::Left, - app, - ); + let cursor = display_map + .anchor_before(movement::left(&display_map, start).unwrap(), Bias::Left); selection.start = cursor.clone(); selection.end = cursor; } @@ -1285,18 +1265,14 @@ impl Editor { } pub fn select_left(&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 buffer = self.buffer.read(cx); for selection in &mut selections { - let head = selection - .head() - .to_display_point(&self.display_map, cx.as_ref()); - let cursor = self.display_map.anchor_before( - movement::left(&self.display_map, head, cx.as_ref()).unwrap(), - Bias::Left, - cx.as_ref(), - ); + let head = selection.head().to_display_point(&display_map); + let cursor = display_map + .anchor_before(movement::left(&display_map, head).unwrap(), Bias::Left); selection.set_head(&buffer, cursor); selection.goal = SelectionGoal::None; } @@ -1305,21 +1281,18 @@ impl Editor { } pub fn move_right(&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 app = cx.as_ref(); for selection in &mut selections { - let start = selection.start.to_display_point(&self.display_map, app); - let end = selection.end.to_display_point(&self.display_map, app); + let start = selection.start.to_display_point(&display_map); + let end = selection.end.to_display_point(&display_map); if start != end { selection.start = selection.end.clone(); } else { - let cursor = self.display_map.anchor_before( - movement::right(&self.display_map, end, app).unwrap(), - Bias::Right, - app, - ); + let cursor = display_map + .anchor_before(movement::right(&display_map, end).unwrap(), Bias::Right); selection.start = cursor.clone(); selection.end = cursor; } @@ -1331,19 +1304,15 @@ impl Editor { } pub fn select_right(&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 app = cx.as_ref(); let buffer = self.buffer.read(app); for selection in &mut selections { - let head = selection - .head() - .to_display_point(&self.display_map, cx.as_ref()); - let cursor = self.display_map.anchor_before( - movement::right(&self.display_map, head, app).unwrap(), - Bias::Right, - app, - ); + let head = selection.head().to_display_point(&display_map); + let cursor = display_map + .anchor_before(movement::right(&display_map, head).unwrap(), Bias::Right); selection.set_head(&buffer, cursor); selection.goal = SelectionGoal::None; } @@ -1352,22 +1321,21 @@ impl Editor { } pub fn move_up(&mut self, _: &(), cx: &mut ViewContext) { + let display_map = self.display_map.snapshot(cx.as_ref()); if self.single_line { cx.propagate_action(); } else { let mut selections = self.selections(cx.as_ref()).to_vec(); { - let app = cx.as_ref(); for selection in &mut selections { - let start = selection.start.to_display_point(&self.display_map, app); - let end = selection.end.to_display_point(&self.display_map, app); + let start = selection.start.to_display_point(&display_map); + let end = selection.end.to_display_point(&display_map); if start != end { selection.goal = SelectionGoal::None; } - let (start, goal) = - movement::up(&self.display_map, start, selection.goal, app).unwrap(); - let cursor = self.display_map.anchor_before(start, Bias::Left, app); + let (start, goal) = movement::up(&display_map, start, selection.goal).unwrap(); + let cursor = display_map.anchor_before(start, Bias::Left); selection.start = cursor.clone(); selection.end = cursor; selection.goal = goal; @@ -1379,18 +1347,15 @@ impl Editor { } pub fn select_up(&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 app = cx.as_ref(); let buffer = self.buffer.read(app); for selection in &mut selections { - let head = selection.head().to_display_point(&self.display_map, app); - let (head, goal) = - movement::up(&self.display_map, head, selection.goal, app).unwrap(); - selection.set_head( - &buffer, - self.display_map.anchor_before(head, Bias::Left, app), - ); + let head = selection.head().to_display_point(&display_map); + let (head, goal) = movement::up(&display_map, head, selection.goal).unwrap(); + selection.set_head(&buffer, display_map.anchor_before(head, Bias::Left)); selection.goal = goal; } } @@ -1401,19 +1366,18 @@ impl Editor { if self.single_line { cx.propagate_action(); } else { + let display_map = self.display_map.snapshot(cx.as_ref()); let mut selections = self.selections(cx.as_ref()).to_vec(); { - let app = cx.as_ref(); for selection in &mut selections { - let start = selection.start.to_display_point(&self.display_map, app); - let end = selection.end.to_display_point(&self.display_map, app); + let start = selection.start.to_display_point(&display_map); + let end = selection.end.to_display_point(&display_map); if start != end { selection.goal = SelectionGoal::None; } - let (start, goal) = - movement::down(&self.display_map, end, selection.goal, app).unwrap(); - let cursor = self.display_map.anchor_before(start, Bias::Right, app); + let (start, goal) = movement::down(&display_map, end, selection.goal).unwrap(); + let cursor = display_map.anchor_before(start, Bias::Right); selection.start = cursor.clone(); selection.end = cursor; selection.goal = goal; @@ -1425,18 +1389,15 @@ 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 app = cx.as_ref(); let buffer = self.buffer.read(app); for selection in &mut selections { - let head = selection.head().to_display_point(&self.display_map, app); - let (head, goal) = - movement::down(&self.display_map, head, selection.goal, app).unwrap(); - selection.set_head( - &buffer, - self.display_map.anchor_before(head, Bias::Right, app), - ); + let head = selection.head().to_display_point(&display_map); + let (head, goal) = movement::down(&display_map, head, selection.goal).unwrap(); + selection.set_head(&buffer, display_map.anchor_before(head, Bias::Right)); selection.goal = goal; } } @@ -1445,12 +1406,13 @@ 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(); { for selection in &mut selections { - let head = selection.head().to_display_point(&self.display_map, app); - let new_head = movement::prev_word_boundary(&self.display_map, head, app).unwrap(); - let anchor = self.display_map.anchor_before(new_head, Bias::Left, app); + let head = selection.head().to_display_point(&display_map); + let new_head = movement::prev_word_boundary(&display_map, head).unwrap(); + let anchor = display_map.anchor_before(new_head, Bias::Left); selection.start = anchor.clone(); selection.end = anchor; selection.reversed = false; @@ -1462,13 +1424,14 @@ 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 buffer = self.buffer.read(cx); for selection in &mut selections { - let head = selection.head().to_display_point(&self.display_map, app); - let new_head = movement::prev_word_boundary(&self.display_map, head, app).unwrap(); - let anchor = self.display_map.anchor_before(new_head, Bias::Left, app); + let head = selection.head().to_display_point(&display_map); + let new_head = movement::prev_word_boundary(&display_map, head).unwrap(); + let anchor = display_map.anchor_before(new_head, Bias::Left); selection.set_head(buffer, anchor); selection.goal = SelectionGoal::None; } @@ -1485,12 +1448,13 @@ 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(); { for selection in &mut selections { - let head = selection.head().to_display_point(&self.display_map, app); - let new_head = movement::next_word_boundary(&self.display_map, head, app).unwrap(); - let anchor = self.display_map.anchor_before(new_head, Bias::Left, app); + let head = selection.head().to_display_point(&display_map); + let new_head = movement::next_word_boundary(&display_map, head).unwrap(); + let anchor = display_map.anchor_before(new_head, Bias::Left); selection.start = anchor.clone(); selection.end = anchor; selection.reversed = false; @@ -1502,13 +1466,14 @@ 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 buffer = self.buffer.read(cx); for selection in &mut selections { - let head = selection.head().to_display_point(&self.display_map, app); - let new_head = movement::next_word_boundary(&self.display_map, head, app).unwrap(); - let anchor = self.display_map.anchor_before(new_head, Bias::Left, app); + let head = selection.head().to_display_point(&display_map); + let new_head = movement::next_word_boundary(&display_map, head).unwrap(); + let anchor = display_map.anchor_before(new_head, Bias::Left); selection.set_head(buffer, anchor); selection.goal = SelectionGoal::None; } @@ -1525,13 +1490,13 @@ 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(); { for selection in &mut selections { - let head = selection.head().to_display_point(&self.display_map, app); - let new_head = - movement::line_beginning(&self.display_map, head, true, app).unwrap(); - let anchor = self.display_map.anchor_before(new_head, Bias::Left, app); + let head = selection.head().to_display_point(&display_map); + let new_head = movement::line_beginning(&display_map, head, true).unwrap(); + let anchor = display_map.anchor_before(new_head, Bias::Left); selection.start = anchor.clone(); selection.end = anchor; selection.reversed = false; @@ -1547,14 +1512,15 @@ impl Editor { 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 buffer = self.buffer.read(cx); for selection in &mut selections { - let head = selection.head().to_display_point(&self.display_map, app); + let head = selection.head().to_display_point(&display_map); let new_head = - movement::line_beginning(&self.display_map, head, *toggle_indent, app).unwrap(); - let anchor = self.display_map.anchor_before(new_head, Bias::Left, app); + movement::line_beginning(&display_map, head, *toggle_indent).unwrap(); + let anchor = display_map.anchor_before(new_head, Bias::Left); selection.set_head(buffer, anchor); selection.goal = SelectionGoal::None; } @@ -1571,12 +1537,13 @@ 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(); { for selection in &mut selections { - let head = selection.head().to_display_point(&self.display_map, app); - let new_head = movement::line_end(&self.display_map, head, app).unwrap(); - let anchor = self.display_map.anchor_before(new_head, Bias::Left, app); + let head = selection.head().to_display_point(&display_map); + let new_head = movement::line_end(&display_map, head).unwrap(); + let anchor = display_map.anchor_before(new_head, Bias::Left); selection.start = anchor.clone(); selection.end = anchor; selection.reversed = false; @@ -1588,13 +1555,14 @@ 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 buffer = self.buffer.read(cx); for selection in &mut selections { - let head = selection.head().to_display_point(&self.display_map, app); - let new_head = movement::line_end(&self.display_map, head, app).unwrap(); - let anchor = self.display_map.anchor_before(new_head, Bias::Left, app); + let head = selection.head().to_display_point(&display_map); + let new_head = movement::line_end(&display_map, head).unwrap(); + let anchor = display_map.anchor_before(new_head, Bias::Left); selection.set_head(buffer, anchor); selection.goal = SelectionGoal::None; } @@ -1668,10 +1636,11 @@ 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 max_point = buffer.max_point(); for selection in &mut selections { - let (rows, _) = selection.buffer_rows_for_display_rows(true, &self.display_map, app); + let (rows, _) = selection.buffer_rows_for_display_rows(true, &display_map); selection.start = buffer.anchor_before(Point::new(rows.start, 0)); selection.end = buffer.anchor_before(cmp::min(max_point, Point::new(rows.end, 0))); selection.reversed = false; @@ -1729,22 +1698,23 @@ 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 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(&self.display_map, app) - .sorted(); + let range = oldest_selection.display_range(&display_map).sorted(); let columns = cmp::min(range.start.column(), range.end.column()) ..cmp::max(range.start.column(), range.end.column()); selections.clear(); let mut stack = Vec::new(); for row in range.start.row()..=range.end.row() { - if let Some(selection) = - self.build_columnar_selection(row, &columns, oldest_selection.reversed, app) - { + if let Some(selection) = self.build_columnar_selection( + &display_map, + row, + &columns, + oldest_selection.reversed, + ) { stack.push(selection.id); selections.push(selection); } @@ -1763,12 +1733,12 @@ impl Editor { let end_row = if above { 0 } else { - self.display_map.max_point(app).row() + display_map.max_point().row() }; 'outer: for selection in selections { if selection.id == last_added_selection { - let range = selection.display_range(&self.display_map, app).sorted(); + let range = selection.display_range(&display_map).sorted(); debug_assert_eq!(range.start.row(), range.end.row()); let mut row = range.start.row(); let columns = if let SelectionGoal::ColumnRange { start, end } = selection.goal @@ -1786,9 +1756,12 @@ impl Editor { row += 1; } - if let Some(new_selection) = - self.build_columnar_selection(row, &columns, selection.reversed, app) - { + if let Some(new_selection) = self.build_columnar_selection( + &display_map, + row, + &columns, + selection.reversed, + ) { state.stack.push(new_selection.id); if above { new_selections.push(new_selection); @@ -1820,6 +1793,7 @@ 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 mut stack = mem::take(&mut self.select_larger_syntax_node_stack); let mut selected_larger_node = false; @@ -1830,8 +1804,8 @@ impl Editor { let mut new_range = old_range.clone(); while let Some(containing_range) = buffer.range_for_syntax_ancestor(new_range.clone()) { new_range = containing_range; - if !self.display_map.intersects_fold(new_range.start, app) - && !self.display_map.intersects_fold(new_range.end, app) + if !display_map.intersects_fold(new_range.start) + && !display_map.intersects_fold(new_range.end) { break; } @@ -1893,20 +1867,20 @@ impl Editor { fn build_columnar_selection( &mut self, + display_map: &DisplayMapSnapshot, row: u32, columns: &Range, reversed: bool, - cx: &AppContext, ) -> Option { let is_empty = columns.start == columns.end; - let line_len = self.display_map.line_len(row, cx); + let line_len = display_map.line_len(row); if columns.start < line_len || (is_empty && columns.start == line_len) { let start = DisplayPoint::new(row, columns.start); let end = DisplayPoint::new(row, cmp::min(columns.end, line_len)); Some(Selection { id: post_inc(&mut self.next_selection_id), - start: self.display_map.anchor_before(start, Bias::Left, cx), - end: self.display_map.anchor_before(end, Bias::Left, cx), + start: display_map.anchor_before(start, Bias::Left), + end: display_map.anchor_before(end, Bias::Left), reversed, goal: SelectionGoal::ColumnRange { start: columns.start, @@ -1936,12 +1910,13 @@ impl Editor { cx: &'a AppContext, ) -> impl 'a + Iterator> { let buffer = self.buffer.read(cx); + let display_map = self.display_map.snapshot(cx); let selections = &buffer.selection_set(set_id).unwrap().selections; - let start = self.display_map.anchor_before(range.start, Bias::Left, cx); + let start = display_map.anchor_before(range.start, Bias::Left); let start_index = self.selection_insertion_index(selections, &start, cx); let pending_selection = if set_id.replica_id == self.buffer.read(cx).replica_id() { self.pending_selection.as_ref().and_then(|s| { - let selection_range = s.display_range(&self.display_map, cx); + let selection_range = s.display_range(&display_map); if selection_range.start <= range.end || selection_range.end <= range.end { Some(selection_range) } else { @@ -1953,7 +1928,7 @@ impl Editor { }; selections[start_index..] .iter() - .map(move |s| s.display_range(&self.display_map, cx)) + .map(move |s| s.display_range(&display_map)) .take_while(move |r| r.start <= range.end || r.end <= range.end) .chain(pending_selection) } @@ -2059,18 +2034,14 @@ impl Editor { 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 range = selection.display_range(&self.display_map, app).sorted(); - let buffer_start_row = range - .start - .to_buffer_point(&self.display_map, Bias::Left, app) - .row; + let range = selection.display_range(&display_map).sorted(); + let buffer_start_row = range.start.to_buffer_point(&display_map, Bias::Left).row; for row in (0..=range.end.row()).rev() { - if self.is_line_foldable(row, app) - && !self.display_map.is_line_folded(row, cx.as_ref()) - { - let fold_range = self.foldable_range_for_line(row, app); + if self.is_line_foldable(&display_map, row) && !display_map.is_line_folded(row) { + let fold_range = self.foldable_range_for_line(&display_map, row); if fold_range.end.row >= buffer_start_row { fold_ranges.push(fold_range); if row <= range.start.row() { @@ -2087,17 +2058,14 @@ 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 ranges = self .selections(app) .iter() .map(|s| { - let range = s.display_range(&self.display_map, app).sorted(); - let mut start = range - .start - .to_buffer_point(&self.display_map, Bias::Left, app); - let mut end = range - .end - .to_buffer_point(&self.display_map, Bias::Left, app); + let range = s.display_range(&display_map).sorted(); + let mut start = range.start.to_buffer_point(&display_map, Bias::Left); + let mut end = range.end.to_buffer_point(&display_map, Bias::Left); start.column = 0; end.column = buffer.line_len(end.row); start..end @@ -2106,17 +2074,17 @@ impl Editor { self.unfold_ranges(ranges, cx); } - fn is_line_foldable(&self, display_row: u32, cx: &AppContext) -> bool { - let max_point = self.max_point(cx); + fn is_line_foldable(&self, display_map: &DisplayMapSnapshot, display_row: u32) -> bool { + let max_point = display_map.max_point(); if display_row >= max_point.row() { false } else { - let (start_indent, is_blank) = self.display_map.line_indent(display_row, cx); + let (start_indent, is_blank) = display_map.line_indent(display_row); if is_blank { false } else { for display_row in display_row + 1..=max_point.row() { - let (indent, is_blank) = self.display_map.line_indent(display_row, cx); + let (indent, is_blank) = display_map.line_indent(display_row); if !is_blank { return indent > start_indent; } @@ -2126,23 +2094,27 @@ impl Editor { } } - fn foldable_range_for_line(&self, start_row: u32, cx: &AppContext) -> Range { - let max_point = self.max_point(cx); + fn foldable_range_for_line( + &self, + display_map: &DisplayMapSnapshot, + start_row: u32, + ) -> Range { + let max_point = display_map.max_point(); - let (start_indent, _) = self.display_map.line_indent(start_row, cx); - let start = DisplayPoint::new(start_row, self.line_len(start_row, cx)); + let (start_indent, _) = display_map.line_indent(start_row); + let start = DisplayPoint::new(start_row, display_map.line_len(start_row)); let mut end = None; for row in start_row + 1..=max_point.row() { - let (indent, is_blank) = self.display_map.line_indent(row, cx); + let (indent, is_blank) = display_map.line_indent(row); if !is_blank && indent <= start_indent { - end = Some(DisplayPoint::new(row - 1, self.line_len(row - 1, cx))); + end = Some(DisplayPoint::new(row - 1, display_map.line_len(row - 1))); break; } } let end = end.unwrap_or(max_point); - return start.to_buffer_point(&self.display_map, Bias::Left, cx) - ..end.to_buffer_point(&self.display_map, Bias::Left, cx); + return start.to_buffer_point(display_map, Bias::Left) + ..end.to_buffer_point(display_map, Bias::Left); } pub fn fold_selected_ranges(&mut self, _: &(), cx: &mut ViewContext) { @@ -2171,24 +2143,20 @@ impl Editor { } } - pub fn line(&self, display_row: u32, cx: &AppContext) -> String { - self.display_map.line(display_row, cx) - } - pub fn line_len(&self, display_row: u32, cx: &AppContext) -> u32 { - self.display_map.line_len(display_row, cx) + self.display_map.snapshot(cx).line_len(display_row) } pub fn longest_row(&self, cx: &AppContext) -> u32 { - self.display_map.longest_row(cx) + self.display_map.snapshot(cx).longest_row() } pub fn max_point(&self, cx: &AppContext) -> DisplayPoint { - self.display_map.max_point(cx) + self.display_map.snapshot(cx).max_point() } pub fn text(&self, cx: &AppContext) -> String { - self.display_map.text(cx) + self.display_map.snapshot(cx).text() } pub fn font_size(&self) -> f32 { @@ -2289,7 +2257,8 @@ impl Editor { layout_cache: &TextLayoutCache, cx: &AppContext, ) -> Result> { - rows.end = cmp::min(rows.end, self.display_map.max_point(cx).row() + 1); + let mut display_map = self.display_map.snapshot(cx); + rows.end = cmp::min(rows.end, display_map.max_point().row() + 1); if rows.start >= rows.end { return Ok(Vec::new()); } @@ -2306,8 +2275,7 @@ impl Editor { let mut line = String::new(); let mut styles = Vec::new(); let mut row = rows.start; - let mut snapshot = self.display_map.snapshot(cx); - let chunks = snapshot.highlighted_chunks_for_rows(rows.clone()); + let chunks = display_map.highlighted_chunks_for_rows(rows.clone()); let theme = settings.theme.clone(); 'outer: for (chunk, style_ix) in chunks.chain(Some(("\n", StyleId::default()))) { @@ -2349,15 +2317,16 @@ impl Editor { cx: &AppContext, ) -> 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 line = self.line(row, cx); + let line = display_map.line(row); Ok(layout_cache.layout_str( &line, settings.buffer_font_size, - &[(self.line_len(row, cx) as usize, font_id, ColorU::black())], + &[(display_map.line_len(row) as usize, font_id, ColorU::black())], )) } diff --git a/zed/src/editor/buffer/selection.rs b/zed/src/editor/buffer/selection.rs index f0251fad1e18be4e9c55bd65e0c9106ff5d54746..3fe057d5910baa7db3fb1084270bb2e45a1a310d 100644 --- a/zed/src/editor/buffer/selection.rs +++ b/zed/src/editor/buffer/selection.rs @@ -1,12 +1,10 @@ use crate::{ editor::{ buffer::{Anchor, Buffer, Point, ToOffset as _, ToPoint as _}, - display_map::DisplayMap, - Bias, DisplayPoint, + Bias, DisplayMapSnapshot, DisplayPoint, }, time, }; -use gpui::AppContext; use std::{cmp::Ordering, mem, ops::Range}; pub type SelectionSetId = time::Lamport; @@ -81,9 +79,9 @@ impl Selection { } } - pub fn display_range(&self, map: &DisplayMap, cx: &AppContext) -> Range { - let start = self.start.to_display_point(map, cx); - let end = self.end.to_display_point(map, cx); + pub fn display_range(&self, map: &DisplayMapSnapshot) -> Range { + let start = self.start.to_display_point(map); + let end = self.end.to_display_point(map); if self.reversed { end..start } else { @@ -94,23 +92,22 @@ impl Selection { pub fn buffer_rows_for_display_rows( &self, include_end_if_at_line_start: bool, - map: &DisplayMap, - cx: &AppContext, + map: &DisplayMapSnapshot, ) -> (Range, Range) { - let display_start = self.start.to_display_point(map, cx); + let display_start = self.start.to_display_point(map); let buffer_start = - DisplayPoint::new(display_start.row(), 0).to_buffer_point(map, Bias::Left, cx); + DisplayPoint::new(display_start.row(), 0).to_buffer_point(map, Bias::Left); - let mut display_end = self.end.to_display_point(map, cx); + let mut display_end = self.end.to_display_point(map); if !include_end_if_at_line_start - && display_end.row() != map.max_point(cx).row() + && display_end.row() != map.max_point().row() && display_start.row() != display_end.row() && display_end.column() == 0 { *display_end.row_mut() -= 1; } - let buffer_end = DisplayPoint::new(display_end.row(), map.line_len(display_end.row(), cx)) - .to_buffer_point(map, Bias::Left, cx); + let buffer_end = DisplayPoint::new(display_end.row(), map.line_len(display_end.row())) + .to_buffer_point(map, Bias::Left); ( buffer_start.row..buffer_end.row + 1, diff --git a/zed/src/editor/display_map.rs b/zed/src/editor/display_map.rs index cff0416fb52ade07e748c0da4eb24492a94b6201..03827fb1761eee9692742266616c08f1ad260741 100644 --- a/zed/src/editor/display_map.rs +++ b/zed/src/editor/display_map.rs @@ -26,6 +26,7 @@ impl DisplayMap { pub fn snapshot(&self, cx: &AppContext) -> DisplayMapSnapshot { DisplayMapSnapshot { + buffer_snapshot: self.buffer.read(cx).snapshot(), folds_snapshot: self.fold_map.snapshot(cx), tab_size: self.tab_size, } @@ -46,80 +47,10 @@ impl DisplayMap { ) { self.fold_map.unfold(ranges, cx) } - - pub fn intersects_fold(&self, offset: T, cx: &AppContext) -> bool { - self.fold_map.snapshot(cx).intersects_fold(offset) - } - - pub fn is_line_folded(&self, display_row: u32, cx: &AppContext) -> bool { - self.fold_map.snapshot(cx).is_line_folded(display_row) - } - - pub fn text(&self, cx: &AppContext) -> String { - self.snapshot(cx).chunks_at(DisplayPoint::zero()).collect() - } - - pub fn line(&self, display_row: u32, cx: &AppContext) -> String { - let mut result = String::new(); - for chunk in self - .snapshot(cx) - .chunks_at(DisplayPoint::new(display_row, 0)) - { - if let Some(ix) = chunk.find('\n') { - result.push_str(&chunk[0..ix]); - break; - } else { - result.push_str(chunk); - } - } - result - } - - pub fn line_indent(&self, display_row: u32, cx: &AppContext) -> (u32, bool) { - let mut indent = 0; - let mut is_blank = true; - for c in self - .snapshot(cx) - .chars_at(DisplayPoint::new(display_row, 0)) - { - if c == ' ' { - indent += 1; - } else { - is_blank = c == '\n'; - break; - } - } - (indent, is_blank) - } - - pub fn line_len(&self, row: u32, cx: &AppContext) -> u32 { - DisplayPoint::new(row, self.fold_map.snapshot(cx).line_len(row)) - .expand_tabs(self, cx) - .column() - } - - pub fn max_point(&self, cx: &AppContext) -> DisplayPoint { - self.snapshot(cx).max_point().expand_tabs(self, cx) - } - - pub fn longest_row(&self, cx: &AppContext) -> u32 { - self.fold_map.snapshot(cx).longest_row() - } - - pub fn anchor_before(&self, point: DisplayPoint, bias: Bias, cx: &AppContext) -> Anchor { - self.buffer - .read(cx) - .anchor_before(point.to_buffer_point(self, bias, cx)) - } - - pub fn anchor_after(&self, point: DisplayPoint, bias: Bias, cx: &AppContext) -> Anchor { - self.buffer - .read(cx) - .anchor_after(point.to_buffer_point(self, bias, cx)) - } } pub struct DisplayMapSnapshot { + buffer_snapshot: buffer::Snapshot, folds_snapshot: FoldMapSnapshot, tab_size: usize, } @@ -208,6 +139,64 @@ impl DisplayMapSnapshot { self.folds_snapshot.folds_in_range(range) } + pub fn intersects_fold(&self, offset: T) -> bool { + self.folds_snapshot.intersects_fold(offset) + } + + pub fn is_line_folded(&self, display_row: u32) -> bool { + self.folds_snapshot.is_line_folded(display_row) + } + + pub fn text(&self) -> String { + self.chunks_at(DisplayPoint::zero()).collect() + } + + pub fn line(&self, display_row: u32) -> String { + let mut result = String::new(); + for chunk in self.chunks_at(DisplayPoint::new(display_row, 0)) { + if let Some(ix) = chunk.find('\n') { + result.push_str(&chunk[0..ix]); + break; + } else { + result.push_str(chunk); + } + } + result + } + + pub fn line_indent(&self, display_row: u32) -> (u32, bool) { + let mut indent = 0; + let mut is_blank = true; + for c in self.chars_at(DisplayPoint::new(display_row, 0)) { + if c == ' ' { + indent += 1; + } else { + is_blank = c == '\n'; + break; + } + } + (indent, is_blank) + } + + pub fn line_len(&self, row: u32) -> u32 { + self.expand_tabs(DisplayPoint::new(row, self.folds_snapshot.line_len(row))) + .column() + } + + pub fn longest_row(&self) -> u32 { + self.folds_snapshot.longest_row() + } + + pub fn anchor_before(&self, point: DisplayPoint, bias: Bias) -> Anchor { + self.buffer_snapshot + .anchor_before(point.to_buffer_point(self, bias)) + } + + pub fn anchor_after(&self, point: DisplayPoint, bias: Bias) -> Anchor { + self.buffer_snapshot + .anchor_after(point.to_buffer_point(self, bias)) + } + fn expand_tabs(&self, mut point: DisplayPoint) -> DisplayPoint { let chars = self .folds_snapshot @@ -257,32 +246,23 @@ impl DisplayPoint { &mut self.0.column } - pub fn to_buffer_point(self, map: &DisplayMap, bias: Bias, cx: &AppContext) -> Point { - map.fold_map - .snapshot(cx) - .to_buffer_point(self.collapse_tabs(map, bias, cx)) - } - - pub fn to_buffer_offset(self, map: &DisplayMap, bias: Bias, cx: &AppContext) -> usize { - map.fold_map - .snapshot(cx) - .to_buffer_offset(self.collapse_tabs(&map, bias, cx)) + pub fn to_buffer_point(self, map: &DisplayMapSnapshot, bias: Bias) -> Point { + map.folds_snapshot + .to_buffer_point(map.collapse_tabs(self, bias).0) } - fn expand_tabs(self, map: &DisplayMap, cx: &AppContext) -> Self { - map.snapshot(cx).expand_tabs(self) - } - - fn collapse_tabs(self, map: &DisplayMap, bias: Bias, cx: &AppContext) -> Self { - map.snapshot(cx).collapse_tabs(self, bias).0 + pub fn to_buffer_offset(self, map: &DisplayMapSnapshot, bias: Bias) -> usize { + map.folds_snapshot + .to_buffer_offset(map.collapse_tabs(self, bias).0) } } impl Point { - pub fn to_display_point(self, map: &DisplayMap, cx: &AppContext) -> DisplayPoint { - let mut display_point = map.fold_map.snapshot(cx).to_display_point(self); - let snapshot = map.fold_map.snapshot(cx); - let chars = snapshot.chars_at(DisplayPoint::new(display_point.row(), 0)); + pub fn to_display_point(self, map: &DisplayMapSnapshot) -> DisplayPoint { + let mut display_point = map.folds_snapshot.to_display_point(self); + let chars = map + .folds_snapshot + .chars_at(DisplayPoint::new(display_point.row(), 0)); *display_point.column_mut() = expand_tabs(chars, display_point.column() as usize, map.tab_size) as u32; display_point @@ -290,8 +270,8 @@ impl Point { } impl Anchor { - pub fn to_display_point(&self, map: &DisplayMap, cx: &AppContext) -> DisplayPoint { - self.to_point(map.buffer.read(cx)).to_display_point(map, cx) + pub fn to_display_point(&self, map: &DisplayMapSnapshot) -> DisplayPoint { + self.to_point(&map.buffer_snapshot).to_display_point(map) } } @@ -610,9 +590,9 @@ mod tests { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx)); let cx = cx.as_ref(); let map = DisplayMap::new(buffer.clone(), 4, cx); - assert_eq!(map.text(cx), display_text); - let map = map.snapshot(cx); + + assert_eq!(map.text(), display_text); for (input_column, bias, output_column) in vec![ ("'a', '".len(), Left, "'a', '".len()), ("'a', '".len() + 1, Left, "'a', '".len()), @@ -652,62 +632,59 @@ mod tests { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx)); let cx = cx.as_ref(); let map = DisplayMap::new(buffer.clone(), 4, cx); - assert_eq!(map.text(cx), "āœ… α\nβ \nšŸ€Ī² γ"); + let map = map.snapshot(cx); + assert_eq!(map.text(), "āœ… α\nβ \nšŸ€Ī² γ"); let point = Point::new(0, "āœ…\t\t".len() as u32); let display_point = DisplayPoint::new(0, "āœ… ".len() as u32); - assert_eq!(point.to_display_point(&map, cx), display_point); - assert_eq!(display_point.to_buffer_point(&map, Bias::Left, cx), point,); + assert_eq!(point.to_display_point(&map), display_point); + assert_eq!(display_point.to_buffer_point(&map, Bias::Left), point,); let point = Point::new(1, "β\t".len() as u32); let display_point = DisplayPoint::new(1, "β ".len() as u32); - assert_eq!(point.to_display_point(&map, cx), display_point); - assert_eq!(display_point.to_buffer_point(&map, Bias::Left, cx), point,); + assert_eq!(point.to_display_point(&map), display_point); + assert_eq!(display_point.to_buffer_point(&map, Bias::Left), point,); let point = Point::new(2, "šŸ€Ī²\t\t".len() as u32); let display_point = DisplayPoint::new(2, "šŸ€Ī² ".len() as u32); - assert_eq!(point.to_display_point(&map, cx), display_point); - assert_eq!(display_point.to_buffer_point(&map, Bias::Left, cx), point,); + assert_eq!(point.to_display_point(&map), display_point); + assert_eq!(display_point.to_buffer_point(&map, Bias::Left), point,); // Display points inside of expanded tabs assert_eq!( - DisplayPoint::new(0, "āœ… ".len() as u32).to_buffer_point(&map, Bias::Right, cx), + DisplayPoint::new(0, "āœ… ".len() as u32).to_buffer_point(&map, Bias::Right), Point::new(0, "āœ…\t\t".len() as u32), ); assert_eq!( - DisplayPoint::new(0, "āœ… ".len() as u32).to_buffer_point(&map, Bias::Left, cx), + DisplayPoint::new(0, "āœ… ".len() as u32).to_buffer_point(&map, Bias::Left), Point::new(0, "āœ…\t".len() as u32), ); assert_eq!( - map.snapshot(cx) - .chunks_at(DisplayPoint::new(0, "āœ… ".len() as u32)) + map.chunks_at(DisplayPoint::new(0, "āœ… ".len() as u32)) .collect::(), " α\nβ \nšŸ€Ī² γ" ); assert_eq!( - DisplayPoint::new(0, "āœ… ".len() as u32).to_buffer_point(&map, Bias::Right, cx), + DisplayPoint::new(0, "āœ… ".len() as u32).to_buffer_point(&map, Bias::Right), Point::new(0, "āœ…\t".len() as u32), ); assert_eq!( - DisplayPoint::new(0, "āœ… ".len() as u32).to_buffer_point(&map, Bias::Left, cx), + DisplayPoint::new(0, "āœ… ".len() as u32).to_buffer_point(&map, Bias::Left), Point::new(0, "āœ…".len() as u32), ); assert_eq!( - map.snapshot(cx) - .chunks_at(DisplayPoint::new(0, "āœ… ".len() as u32)) + map.chunks_at(DisplayPoint::new(0, "āœ… ".len() as u32)) .collect::(), " α\nβ \nšŸ€Ī² γ" ); // Clipping display points inside of multi-byte characters assert_eq!( - map.snapshot(cx) - .clip_point(DisplayPoint::new(0, "āœ…".len() as u32 - 1), Bias::Left), + map.clip_point(DisplayPoint::new(0, "āœ…".len() as u32 - 1), Bias::Left), DisplayPoint::new(0, 0) ); assert_eq!( - map.snapshot(cx) - .clip_point(DisplayPoint::new(0, "āœ…".len() as u32 - 1), Bias::Right), + map.clip_point(DisplayPoint::new(0, "āœ…".len() as u32 - 1), Bias::Right), DisplayPoint::new(0, "āœ…".len() as u32) ); } @@ -716,6 +693,9 @@ mod tests { fn test_max_point(cx: &mut gpui::MutableAppContext) { let buffer = cx.add_model(|cx| Buffer::new(0, "aaa\n\t\tbbb", cx)); let map = DisplayMap::new(buffer.clone(), 4, cx.as_ref()); - assert_eq!(map.max_point(cx.as_ref()), DisplayPoint::new(1, 11)) + assert_eq!( + map.snapshot(cx.as_ref()).max_point(), + DisplayPoint::new(1, 11) + ) } } diff --git a/zed/src/editor/display_map/wrap_map.rs b/zed/src/editor/display_map/wrap_map.rs index 1fa5aa5e3af39863a37247c8b78ef3194bcc155c..24c19fe9458d6525570b5e67f47549c1719fe2f8 100644 --- a/zed/src/editor/display_map/wrap_map.rs +++ b/zed/src/editor/display_map/wrap_map.rs @@ -4,7 +4,7 @@ use crate::{ time, util::Bias, }; -use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task}; +use gpui::{Entity, ModelContext, ModelHandle, Task}; use parking_lot::Mutex; use postage::{ mpsc, diff --git a/zed/src/editor/movement.rs b/zed/src/editor/movement.rs index d7af40858b91edc86827b863dca9810dc00861d9..1a0f01c14520151c932f6756153159d22682f4e6 100644 --- a/zed/src/editor/movement.rs +++ b/zed/src/editor/movement.rs @@ -1,35 +1,32 @@ -use super::{Bias, DisplayMap, DisplayPoint, SelectionGoal}; +use super::{Bias, DisplayMapSnapshot, DisplayPoint, SelectionGoal}; use anyhow::Result; -use gpui::AppContext; -pub fn left(map: &DisplayMap, mut point: DisplayPoint, cx: &AppContext) -> Result { +pub fn left(map: &DisplayMapSnapshot, mut point: DisplayPoint) -> Result { if point.column() > 0 { *point.column_mut() -= 1; } else if point.row() > 0 { *point.row_mut() -= 1; - *point.column_mut() = map.line_len(point.row(), cx); + *point.column_mut() = map.line_len(point.row()); } - Ok(map.snapshot(cx).clip_point(point, Bias::Left)) + Ok(map.clip_point(point, Bias::Left)) } -pub fn right(map: &DisplayMap, mut point: DisplayPoint, cx: &AppContext) -> Result { - let max_column = map.line_len(point.row(), cx); +pub fn right(map: &DisplayMapSnapshot, mut point: DisplayPoint) -> Result { + let max_column = map.line_len(point.row()); if point.column() < max_column { *point.column_mut() += 1; - } else if point.row() < map.max_point(cx).row() { + } else if point.row() < map.max_point().row() { *point.row_mut() += 1; *point.column_mut() = 0; } - Ok(map.snapshot(cx).clip_point(point, Bias::Right)) + Ok(map.clip_point(point, Bias::Right)) } pub fn up( - map: &DisplayMap, + map: &DisplayMapSnapshot, mut point: DisplayPoint, goal: SelectionGoal, - cx: &AppContext, ) -> Result<(DisplayPoint, SelectionGoal)> { - let map = map.snapshot(cx); let goal_column = if let SelectionGoal::Column(column) = goal { column } else { @@ -47,13 +44,11 @@ pub fn up( } pub fn down( - map: &DisplayMap, + map: &DisplayMapSnapshot, mut point: DisplayPoint, goal: SelectionGoal, - cx: &AppContext, ) -> Result<(DisplayPoint, SelectionGoal)> { - let max_point = map.max_point(cx); - let map = map.snapshot(cx); + let max_point = map.max_point(); let goal_column = if let SelectionGoal::Column(column) = goal { column } else { @@ -71,12 +66,11 @@ pub fn down( } pub fn line_beginning( - map: &DisplayMap, + map: &DisplayMapSnapshot, point: DisplayPoint, toggle_indent: bool, - cx: &AppContext, ) -> Result { - let (indent, is_blank) = map.line_indent(point.row(), cx); + let (indent, is_blank) = map.line_indent(point.row()); if toggle_indent && !is_blank && point.column() != indent { Ok(DisplayPoint::new(point.row(), indent)) } else { @@ -84,30 +78,23 @@ pub fn line_beginning( } } -pub fn line_end(map: &DisplayMap, point: DisplayPoint, cx: &AppContext) -> Result { - Ok(DisplayPoint::new( - point.row(), - map.line_len(point.row(), cx), - )) +pub fn line_end(map: &DisplayMapSnapshot, point: DisplayPoint) -> Result { + Ok(DisplayPoint::new(point.row(), map.line_len(point.row()))) } -pub fn prev_word_boundary( - map: &DisplayMap, - point: DisplayPoint, - cx: &AppContext, -) -> Result { +pub fn prev_word_boundary(map: &DisplayMapSnapshot, point: DisplayPoint) -> Result { if point.column() == 0 { if point.row() == 0 { Ok(DisplayPoint::new(0, 0)) } else { let row = point.row() - 1; - Ok(DisplayPoint::new(row, map.line_len(row, cx))) + Ok(DisplayPoint::new(row, map.line_len(row))) } } else { let mut boundary = DisplayPoint::new(point.row(), 0); let mut column = 0; let mut prev_c = None; - for c in map.snapshot(cx).chars_at(boundary) { + for c in map.chars_at(boundary) { if column >= point.column() { break; } @@ -124,12 +111,11 @@ pub fn prev_word_boundary( } pub fn next_word_boundary( - map: &DisplayMap, + map: &DisplayMapSnapshot, mut point: DisplayPoint, - cx: &AppContext, ) -> Result { let mut prev_c = None; - for c in map.snapshot(cx).chars_at(point) { + for c in map.chars_at(point) { if prev_c.is_some() && (c == '\n' || char_kind(prev_c.unwrap()) != char_kind(c)) { break; }