mirror of
https://github.com/zed-industries/zed.git
synced 2026-05-31 19:05:00 +07:00
Reduce display_map snapshot creation (#39354)
Re-applies https://github.com/zed-industries/zed/pull/30840 This PR re-applies the initial [PR](https://github.com/zed-industries/zed/pull/30840). As it was closed because it was hard to land, because of the many conflicts. This PR re-applies the changes for it. In several cases we were creating multiple display_map snapshots within the same root-level function call. Creating a display_map snapshot is quite slow, and in some cases we were creating the snapshot multiple times. Release Notes: - N/A
This commit is contained in:
parent
ef5b8c6fed
commit
7e97fcaacb
60 changed files with 853 additions and 426 deletions
|
|
@ -652,7 +652,9 @@ impl ContextPickerCompletionProvider {
|
|||
.active_item(cx)
|
||||
.and_then(|item| item.downcast::<Editor>())
|
||||
.is_some_and(|editor| {
|
||||
editor.update(cx, |editor, cx| editor.has_non_empty_selection(cx))
|
||||
editor.update(cx, |editor, cx| {
|
||||
editor.has_non_empty_selection(&editor.display_snapshot(cx))
|
||||
})
|
||||
});
|
||||
if has_selection {
|
||||
entries.push(ContextPickerEntry::Action(
|
||||
|
|
|
|||
|
|
@ -452,7 +452,10 @@ fn update_editor_selection(
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Editor>,
|
||||
) {
|
||||
let newest_cursor = editor.selections.newest::<Point>(cx).head();
|
||||
let newest_cursor = editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx))
|
||||
.head();
|
||||
|
||||
if !diff_hunks.iter().any(|hunk| {
|
||||
hunk.row_range
|
||||
|
|
@ -1895,7 +1898,9 @@ mod tests {
|
|||
);
|
||||
assert_eq!(
|
||||
editor
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(1, 0)..Point::new(1, 0)
|
||||
);
|
||||
|
|
@ -1909,7 +1914,9 @@ mod tests {
|
|||
);
|
||||
assert_eq!(
|
||||
editor
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(3, 0)..Point::new(3, 0)
|
||||
);
|
||||
|
|
@ -1930,7 +1937,9 @@ mod tests {
|
|||
);
|
||||
assert_eq!(
|
||||
editor
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(3, 0)..Point::new(3, 0)
|
||||
);
|
||||
|
|
@ -1962,7 +1971,9 @@ mod tests {
|
|||
);
|
||||
assert_eq!(
|
||||
editor
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(3, 0)..Point::new(3, 0)
|
||||
);
|
||||
|
|
@ -2119,7 +2130,9 @@ mod tests {
|
|||
);
|
||||
assert_eq!(
|
||||
editor1
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(1, 0)..Point::new(1, 0)
|
||||
);
|
||||
|
|
@ -2160,7 +2173,9 @@ mod tests {
|
|||
);
|
||||
assert_eq!(
|
||||
editor1
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(3, 0)..Point::new(3, 0)
|
||||
);
|
||||
|
|
@ -2181,7 +2196,9 @@ mod tests {
|
|||
);
|
||||
assert_eq!(
|
||||
editor1
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(3, 0)..Point::new(3, 0)
|
||||
);
|
||||
|
|
@ -2207,7 +2224,9 @@ mod tests {
|
|||
);
|
||||
assert_eq!(
|
||||
editor1
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(3, 0)..Point::new(3, 0)
|
||||
);
|
||||
|
|
@ -2240,7 +2259,9 @@ mod tests {
|
|||
);
|
||||
assert_eq!(
|
||||
editor2
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(0, 0)..Point::new(0, 0)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -606,7 +606,11 @@ pub(crate) fn available_context_picker_entries(
|
|||
.read(cx)
|
||||
.active_item(cx)
|
||||
.and_then(|item| item.downcast::<Editor>())
|
||||
.is_some_and(|editor| editor.update(cx, |editor, cx| editor.has_non_empty_selection(cx)));
|
||||
.is_some_and(|editor| {
|
||||
editor.update(cx, |editor, cx| {
|
||||
editor.has_non_empty_selection(&editor.display_snapshot(cx))
|
||||
})
|
||||
});
|
||||
if has_selection {
|
||||
entries.push(ContextPickerEntry::Action(
|
||||
ContextPickerAction::AddSelections,
|
||||
|
|
@ -725,7 +729,7 @@ pub(crate) fn selection_ranges(
|
|||
};
|
||||
|
||||
editor.update(cx, |editor, cx| {
|
||||
let selections = editor.selections.all_adjusted(cx);
|
||||
let selections = editor.selections.all_adjusted(&editor.display_snapshot(cx));
|
||||
|
||||
let buffer = editor.buffer().clone().read(cx);
|
||||
let snapshot = buffer.snapshot(cx);
|
||||
|
|
|
|||
|
|
@ -363,9 +363,12 @@ impl InlineAssistant {
|
|||
cx: &mut App,
|
||||
) {
|
||||
let (snapshot, initial_selections, newest_selection) = editor.update(cx, |editor, cx| {
|
||||
let selections = editor.selections.all::<Point>(cx);
|
||||
let newest_selection = editor.selections.newest::<Point>(cx);
|
||||
(editor.snapshot(window, cx), selections, newest_selection)
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let selections = editor.selections.all::<Point>(&snapshot.display_snapshot);
|
||||
let newest_selection = editor
|
||||
.selections
|
||||
.newest::<Point>(&snapshot.display_snapshot);
|
||||
(snapshot, selections, newest_selection)
|
||||
});
|
||||
|
||||
// Check if there is already an inline assistant that contains the
|
||||
|
|
@ -798,7 +801,9 @@ impl InlineAssistant {
|
|||
if editor.read(cx).selections.count() == 1 {
|
||||
let (selection, buffer) = editor.update(cx, |editor, cx| {
|
||||
(
|
||||
editor.selections.newest::<usize>(cx),
|
||||
editor
|
||||
.selections
|
||||
.newest::<usize>(&editor.display_snapshot(cx)),
|
||||
editor.buffer().read(cx).snapshot(cx),
|
||||
)
|
||||
});
|
||||
|
|
@ -829,7 +834,9 @@ impl InlineAssistant {
|
|||
if editor.read(cx).selections.count() == 1 {
|
||||
let (selection, buffer) = editor.update(cx, |editor, cx| {
|
||||
(
|
||||
editor.selections.newest::<usize>(cx),
|
||||
editor
|
||||
.selections
|
||||
.newest::<usize>(&editor.display_snapshot(cx)),
|
||||
editor.buffer().read(cx).snapshot(cx),
|
||||
)
|
||||
});
|
||||
|
|
|
|||
|
|
@ -431,9 +431,9 @@ impl TextThreadEditor {
|
|||
}
|
||||
|
||||
fn cursors(&self, cx: &mut App) -> Vec<usize> {
|
||||
let selections = self
|
||||
.editor
|
||||
.update(cx, |editor, cx| editor.selections.all::<usize>(cx));
|
||||
let selections = self.editor.update(cx, |editor, cx| {
|
||||
editor.selections.all::<usize>(&editor.display_snapshot(cx))
|
||||
});
|
||||
selections
|
||||
.into_iter()
|
||||
.map(|selection| selection.head())
|
||||
|
|
@ -446,7 +446,10 @@ impl TextThreadEditor {
|
|||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| s.try_cancel());
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
let newest_cursor = editor.selections.newest::<Point>(cx).head();
|
||||
let newest_cursor = editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx))
|
||||
.head();
|
||||
if newest_cursor.column > 0
|
||||
|| snapshot
|
||||
.chars_at(newest_cursor)
|
||||
|
|
@ -1248,11 +1251,19 @@ impl TextThreadEditor {
|
|||
|
||||
let context_editor = context_editor_view.read(cx).editor.clone();
|
||||
context_editor.update(cx, |context_editor, cx| {
|
||||
if context_editor.selections.newest::<Point>(cx).is_empty() {
|
||||
let display_map = context_editor.display_snapshot(cx);
|
||||
if context_editor
|
||||
.selections
|
||||
.newest::<Point>(&display_map)
|
||||
.is_empty()
|
||||
{
|
||||
let snapshot = context_editor.buffer().read(cx).snapshot(cx);
|
||||
let (_, _, snapshot) = snapshot.as_singleton()?;
|
||||
|
||||
let head = context_editor.selections.newest::<Point>(cx).head();
|
||||
let head = context_editor
|
||||
.selections
|
||||
.newest::<Point>(&display_map)
|
||||
.head();
|
||||
let offset = snapshot.point_to_offset(head);
|
||||
|
||||
let surrounding_code_block_range = find_surrounding_code_block(snapshot, offset)?;
|
||||
|
|
@ -1269,7 +1280,7 @@ impl TextThreadEditor {
|
|||
|
||||
(!text.is_empty()).then_some((text, true))
|
||||
} else {
|
||||
let selection = context_editor.selections.newest_adjusted(cx);
|
||||
let selection = context_editor.selections.newest_adjusted(&display_map);
|
||||
let buffer = context_editor.buffer().read(cx).snapshot(cx);
|
||||
let selected_text = buffer.text_for_range(selection.range()).collect::<String>();
|
||||
|
||||
|
|
@ -1457,7 +1468,7 @@ impl TextThreadEditor {
|
|||
let selections = editor.update(cx, |editor, cx| {
|
||||
editor
|
||||
.selections
|
||||
.all_adjusted(cx)
|
||||
.all_adjusted(&editor.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.filter_map(|s| {
|
||||
(!s.is_empty())
|
||||
|
|
@ -1489,7 +1500,10 @@ impl TextThreadEditor {
|
|||
self.editor.update(cx, |editor, cx| {
|
||||
editor.insert("\n", window, cx);
|
||||
for (text, crease_title) in creases {
|
||||
let point = editor.selections.newest::<Point>(cx).head();
|
||||
let point = editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx))
|
||||
.head();
|
||||
let start_row = MultiBufferRow(point.row);
|
||||
|
||||
editor.insert(&text, window, cx);
|
||||
|
|
@ -1561,7 +1575,9 @@ impl TextThreadEditor {
|
|||
cx: &mut Context<Self>,
|
||||
) -> (String, CopyMetadata, Vec<text::Selection<usize>>) {
|
||||
let (mut selection, creases) = self.editor.update(cx, |editor, cx| {
|
||||
let mut selection = editor.selections.newest_adjusted(cx);
|
||||
let mut selection = editor
|
||||
.selections
|
||||
.newest_adjusted(&editor.display_snapshot(cx));
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
|
||||
selection.goal = SelectionGoal::None;
|
||||
|
|
@ -1680,7 +1696,10 @@ impl TextThreadEditor {
|
|||
|
||||
if images.is_empty() {
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
let paste_position = editor.selections.newest::<usize>(cx).head();
|
||||
let paste_position = editor
|
||||
.selections
|
||||
.newest::<usize>(&editor.display_snapshot(cx))
|
||||
.head();
|
||||
editor.paste(action, window, cx);
|
||||
|
||||
if let Some(metadata) = metadata {
|
||||
|
|
@ -1727,13 +1746,13 @@ impl TextThreadEditor {
|
|||
editor.transact(window, cx, |editor, _window, cx| {
|
||||
let edits = editor
|
||||
.selections
|
||||
.all::<usize>(cx)
|
||||
.all::<usize>(&editor.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.map(|selection| (selection.start..selection.end, "\n"));
|
||||
editor.edit(edits, cx);
|
||||
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
for selection in editor.selections.all::<usize>(cx) {
|
||||
for selection in editor.selections.all::<usize>(&editor.display_snapshot(cx)) {
|
||||
image_positions.push(snapshot.anchor_before(selection.end));
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ impl SlashCommand for SelectionCommand {
|
|||
editor.update(cx, |editor, cx| {
|
||||
let selection_ranges = editor
|
||||
.selections
|
||||
.all_adjusted(cx)
|
||||
.all_adjusted(&editor.display_snapshot(cx))
|
||||
.iter()
|
||||
.map(|selection| selection.range())
|
||||
.collect::<Vec<_>>();
|
||||
|
|
|
|||
|
|
@ -877,7 +877,7 @@ async fn test_collaborating_with_renames(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
6..9
|
||||
);
|
||||
rename.editor.update(cx, |rename_editor, cx| {
|
||||
let rename_selection = rename_editor.selections.newest::<usize>(cx);
|
||||
let rename_selection = rename_editor.selections.newest::<usize>(&rename_editor.display_snapshot(cx));
|
||||
assert_eq!(
|
||||
rename_selection.range(),
|
||||
0..3,
|
||||
|
|
@ -924,7 +924,7 @@ async fn test_collaborating_with_renames(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
let lsp_rename_end = rename.range.end.to_offset(&buffer);
|
||||
assert_eq!(lsp_rename_start..lsp_rename_end, 6..9);
|
||||
rename.editor.update(cx, |rename_editor, cx| {
|
||||
let rename_selection = rename_editor.selections.newest::<usize>(cx);
|
||||
let rename_selection = rename_editor.selections.newest::<usize>(&rename_editor.display_snapshot(cx));
|
||||
assert_eq!(
|
||||
rename_selection.range(),
|
||||
1..2,
|
||||
|
|
|
|||
|
|
@ -122,13 +122,19 @@ async fn test_basic_following(
|
|||
editor.handle_input("b", window, cx);
|
||||
editor.handle_input("c", window, cx);
|
||||
editor.select_left(&Default::default(), window, cx);
|
||||
assert_eq!(editor.selections.ranges(cx), vec![3..2]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
vec![3..2]
|
||||
);
|
||||
});
|
||||
editor_a2.update_in(cx_a, |editor, window, cx| {
|
||||
editor.handle_input("d", window, cx);
|
||||
editor.handle_input("e", window, cx);
|
||||
editor.select_left(&Default::default(), window, cx);
|
||||
assert_eq!(editor.selections.ranges(cx), vec![2..1]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
vec![2..1]
|
||||
);
|
||||
});
|
||||
|
||||
// When client B starts following client A, only the active view state is replicated to client B.
|
||||
|
|
@ -149,11 +155,15 @@ async fn test_basic_following(
|
|||
Some((worktree_id, rel_path("2.txt")).into())
|
||||
);
|
||||
assert_eq!(
|
||||
editor_b2.update(cx_b, |editor, cx| editor.selections.ranges(cx)),
|
||||
editor_b2.update(cx_b, |editor, cx| editor
|
||||
.selections
|
||||
.ranges(&editor.display_snapshot(cx))),
|
||||
vec![2..1]
|
||||
);
|
||||
assert_eq!(
|
||||
editor_b1.update(cx_b, |editor, cx| editor.selections.ranges(cx)),
|
||||
editor_b1.update(cx_b, |editor, cx| editor
|
||||
.selections
|
||||
.ranges(&editor.display_snapshot(cx))),
|
||||
vec![3..3]
|
||||
);
|
||||
|
||||
|
|
@ -384,7 +394,10 @@ async fn test_basic_following(
|
|||
cx_b.background_executor.run_until_parked();
|
||||
|
||||
editor_b1.update(cx_b, |editor, cx| {
|
||||
assert_eq!(editor.selections.ranges(cx), &[1..1, 2..2]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
&[1..1, 2..2]
|
||||
);
|
||||
});
|
||||
|
||||
editor_a1.update_in(cx_a, |editor, window, cx| {
|
||||
|
|
@ -402,7 +415,10 @@ async fn test_basic_following(
|
|||
executor.advance_clock(workspace::item::LEADER_UPDATE_THROTTLE);
|
||||
executor.run_until_parked();
|
||||
editor_b1.update(cx_b, |editor, cx| {
|
||||
assert_eq!(editor.selections.ranges(cx), &[3..3]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
&[3..3]
|
||||
);
|
||||
});
|
||||
|
||||
// After unfollowing, client B stops receiving updates from client A.
|
||||
|
|
@ -1679,7 +1695,10 @@ async fn test_following_stops_on_unshare(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
.advance_clock(workspace::item::LEADER_UPDATE_THROTTLE);
|
||||
cx_a.run_until_parked();
|
||||
editor_b.update(cx_b, |editor, cx| {
|
||||
assert_eq!(editor.selections.ranges(cx), vec![1..1])
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
vec![1..1]
|
||||
)
|
||||
});
|
||||
|
||||
// a unshares the project
|
||||
|
|
@ -1701,7 +1720,10 @@ async fn test_following_stops_on_unshare(cx_a: &mut TestAppContext, cx_b: &mut T
|
|||
.advance_clock(workspace::item::LEADER_UPDATE_THROTTLE);
|
||||
cx_a.run_until_parked();
|
||||
editor_b.update(cx_b, |editor, cx| {
|
||||
assert_eq!(editor.selections.ranges(cx), vec![1..1])
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
vec![1..1]
|
||||
)
|
||||
});
|
||||
cx_b.update(|_, cx| {
|
||||
let room = ActiveCall::global(cx).read(cx).room().unwrap().read(cx);
|
||||
|
|
@ -1799,13 +1821,19 @@ async fn test_following_into_excluded_file(
|
|||
editor.handle_input("b", window, cx);
|
||||
editor.handle_input("c", window, cx);
|
||||
editor.select_left(&Default::default(), window, cx);
|
||||
assert_eq!(editor.selections.ranges(cx), vec![3..2]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
vec![3..2]
|
||||
);
|
||||
});
|
||||
editor_for_excluded_a.update_in(cx_a, |editor, window, cx| {
|
||||
editor.select_all(&Default::default(), window, cx);
|
||||
editor.handle_input("new commit message", window, cx);
|
||||
editor.select_left(&Default::default(), window, cx);
|
||||
assert_eq!(editor.selections.ranges(cx), vec![18..17]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
vec![18..17]
|
||||
);
|
||||
});
|
||||
|
||||
// When client B starts following client A, currently visible file is replicated
|
||||
|
|
@ -1827,7 +1855,9 @@ async fn test_following_into_excluded_file(
|
|||
Some((worktree_id, rel_path(".git/COMMIT_EDITMSG")).into())
|
||||
);
|
||||
assert_eq!(
|
||||
editor_for_excluded_b.update(cx_b, |editor, cx| editor.selections.ranges(cx)),
|
||||
editor_for_excluded_b.update(cx_b, |editor, cx| editor
|
||||
.selections
|
||||
.ranges(&editor.display_snapshot(cx))),
|
||||
vec![18..17]
|
||||
);
|
||||
|
||||
|
|
@ -2037,7 +2067,12 @@ async fn test_following_to_channel_notes_without_a_shared_project(
|
|||
assert_eq!(notes.channel(cx).unwrap().name, "channel-1");
|
||||
notes.editor.update(cx, |editor, cx| {
|
||||
assert_eq!(editor.text(cx), "Hello from A.");
|
||||
assert_eq!(editor.selections.ranges::<usize>(cx), &[3..4]);
|
||||
assert_eq!(
|
||||
editor
|
||||
.selections
|
||||
.ranges::<usize>(&editor.display_snapshot(cx)),
|
||||
&[3..4]
|
||||
);
|
||||
})
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -287,9 +287,12 @@ impl ChannelView {
|
|||
}
|
||||
|
||||
fn copy_link(&mut self, _: &CopyLink, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let position = self
|
||||
.editor
|
||||
.update(cx, |editor, cx| editor.selections.newest_display(cx).start);
|
||||
let position = self.editor.update(cx, |editor, cx| {
|
||||
editor
|
||||
.selections
|
||||
.newest_display(&editor.display_snapshot(cx))
|
||||
.start
|
||||
});
|
||||
self.copy_link_for_position(position, window, cx)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -698,7 +698,11 @@ mod tests {
|
|||
editor.update_in(cx, |editor, window, cx| {
|
||||
assert!(editor.focus_handle(cx).is_focused(window));
|
||||
assert_eq!(
|
||||
editor.selections.last::<Point>(cx).range().start,
|
||||
editor
|
||||
.selections
|
||||
.last::<Point>(&editor.display_snapshot(cx))
|
||||
.range()
|
||||
.start,
|
||||
Point::new(2, 0)
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -341,8 +341,10 @@ pub fn init(cx: &mut App) {
|
|||
maybe!({
|
||||
let (buffer, position, _) = editor
|
||||
.update(cx, |editor, cx| {
|
||||
let cursor_point: language::Point =
|
||||
editor.selections.newest(cx).head();
|
||||
let cursor_point: language::Point = editor
|
||||
.selections
|
||||
.newest(&editor.display_snapshot(cx))
|
||||
.head();
|
||||
|
||||
editor
|
||||
.buffer()
|
||||
|
|
@ -392,7 +394,10 @@ pub fn init(cx: &mut App) {
|
|||
let text = editor
|
||||
.update(cx, |editor, cx| {
|
||||
editor.text_for_range(
|
||||
editor.selections.newest(cx).range(),
|
||||
editor
|
||||
.selections
|
||||
.newest(&editor.display_snapshot(cx))
|
||||
.range(),
|
||||
&mut None,
|
||||
window,
|
||||
cx,
|
||||
|
|
|
|||
|
|
@ -963,8 +963,12 @@ mod tests {
|
|||
) {
|
||||
cx.set_state(input);
|
||||
|
||||
let buffer_position =
|
||||
cx.editor(|editor, _, cx| editor.selections.newest::<Point>(cx).start);
|
||||
let buffer_position = cx.editor(|editor, _, cx| {
|
||||
editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx))
|
||||
.start
|
||||
});
|
||||
|
||||
let snapshot = &cx.buffer_snapshot();
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,10 @@ impl StackTraceView {
|
|||
cx.subscribe_in(&editor, window, |this, editor, event, window, cx| {
|
||||
if let EditorEvent::SelectionsChanged { local: true } = event {
|
||||
let excerpt_id = editor.update(cx, |editor, cx| {
|
||||
let position: Point = editor.selections.newest(cx).head();
|
||||
let position: Point = editor
|
||||
.selections
|
||||
.newest(&editor.display_snapshot(cx))
|
||||
.head();
|
||||
|
||||
editor
|
||||
.snapshot(window, cx)
|
||||
|
|
|
|||
|
|
@ -231,7 +231,10 @@ async fn test_save_debug_scenario_to_file(executor: BackgroundExecutor, cx: &mut
|
|||
|
||||
editor.update(cx, |editor, cx| {
|
||||
assert_eq!(
|
||||
editor.selections.newest::<Point>(cx).head(),
|
||||
editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx))
|
||||
.head(),
|
||||
Point::new(5, 2)
|
||||
)
|
||||
});
|
||||
|
|
|
|||
|
|
@ -170,7 +170,10 @@ impl DiagnosticIndicator {
|
|||
fn update(&mut self, editor: Entity<Editor>, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let (buffer, cursor_position) = editor.update(cx, |editor, cx| {
|
||||
let buffer = editor.buffer().read(cx).snapshot(cx);
|
||||
let cursor_position = editor.selections.newest::<usize>(cx).head();
|
||||
let cursor_position = editor
|
||||
.selections
|
||||
.newest::<usize>(&editor.display_snapshot(cx))
|
||||
.head();
|
||||
(buffer, cursor_position)
|
||||
});
|
||||
let new_diagnostic = buffer
|
||||
|
|
|
|||
|
|
@ -2323,21 +2323,22 @@ impl Editor {
|
|||
}
|
||||
EditorEvent::Edited { .. } => {
|
||||
if !vim_enabled(cx) {
|
||||
let (map, selections) = editor.selections.all_adjusted_display(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let selections = editor.selections.all_adjusted_display(&display_map);
|
||||
let pop_state = editor
|
||||
.change_list
|
||||
.last()
|
||||
.map(|previous| {
|
||||
previous.len() == selections.len()
|
||||
&& previous.iter().enumerate().all(|(ix, p)| {
|
||||
p.to_display_point(&map).row()
|
||||
p.to_display_point(&display_map).row()
|
||||
== selections[ix].head().row()
|
||||
})
|
||||
})
|
||||
.unwrap_or(false);
|
||||
let new_positions = selections
|
||||
.into_iter()
|
||||
.map(|s| map.display_point_to_anchor(s.head(), Bias::Left))
|
||||
.map(|s| display_map.display_point_to_anchor(s.head(), Bias::Left))
|
||||
.collect();
|
||||
editor
|
||||
.change_list
|
||||
|
|
@ -2408,6 +2409,10 @@ impl Editor {
|
|||
editor
|
||||
}
|
||||
|
||||
pub fn display_snapshot(&self, cx: &mut App) -> DisplaySnapshot {
|
||||
self.selections.display_map(cx)
|
||||
}
|
||||
|
||||
pub fn deploy_mouse_context_menu(
|
||||
&mut self,
|
||||
position: gpui::Point<Pixels>,
|
||||
|
|
@ -2443,7 +2448,7 @@ impl Editor {
|
|||
}
|
||||
|
||||
self.selections
|
||||
.disjoint_in_range::<usize>(range.clone(), cx)
|
||||
.disjoint_in_range::<usize>(range.clone(), &self.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.any(|selection| {
|
||||
// This is needed to cover a corner case, if we just check for an existing
|
||||
|
|
@ -3039,7 +3044,7 @@ impl Editor {
|
|||
// Copy selections to primary selection buffer
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
|
||||
if local {
|
||||
let selections = self.selections.all::<usize>(cx);
|
||||
let selections = self.selections.all::<usize>(&self.display_snapshot(cx));
|
||||
let buffer_handle = self.buffer.read(cx).read(cx);
|
||||
|
||||
let mut text = String::new();
|
||||
|
|
@ -3491,7 +3496,7 @@ impl Editor {
|
|||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let tail = self.selections.newest::<usize>(cx).tail();
|
||||
let tail = self.selections.newest::<usize>(&display_map).tail();
|
||||
let click_count = click_count.max(match self.selections.select_mode() {
|
||||
SelectMode::Character => 1,
|
||||
SelectMode::Word(_) => 2,
|
||||
|
|
@ -3610,7 +3615,7 @@ impl Editor {
|
|||
|
||||
let point_to_delete: Option<usize> = {
|
||||
let selected_points: Vec<Selection<Point>> =
|
||||
self.selections.disjoint_in_range(start..end, cx);
|
||||
self.selections.disjoint_in_range(start..end, &display_map);
|
||||
|
||||
if !add || click_count > 1 {
|
||||
None
|
||||
|
|
@ -3686,7 +3691,7 @@ impl Editor {
|
|||
);
|
||||
};
|
||||
|
||||
let tail = self.selections.newest::<Point>(cx).tail();
|
||||
let tail = self.selections.newest::<Point>(&display_map).tail();
|
||||
let selection_anchor = display_map.buffer_snapshot().anchor_before(tail);
|
||||
self.columnar_selection_state = match mode {
|
||||
ColumnarMode::FromMouse => Some(ColumnarSelectionState::FromMouse {
|
||||
|
|
@ -3813,7 +3818,7 @@ impl Editor {
|
|||
fn end_selection(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.columnar_selection_state.take();
|
||||
if let Some(pending_mode) = self.selections.pending_mode() {
|
||||
let selections = self.selections.all::<usize>(cx);
|
||||
let selections = self.selections.all::<usize>(&self.display_snapshot(cx));
|
||||
self.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
s.select(selections);
|
||||
s.clear_pending();
|
||||
|
|
@ -3902,9 +3907,9 @@ impl Editor {
|
|||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn has_non_empty_selection(&self, cx: &mut App) -> bool {
|
||||
pub fn has_non_empty_selection(&self, snapshot: &DisplaySnapshot) -> bool {
|
||||
self.selections
|
||||
.all_adjusted(cx)
|
||||
.all_adjusted(snapshot)
|
||||
.iter()
|
||||
.any(|selection| !selection.is_empty())
|
||||
}
|
||||
|
|
@ -4053,7 +4058,7 @@ impl Editor {
|
|||
|
||||
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
|
||||
|
||||
let selections = self.selections.all_adjusted(cx);
|
||||
let selections = self.selections.all_adjusted(&self.display_snapshot(cx));
|
||||
let mut bracket_inserted = false;
|
||||
let mut edits = Vec::new();
|
||||
let mut linked_edits = HashMap::<_, Vec<_>>::default();
|
||||
|
|
@ -4403,7 +4408,7 @@ impl Editor {
|
|||
let trigger_in_words =
|
||||
this.show_edit_predictions_in_menu() || !had_active_edit_prediction;
|
||||
if this.hard_wrap.is_some() {
|
||||
let latest: Range<Point> = this.selections.newest(cx).range();
|
||||
let latest: Range<Point> = this.selections.newest(&map).range();
|
||||
if latest.is_empty()
|
||||
&& this
|
||||
.buffer()
|
||||
|
|
@ -4479,7 +4484,7 @@ impl Editor {
|
|||
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
|
||||
self.transact(window, cx, |this, window, cx| {
|
||||
let (edits_with_flags, selection_info): (Vec<_>, Vec<_>) = {
|
||||
let selections = this.selections.all::<usize>(cx);
|
||||
let selections = this.selections.all::<usize>(&this.display_snapshot(cx));
|
||||
let multi_buffer = this.buffer.read(cx);
|
||||
let buffer = multi_buffer.snapshot(cx);
|
||||
selections
|
||||
|
|
@ -4771,7 +4776,12 @@ impl Editor {
|
|||
let mut edits = Vec::new();
|
||||
let mut rows = Vec::new();
|
||||
|
||||
for (rows_inserted, selection) in self.selections.all_adjusted(cx).into_iter().enumerate() {
|
||||
for (rows_inserted, selection) in self
|
||||
.selections
|
||||
.all_adjusted(&self.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
{
|
||||
let cursor = selection.head();
|
||||
let row = cursor.row;
|
||||
|
||||
|
|
@ -4831,7 +4841,7 @@ impl Editor {
|
|||
let mut rows = Vec::new();
|
||||
let mut rows_inserted = 0;
|
||||
|
||||
for selection in self.selections.all_adjusted(cx) {
|
||||
for selection in self.selections.all_adjusted(&self.display_snapshot(cx)) {
|
||||
let cursor = selection.head();
|
||||
let row = cursor.row;
|
||||
|
||||
|
|
@ -4903,7 +4913,7 @@ impl Editor {
|
|||
|
||||
let text: Arc<str> = text.into();
|
||||
self.transact(window, cx, |this, window, cx| {
|
||||
let old_selections = this.selections.all_adjusted(cx);
|
||||
let old_selections = this.selections.all_adjusted(&this.display_snapshot(cx));
|
||||
let selection_anchors = this.buffer.update(cx, |buffer, cx| {
|
||||
let anchors = {
|
||||
let snapshot = buffer.read(cx);
|
||||
|
|
@ -5013,7 +5023,7 @@ impl Editor {
|
|||
/// If any empty selections is touching the start of its innermost containing autoclose
|
||||
/// region, expand it to select the brackets.
|
||||
fn select_autoclose_pair(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let selections = self.selections.all::<usize>(cx);
|
||||
let selections = self.selections.all::<usize>(&self.display_snapshot(cx));
|
||||
let buffer = self.buffer.read(cx).read(cx);
|
||||
let new_selections = self
|
||||
.selections_with_autoclose_regions(selections, &buffer)
|
||||
|
|
@ -6010,7 +6020,7 @@ impl Editor {
|
|||
let prefix = &old_text[..old_text.len().saturating_sub(lookahead)];
|
||||
let suffix = &old_text[lookbehind.min(old_text.len())..];
|
||||
|
||||
let selections = self.selections.all::<usize>(cx);
|
||||
let selections = self.selections.all::<usize>(&self.display_snapshot(cx));
|
||||
let mut ranges = Vec::new();
|
||||
let mut linked_edits = HashMap::<_, Vec<_>>::default();
|
||||
|
||||
|
|
@ -6162,7 +6172,10 @@ impl Editor {
|
|||
Some(CodeActionSource::Indicator(row)) | Some(CodeActionSource::RunMenu(row)) => {
|
||||
DisplayPoint::new(*row, 0).to_point(&snapshot)
|
||||
}
|
||||
_ => self.selections.newest::<Point>(cx).head(),
|
||||
_ => self
|
||||
.selections
|
||||
.newest::<Point>(&snapshot.display_snapshot)
|
||||
.head(),
|
||||
};
|
||||
let Some((buffer, buffer_row)) = snapshot
|
||||
.buffer_snapshot()
|
||||
|
|
@ -6624,7 +6637,9 @@ impl Editor {
|
|||
if newest_selection.head().diff_base_anchor.is_some() {
|
||||
return None;
|
||||
}
|
||||
let newest_selection_adjusted = this.selections.newest_adjusted(cx);
|
||||
let display_snapshot = this.display_snapshot(cx);
|
||||
let newest_selection_adjusted =
|
||||
this.selections.newest_adjusted(&display_snapshot);
|
||||
let buffer = this.buffer.read(cx);
|
||||
|
||||
let (start_buffer, start) =
|
||||
|
|
@ -6699,7 +6714,10 @@ impl Editor {
|
|||
|
||||
pub fn blame_hover(&mut self, _: &BlameHover, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let snapshot = self.snapshot(window, cx);
|
||||
let cursor = self.selections.newest::<Point>(cx).head();
|
||||
let cursor = self
|
||||
.selections
|
||||
.newest::<Point>(&snapshot.display_snapshot)
|
||||
.head();
|
||||
let Some((buffer, point, _)) = snapshot.buffer_snapshot().point_to_buffer_point(cursor)
|
||||
else {
|
||||
return;
|
||||
|
|
@ -7572,7 +7590,10 @@ impl Editor {
|
|||
|
||||
// Find an insertion that starts at the cursor position.
|
||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||
let cursor_offset = self.selections.newest::<usize>(cx).head();
|
||||
let cursor_offset = self
|
||||
.selections
|
||||
.newest::<usize>(&self.display_snapshot(cx))
|
||||
.head();
|
||||
let insertion = edits.iter().find_map(|(range, text)| {
|
||||
let range = range.to_offset(&snapshot);
|
||||
if range.is_empty() && range.start == cursor_offset {
|
||||
|
|
@ -8528,7 +8549,11 @@ impl Editor {
|
|||
&mut self,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<(Entity<Buffer>, u32, Arc<RunnableTasks>)> {
|
||||
let cursor_row = self.selections.newest_adjusted(cx).head().row;
|
||||
let cursor_row = self
|
||||
.selections
|
||||
.newest_adjusted(&self.display_snapshot(cx))
|
||||
.head()
|
||||
.row;
|
||||
|
||||
let ((buffer_id, row), tasks) = self
|
||||
.tasks
|
||||
|
|
@ -8545,7 +8570,10 @@ impl Editor {
|
|||
cx: &mut Context<Self>,
|
||||
) -> Option<(Entity<Buffer>, u32, Arc<RunnableTasks>)> {
|
||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||
let offset = self.selections.newest::<usize>(cx).head();
|
||||
let offset = self
|
||||
.selections
|
||||
.newest::<usize>(&self.display_snapshot(cx))
|
||||
.head();
|
||||
let excerpt = snapshot.excerpt_containing(offset..offset)?;
|
||||
let buffer_id = excerpt.buffer().remote_id();
|
||||
|
||||
|
|
@ -9862,8 +9890,7 @@ impl Editor {
|
|||
// Check whether the just-entered snippet ends with an auto-closable bracket.
|
||||
if self.autoclose_regions.is_empty() {
|
||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||
let mut all_selections = self.selections.all::<Point>(cx);
|
||||
for selection in &mut all_selections {
|
||||
for selection in &mut self.selections.all::<Point>(&self.display_snapshot(cx)) {
|
||||
let selection_head = selection.head();
|
||||
let Some(scope) = snapshot.language_scope_at(selection_head) else {
|
||||
continue;
|
||||
|
|
@ -10001,9 +10028,12 @@ impl Editor {
|
|||
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
|
||||
self.transact(window, cx, |this, window, cx| {
|
||||
this.select_autoclose_pair(window, cx);
|
||||
|
||||
let display_map = this.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
|
||||
let mut linked_ranges = HashMap::<_, Vec<_>>::default();
|
||||
if !this.linked_edit_ranges.is_empty() {
|
||||
let selections = this.selections.all::<MultiBufferPoint>(cx);
|
||||
let selections = this.selections.all::<MultiBufferPoint>(&display_map);
|
||||
let snapshot = this.buffer.read(cx).snapshot(cx);
|
||||
|
||||
for selection in selections.iter() {
|
||||
|
|
@ -10022,8 +10052,7 @@ impl Editor {
|
|||
}
|
||||
}
|
||||
|
||||
let mut selections = this.selections.all::<MultiBufferPoint>(cx);
|
||||
let display_map = this.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let mut selections = this.selections.all::<MultiBufferPoint>(&display_map);
|
||||
for selection in &mut selections {
|
||||
if selection.is_empty() {
|
||||
let old_head = selection.head();
|
||||
|
|
@ -10138,7 +10167,7 @@ impl Editor {
|
|||
return;
|
||||
}
|
||||
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
|
||||
let mut selections = self.selections.all_adjusted(cx);
|
||||
let mut selections = self.selections.all_adjusted(&self.display_snapshot(cx));
|
||||
let buffer = self.buffer.read(cx);
|
||||
let snapshot = buffer.snapshot(cx);
|
||||
let rows_iter = selections.iter().map(|s| s.head().row);
|
||||
|
|
@ -10254,7 +10283,7 @@ impl Editor {
|
|||
}
|
||||
|
||||
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
|
||||
let mut selections = self.selections.all::<Point>(cx);
|
||||
let mut selections = self.selections.all::<Point>(&self.display_snapshot(cx));
|
||||
let mut prev_edited_row = 0;
|
||||
let mut row_delta = 0;
|
||||
let mut edits = Vec::new();
|
||||
|
|
@ -10363,7 +10392,7 @@ impl Editor {
|
|||
|
||||
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let selections = self.selections.all::<Point>(&display_map);
|
||||
let mut deletion_ranges = Vec::new();
|
||||
let mut last_outdent = None;
|
||||
{
|
||||
|
|
@ -10424,7 +10453,7 @@ impl Editor {
|
|||
cx,
|
||||
);
|
||||
});
|
||||
let selections = this.selections.all::<usize>(cx);
|
||||
let selections = this.selections.all::<usize>(&this.display_snapshot(cx));
|
||||
this.change_selections(Default::default(), window, cx, |s| s.select(selections));
|
||||
});
|
||||
}
|
||||
|
|
@ -10441,7 +10470,7 @@ impl Editor {
|
|||
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
|
||||
let selections = self
|
||||
.selections
|
||||
.all::<usize>(cx)
|
||||
.all::<usize>(&self.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.map(|s| s.range());
|
||||
|
||||
|
|
@ -10449,7 +10478,7 @@ impl Editor {
|
|||
this.buffer.update(cx, |buffer, cx| {
|
||||
buffer.autoindent_ranges(selections, cx);
|
||||
});
|
||||
let selections = this.selections.all::<usize>(cx);
|
||||
let selections = this.selections.all::<usize>(&this.display_snapshot(cx));
|
||||
this.change_selections(Default::default(), window, cx, |s| s.select(selections));
|
||||
});
|
||||
}
|
||||
|
|
@ -10457,7 +10486,7 @@ impl Editor {
|
|||
pub fn delete_line(&mut self, _: &DeleteLine, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let selections = self.selections.all::<Point>(&display_map);
|
||||
|
||||
let mut new_cursors = Vec::new();
|
||||
let mut edit_ranges = Vec::new();
|
||||
|
|
@ -10551,7 +10580,7 @@ impl Editor {
|
|||
return;
|
||||
}
|
||||
let mut row_ranges = Vec::<Range<MultiBufferRow>>::new();
|
||||
for selection in self.selections.all::<Point>(cx) {
|
||||
for selection in self.selections.all::<Point>(&self.display_snapshot(cx)) {
|
||||
let start = MultiBufferRow(selection.start.row);
|
||||
// Treat single line selections as if they include the next line. Otherwise this action
|
||||
// would do nothing for single line selections individual cursors.
|
||||
|
|
@ -10694,7 +10723,11 @@ impl Editor {
|
|||
let mut edits = Vec::new();
|
||||
let mut boundaries = Vec::new();
|
||||
|
||||
for selection in self.selections.all::<Point>(cx).iter() {
|
||||
for selection in self
|
||||
.selections
|
||||
.all::<Point>(&self.display_snapshot(cx))
|
||||
.iter()
|
||||
{
|
||||
let Some(wrap_config) = snapshot
|
||||
.language_at(selection.start)
|
||||
.and_then(|lang| lang.config().wrap_characters.clone())
|
||||
|
|
@ -10764,7 +10797,7 @@ impl Editor {
|
|||
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
|
||||
let mut buffer_ids = HashSet::default();
|
||||
let snapshot = self.buffer().read(cx).snapshot(cx);
|
||||
for selection in self.selections.all::<usize>(cx) {
|
||||
for selection in self.selections.all::<usize>(&self.display_snapshot(cx)) {
|
||||
buffer_ids.extend(snapshot.buffer_ids_for_range(selection.range()))
|
||||
}
|
||||
|
||||
|
|
@ -10781,7 +10814,7 @@ impl Editor {
|
|||
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
|
||||
let selections = self
|
||||
.selections
|
||||
.all(cx)
|
||||
.all(&self.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.map(|s| s.range())
|
||||
.collect();
|
||||
|
|
@ -11189,7 +11222,7 @@ impl Editor {
|
|||
|
||||
let mut edits = Vec::new();
|
||||
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let selections = self.selections.all::<Point>(&display_map);
|
||||
let mut selections = selections.iter().peekable();
|
||||
let mut contiguous_row_selections = Vec::new();
|
||||
let mut new_selections = Vec::new();
|
||||
|
|
@ -11591,7 +11624,7 @@ impl Editor {
|
|||
let mut edits = Vec::new();
|
||||
let mut selection_adjustment = 0i32;
|
||||
|
||||
for selection in self.selections.all_adjusted(cx) {
|
||||
for selection in self.selections.all_adjusted(&self.display_snapshot(cx)) {
|
||||
let selection_is_empty = selection.is_empty();
|
||||
|
||||
let (start, end) = if selection_is_empty {
|
||||
|
|
@ -11683,7 +11716,7 @@ impl Editor {
|
|||
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let buffer = display_map.buffer_snapshot();
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let selections = self.selections.all::<Point>(&display_map);
|
||||
|
||||
let mut edits = Vec::new();
|
||||
let mut selections_iter = selections.iter().peekable();
|
||||
|
|
@ -11791,7 +11824,7 @@ impl Editor {
|
|||
let mut unfold_ranges = Vec::new();
|
||||
let mut refold_creases = Vec::new();
|
||||
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let selections = self.selections.all::<Point>(&display_map);
|
||||
let mut selections = selections.iter().peekable();
|
||||
let mut contiguous_row_selections = Vec::new();
|
||||
let mut new_selections = Vec::new();
|
||||
|
|
@ -11902,7 +11935,7 @@ impl Editor {
|
|||
let mut unfold_ranges = Vec::new();
|
||||
let mut refold_creases = Vec::new();
|
||||
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let selections = self.selections.all::<Point>(&display_map);
|
||||
let mut selections = selections.iter().peekable();
|
||||
let mut contiguous_row_selections = Vec::new();
|
||||
let mut new_selections = Vec::new();
|
||||
|
|
@ -12035,7 +12068,7 @@ impl Editor {
|
|||
});
|
||||
this.buffer
|
||||
.update(cx, |buffer, cx| buffer.edit(edits, None, cx));
|
||||
let selections = this.selections.all::<usize>(cx);
|
||||
let selections = this.selections.all::<usize>(&this.display_snapshot(cx));
|
||||
this.change_selections(Default::default(), window, cx, |s| {
|
||||
s.select(selections);
|
||||
});
|
||||
|
|
@ -12054,7 +12087,7 @@ impl Editor {
|
|||
|
||||
pub fn rewrap_impl(&mut self, options: RewrapOptions, cx: &mut Context<Self>) {
|
||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let selections = self.selections.all::<Point>(&self.display_snapshot(cx));
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
enum CommentFormat {
|
||||
|
|
@ -12430,7 +12463,7 @@ impl Editor {
|
|||
) -> ClipboardItem {
|
||||
let mut text = String::new();
|
||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||
let mut selections = self.selections.all::<Point>(cx);
|
||||
let mut selections = self.selections.all::<Point>(&self.display_snapshot(cx));
|
||||
let mut clipboard_selections = Vec::with_capacity(selections.len());
|
||||
{
|
||||
let max_point = buffer.max_point();
|
||||
|
|
@ -12526,7 +12559,7 @@ impl Editor {
|
|||
}
|
||||
|
||||
fn do_copy(&self, strip_leading_indents: bool, cx: &mut Context<Self>) {
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let selections = self.selections.all::<Point>(&self.display_snapshot(cx));
|
||||
let buffer = self.buffer.read(cx).read(cx);
|
||||
let mut text = String::new();
|
||||
|
||||
|
|
@ -12637,8 +12670,9 @@ impl Editor {
|
|||
|
||||
self.transact(window, cx, |this, window, cx| {
|
||||
let had_active_edit_prediction = this.has_active_edit_prediction();
|
||||
let old_selections = this.selections.all::<usize>(cx);
|
||||
let cursor_offset = this.selections.last::<usize>(cx).head();
|
||||
let display_map = this.display_snapshot(cx);
|
||||
let old_selections = this.selections.all::<usize>(&display_map);
|
||||
let cursor_offset = this.selections.last::<usize>(&display_map).head();
|
||||
|
||||
if let Some(mut clipboard_selections) = clipboard_selections {
|
||||
let all_selections_were_entire_line =
|
||||
|
|
@ -12719,7 +12753,7 @@ impl Editor {
|
|||
);
|
||||
});
|
||||
|
||||
let selections = this.selections.all::<usize>(cx);
|
||||
let selections = this.selections.all::<usize>(&this.display_snapshot(cx));
|
||||
this.change_selections(Default::default(), window, cx, |s| s.select(selections));
|
||||
} else {
|
||||
let url = url::Url::parse(&clipboard_text).ok();
|
||||
|
|
@ -12784,7 +12818,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let selections = self.selections.all::<usize>(cx);
|
||||
let selections = self.selections.all::<usize>(&self.display_snapshot(cx));
|
||||
|
||||
if selections.is_empty() {
|
||||
log::warn!("There should always be at least one selection in Zed. This is a bug.");
|
||||
|
|
@ -14047,7 +14081,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let mut selection = self.selections.last::<Point>(cx);
|
||||
let mut selection = self.selections.last::<Point>(&self.display_snapshot(cx));
|
||||
selection.set_head(Point::zero(), SelectionGoal::None);
|
||||
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
|
||||
self.change_selections(Default::default(), window, cx, |s| {
|
||||
|
|
@ -14126,7 +14160,7 @@ impl Editor {
|
|||
pub fn select_to_end(&mut self, _: &SelectToEnd, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
|
||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||
let mut selection = self.selections.first::<usize>(cx);
|
||||
let mut selection = self.selections.first::<usize>(&self.display_snapshot(cx));
|
||||
selection.set_head(buffer.len(), SelectionGoal::None);
|
||||
self.change_selections(Default::default(), window, cx, |s| {
|
||||
s.select(vec![selection]);
|
||||
|
|
@ -14144,7 +14178,7 @@ impl Editor {
|
|||
pub fn select_line(&mut self, _: &SelectLine, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let mut selections = self.selections.all::<Point>(cx);
|
||||
let mut selections = self.selections.all::<Point>(&display_map);
|
||||
let max_point = display_map.buffer_snapshot().max_point();
|
||||
for selection in &mut selections {
|
||||
let rows = selection.spanned_rows(true, &display_map);
|
||||
|
|
@ -14165,7 +14199,7 @@ impl Editor {
|
|||
) {
|
||||
let selections = self
|
||||
.selections
|
||||
.all::<Point>(cx)
|
||||
.all::<Point>(&self.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.map(|selection| selection.start..selection.end)
|
||||
.collect::<Vec<_>>();
|
||||
|
|
@ -14244,7 +14278,7 @@ impl Editor {
|
|||
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
|
||||
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let all_selections = self.selections.all::<Point>(cx);
|
||||
let all_selections = self.selections.all::<Point>(&display_map);
|
||||
let text_layout_details = self.text_layout_details(window);
|
||||
|
||||
let (mut columnar_selections, new_selections_to_columnarize) = {
|
||||
|
|
@ -14378,7 +14412,7 @@ impl Editor {
|
|||
|
||||
let final_selection_ids: HashSet<_> = self
|
||||
.selections
|
||||
.all::<Point>(cx)
|
||||
.all::<Point>(&display_map)
|
||||
.iter()
|
||||
.map(|s| s.id)
|
||||
.collect();
|
||||
|
|
@ -14436,7 +14470,7 @@ impl Editor {
|
|||
cx: &mut Context<Self>,
|
||||
) -> Result<()> {
|
||||
let buffer = display_map.buffer_snapshot();
|
||||
let mut selections = self.selections.all::<usize>(cx);
|
||||
let mut selections = self.selections.all::<usize>(&display_map);
|
||||
if let Some(mut select_next_state) = self.select_next_state.take() {
|
||||
let query = &select_next_state.query;
|
||||
if !select_next_state.done {
|
||||
|
|
@ -14610,7 +14644,7 @@ impl Editor {
|
|||
|
||||
let mut new_selections = Vec::new();
|
||||
|
||||
let reversed = self.selections.oldest::<usize>(cx).reversed;
|
||||
let reversed = self.selections.oldest::<usize>(&display_map).reversed;
|
||||
let buffer = display_map.buffer_snapshot();
|
||||
let query_matches = select_next_state
|
||||
.query
|
||||
|
|
@ -14674,7 +14708,7 @@ impl Editor {
|
|||
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let buffer = display_map.buffer_snapshot();
|
||||
let mut selections = self.selections.all::<usize>(cx);
|
||||
let mut selections = self.selections.all::<usize>(&display_map);
|
||||
if let Some(mut select_prev_state) = self.select_prev_state.take() {
|
||||
let query = &select_prev_state.query;
|
||||
if !select_prev_state.done {
|
||||
|
|
@ -14862,7 +14896,9 @@ impl Editor {
|
|||
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
|
||||
let text_layout_details = &self.text_layout_details(window);
|
||||
self.transact(window, cx, |this, window, cx| {
|
||||
let mut selections = this.selections.all::<MultiBufferPoint>(cx);
|
||||
let mut selections = this
|
||||
.selections
|
||||
.all::<MultiBufferPoint>(&this.display_snapshot(cx));
|
||||
let mut edits = Vec::new();
|
||||
let mut selection_edit_ranges = Vec::new();
|
||||
let mut last_toggled_row = None;
|
||||
|
|
@ -15093,7 +15129,7 @@ impl Editor {
|
|||
// Adjust selections so that they end before any comment suffixes that
|
||||
// were inserted.
|
||||
let mut suffixes_inserted = suffixes_inserted.into_iter().peekable();
|
||||
let mut selections = this.selections.all::<Point>(cx);
|
||||
let mut selections = this.selections.all::<Point>(&this.display_snapshot(cx));
|
||||
let snapshot = this.buffer.read(cx).read(cx);
|
||||
for selection in &mut selections {
|
||||
while let Some((row, suffix_len)) = suffixes_inserted.peek().copied() {
|
||||
|
|
@ -15119,7 +15155,7 @@ impl Editor {
|
|||
drop(snapshot);
|
||||
this.change_selections(Default::default(), window, cx, |s| s.select(selections));
|
||||
|
||||
let selections = this.selections.all::<Point>(cx);
|
||||
let selections = this.selections.all::<Point>(&this.display_snapshot(cx));
|
||||
let selections_on_single_row = selections.windows(2).all(|selections| {
|
||||
selections[0].start.row == selections[1].start.row
|
||||
&& selections[0].end.row == selections[1].end.row
|
||||
|
|
@ -15163,7 +15199,10 @@ impl Editor {
|
|||
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
|
||||
|
||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||
let old_selections = self.selections.all::<usize>(cx).into_boxed_slice();
|
||||
let old_selections = self
|
||||
.selections
|
||||
.all::<usize>(&self.display_snapshot(cx))
|
||||
.into_boxed_slice();
|
||||
|
||||
fn update_selection(
|
||||
selection: &Selection<usize>,
|
||||
|
|
@ -15218,7 +15257,10 @@ impl Editor {
|
|||
let Some(visible_row_count) = self.visible_row_count() else {
|
||||
return;
|
||||
};
|
||||
let old_selections: Box<[_]> = self.selections.all::<usize>(cx).into();
|
||||
let old_selections: Box<[_]> = self
|
||||
.selections
|
||||
.all::<usize>(&self.display_snapshot(cx))
|
||||
.into();
|
||||
if old_selections.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
|
@ -15376,7 +15418,7 @@ impl Editor {
|
|||
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||
let selections = self
|
||||
.selections
|
||||
.all::<usize>(cx)
|
||||
.all::<usize>(&self.display_snapshot(cx))
|
||||
.into_iter()
|
||||
// subtracting the offset requires sorting
|
||||
.sorted_by_key(|i| i.start);
|
||||
|
|
@ -15448,7 +15490,10 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let old_selections: Box<[_]> = self.selections.all::<usize>(cx).into();
|
||||
let old_selections: Box<[_]> = self
|
||||
.selections
|
||||
.all::<usize>(&self.display_snapshot(cx))
|
||||
.into();
|
||||
if old_selections.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
|
@ -15497,7 +15542,10 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let old_selections: Box<[_]> = self.selections.all::<usize>(cx).into();
|
||||
let old_selections: Box<[_]> = self
|
||||
.selections
|
||||
.all::<usize>(&self.display_snapshot(cx))
|
||||
.into();
|
||||
if old_selections.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
|
@ -16046,7 +16094,7 @@ impl Editor {
|
|||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||
let selection = self.selections.newest::<usize>(cx);
|
||||
let selection = self.selections.newest::<usize>(&self.display_snapshot(cx));
|
||||
|
||||
let mut active_group_id = None;
|
||||
if let ActiveDiagnostic::Group(active_group) = &self.active_diagnostics
|
||||
|
|
@ -16127,7 +16175,7 @@ impl Editor {
|
|||
pub fn go_to_next_hunk(&mut self, _: &GoToHunk, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
|
||||
let snapshot = self.snapshot(window, cx);
|
||||
let selection = self.selections.newest::<Point>(cx);
|
||||
let selection = self.selections.newest::<Point>(&self.display_snapshot(cx));
|
||||
self.go_to_hunk_before_or_after_position(
|
||||
&snapshot,
|
||||
selection.head(),
|
||||
|
|
@ -16188,7 +16236,7 @@ impl Editor {
|
|||
) {
|
||||
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
|
||||
let snapshot = self.snapshot(window, cx);
|
||||
let selection = self.selections.newest::<Point>(cx);
|
||||
let selection = self.selections.newest::<Point>(&snapshot.display_snapshot);
|
||||
self.go_to_hunk_before_or_after_position(
|
||||
&snapshot,
|
||||
selection.head(),
|
||||
|
|
@ -16278,7 +16326,10 @@ impl Editor {
|
|||
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
|
||||
let snapshot = self.snapshot(window, cx);
|
||||
let buffer = &snapshot.buffer_snapshot();
|
||||
let position = self.selections.newest::<Point>(cx).head();
|
||||
let position = self
|
||||
.selections
|
||||
.newest::<Point>(&snapshot.display_snapshot)
|
||||
.head();
|
||||
let anchor_position = buffer.anchor_after(position);
|
||||
|
||||
// Get all document highlights (both read and write)
|
||||
|
|
@ -16461,7 +16512,10 @@ impl Editor {
|
|||
let Some(provider) = self.semantics_provider.clone() else {
|
||||
return Task::ready(Ok(Navigated::No));
|
||||
};
|
||||
let head = self.selections.newest::<usize>(cx).head();
|
||||
let head = self
|
||||
.selections
|
||||
.newest::<usize>(&self.display_snapshot(cx))
|
||||
.head();
|
||||
let buffer = self.buffer.read(cx);
|
||||
let Some((buffer, head)) = buffer.text_anchor_for_position(head, cx) else {
|
||||
return Task::ready(Ok(Navigated::No));
|
||||
|
|
@ -16792,7 +16846,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<Task<Result<Navigated>>> {
|
||||
let selection = self.selections.newest::<usize>(cx);
|
||||
let selection = self.selections.newest::<usize>(&self.display_snapshot(cx));
|
||||
let multi_buffer = self.buffer.read(cx);
|
||||
let head = selection.head();
|
||||
|
||||
|
|
@ -17267,7 +17321,10 @@ impl Editor {
|
|||
|
||||
if moving_cursor {
|
||||
let cursor_in_rename_editor = rename.editor.update(cx, |editor, cx| {
|
||||
editor.selections.newest::<usize>(cx).head()
|
||||
editor
|
||||
.selections
|
||||
.newest::<usize>(&editor.display_snapshot(cx))
|
||||
.head()
|
||||
});
|
||||
|
||||
// Update the selection to match the position of the selection inside
|
||||
|
|
@ -17330,7 +17387,7 @@ impl Editor {
|
|||
|
||||
let ranges = self
|
||||
.selections
|
||||
.all_adjusted(cx)
|
||||
.all_adjusted(&self.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.map(|selection| selection.range())
|
||||
.collect_vec();
|
||||
|
|
@ -18029,9 +18086,9 @@ impl Editor {
|
|||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if self.buffer_kind(cx) == ItemBufferKind::Singleton {
|
||||
let selection = self.selections.newest::<Point>(cx);
|
||||
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let selection = self.selections.newest::<Point>(&display_map);
|
||||
|
||||
let range = if selection.is_empty() {
|
||||
let point = selection.head().to_display_point(&display_map);
|
||||
let start = DisplayPoint::new(point.row(), 0).to_point(&display_map);
|
||||
|
|
@ -18074,7 +18131,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let selection = self.selections.newest::<Point>(cx);
|
||||
let selection = self.selections.newest::<Point>(&self.display_snapshot(cx));
|
||||
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let range = if selection.is_empty() {
|
||||
|
|
@ -18097,7 +18154,7 @@ impl Editor {
|
|||
if self.buffer_kind(cx) == ItemBufferKind::Singleton {
|
||||
let mut to_fold = Vec::new();
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let selections = self.selections.all_adjusted(cx);
|
||||
let selections = self.selections.all_adjusted(&display_map);
|
||||
|
||||
for selection in selections {
|
||||
let range = selection.range().sorted();
|
||||
|
|
@ -18204,7 +18261,7 @@ impl Editor {
|
|||
|
||||
let row_ranges_to_keep: Vec<Range<u32>> = self
|
||||
.selections
|
||||
.all::<Point>(cx)
|
||||
.all::<Point>(&self.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.map(|sel| sel.start.row..sel.end.row)
|
||||
.collect();
|
||||
|
|
@ -18379,7 +18436,7 @@ impl Editor {
|
|||
) {
|
||||
let mut to_fold = Vec::new();
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let selections = self.selections.all_adjusted(cx);
|
||||
let selections = self.selections.all_adjusted(&display_map);
|
||||
|
||||
for selection in selections {
|
||||
let range = selection.range().sorted();
|
||||
|
|
@ -18423,7 +18480,7 @@ impl Editor {
|
|||
if let Some(crease) = display_map.crease_for_buffer_row(buffer_row) {
|
||||
let autoscroll = self
|
||||
.selections
|
||||
.all::<Point>(cx)
|
||||
.all::<Point>(&display_map)
|
||||
.iter()
|
||||
.any(|selection| crease.range().overlaps(&selection.range()));
|
||||
|
||||
|
|
@ -18435,7 +18492,7 @@ impl Editor {
|
|||
if self.buffer_kind(cx) == ItemBufferKind::Singleton {
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let buffer = display_map.buffer_snapshot();
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let selections = self.selections.all::<Point>(&display_map);
|
||||
let ranges = selections
|
||||
.iter()
|
||||
.map(|s| {
|
||||
|
|
@ -18469,7 +18526,7 @@ impl Editor {
|
|||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let selections = self.selections.all::<Point>(&display_map);
|
||||
let ranges = selections
|
||||
.iter()
|
||||
.map(|s| {
|
||||
|
|
@ -18501,7 +18558,7 @@ impl Editor {
|
|||
|
||||
let autoscroll = self
|
||||
.selections
|
||||
.all::<Point>(cx)
|
||||
.all::<Point>(&display_map)
|
||||
.iter()
|
||||
.any(|selection| RangeExt::overlaps(&selection.range(), &intersection_range));
|
||||
|
||||
|
|
@ -18536,8 +18593,8 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let selections = self.selections.all_adjusted(cx);
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let selections = self.selections.all_adjusted(&display_map);
|
||||
let ranges = selections
|
||||
.into_iter()
|
||||
.map(|s| Crease::simple(s.range(), display_map.fold_placeholder.clone()))
|
||||
|
|
@ -18870,7 +18927,10 @@ impl Editor {
|
|||
|
||||
self.stage_or_unstage_diff_hunks(stage, ranges, cx);
|
||||
let snapshot = self.snapshot(window, cx);
|
||||
let position = self.selections.newest::<Point>(cx).head();
|
||||
let position = self
|
||||
.selections
|
||||
.newest::<Point>(&snapshot.display_snapshot)
|
||||
.head();
|
||||
let mut row = snapshot
|
||||
.buffer_snapshot()
|
||||
.diff_hunks_in_range(position..snapshot.buffer_snapshot().max_point())
|
||||
|
|
@ -19018,7 +19078,7 @@ impl Editor {
|
|||
let snapshot = self.snapshot(window, cx);
|
||||
let hunks = snapshot.hunks_for_ranges(
|
||||
self.selections
|
||||
.all(cx)
|
||||
.all(&snapshot.display_snapshot)
|
||||
.into_iter()
|
||||
.map(|selection| selection.range()),
|
||||
);
|
||||
|
|
@ -19754,7 +19814,10 @@ impl Editor {
|
|||
) -> Option<()> {
|
||||
let blame = self.blame.as_ref()?;
|
||||
let snapshot = self.snapshot(window, cx);
|
||||
let cursor = self.selections.newest::<Point>(cx).head();
|
||||
let cursor = self
|
||||
.selections
|
||||
.newest::<Point>(&snapshot.display_snapshot)
|
||||
.head();
|
||||
let (buffer, point, _) = snapshot.buffer_snapshot().point_to_buffer_point(cursor)?;
|
||||
let (_, blame_entry) = blame
|
||||
.update(cx, |blame, cx| {
|
||||
|
|
@ -19896,7 +19959,7 @@ impl Editor {
|
|||
|
||||
fn get_permalink_to_line(&self, cx: &mut Context<Self>) -> Task<Result<url::Url>> {
|
||||
let buffer_and_selection = maybe!({
|
||||
let selection = self.selections.newest::<Point>(cx);
|
||||
let selection = self.selections.newest::<Point>(&self.display_snapshot(cx));
|
||||
let selection_range = selection.range();
|
||||
|
||||
let multi_buffer = self.buffer().read(cx);
|
||||
|
|
@ -19974,7 +20037,12 @@ impl Editor {
|
|||
_: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let selection = self.selections.newest::<Point>(cx).start.row + 1;
|
||||
let selection = self
|
||||
.selections
|
||||
.newest::<Point>(&self.display_snapshot(cx))
|
||||
.start
|
||||
.row
|
||||
+ 1;
|
||||
if let Some(file) = self.target_file(cx) {
|
||||
let path = file.path().display(file.path_style(cx));
|
||||
cx.write_to_clipboard(ClipboardItem::new_string(format!("{path}:{selection}")));
|
||||
|
|
@ -20045,7 +20113,7 @@ impl Editor {
|
|||
self.transact(window, cx, |this, window, cx| {
|
||||
let edits = this
|
||||
.selections
|
||||
.all::<Point>(cx)
|
||||
.all::<Point>(&this.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.map(|selection| {
|
||||
let uuid = match version {
|
||||
|
|
@ -21131,7 +21199,7 @@ impl Editor {
|
|||
return;
|
||||
};
|
||||
|
||||
let selections = self.selections.all::<usize>(cx);
|
||||
let selections = self.selections.all::<usize>(&self.display_snapshot(cx));
|
||||
let multi_buffer = self.buffer.read(cx);
|
||||
let multi_buffer_snapshot = multi_buffer.snapshot(cx);
|
||||
let mut new_selections_by_buffer = HashMap::default();
|
||||
|
|
@ -21255,7 +21323,7 @@ impl Editor {
|
|||
}
|
||||
}
|
||||
None => {
|
||||
let selections = self.selections.all::<usize>(cx);
|
||||
let selections = self.selections.all::<usize>(&self.display_snapshot(cx));
|
||||
let multi_buffer = self.buffer.read(cx);
|
||||
for selection in selections {
|
||||
for (snapshot, range, _, anchor) in multi_buffer
|
||||
|
|
@ -21393,7 +21461,9 @@ impl Editor {
|
|||
range: Range<OffsetUtf16>,
|
||||
cx: &mut App,
|
||||
) -> Vec<Range<OffsetUtf16>> {
|
||||
let selections = self.selections.all::<OffsetUtf16>(cx);
|
||||
let selections = self
|
||||
.selections
|
||||
.all::<OffsetUtf16>(&self.display_snapshot(cx));
|
||||
let newest_selection = selections
|
||||
.iter()
|
||||
.max_by_key(|selection| selection.id)
|
||||
|
|
@ -21556,7 +21626,10 @@ impl Editor {
|
|||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.request_autoscroll(Autoscroll::newest(), cx);
|
||||
let position = self.selections.newest_display(cx).start;
|
||||
let position = self
|
||||
.selections
|
||||
.newest_display(&self.display_snapshot(cx))
|
||||
.start;
|
||||
mouse_context_menu::deploy_context_menu(self, None, position, window, cx);
|
||||
}
|
||||
|
||||
|
|
@ -21576,7 +21649,9 @@ impl Editor {
|
|||
return;
|
||||
}
|
||||
if let Some(relative_utf16_range) = relative_utf16_range {
|
||||
let selections = self.selections.all::<OffsetUtf16>(cx);
|
||||
let selections = self
|
||||
.selections
|
||||
.all::<OffsetUtf16>(&self.display_snapshot(cx));
|
||||
self.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
let new_ranges = selections.into_iter().map(|range| {
|
||||
let start = OffsetUtf16(
|
||||
|
|
@ -21716,7 +21791,7 @@ impl Editor {
|
|||
}
|
||||
let transaction =
|
||||
self.transact(window, cx, |this, window, cx| {
|
||||
let selections = this.selections.all::<usize>(cx);
|
||||
let selections = this.selections.all::<usize>(&this.display_snapshot(cx));
|
||||
let edits = selections
|
||||
.iter()
|
||||
.map(|selection| (selection.end..selection.end, pending.clone()));
|
||||
|
|
@ -21735,7 +21810,7 @@ impl Editor {
|
|||
let snapshot = self.snapshot(window, cx);
|
||||
let ranges = self
|
||||
.selections
|
||||
.all::<usize>(cx)
|
||||
.all::<usize>(&snapshot.display_snapshot)
|
||||
.into_iter()
|
||||
.map(|selection| {
|
||||
snapshot.buffer_snapshot().anchor_after(selection.end)
|
||||
|
|
@ -23867,7 +23942,9 @@ impl EntityInputHandler for Editor {
|
|||
return None;
|
||||
}
|
||||
|
||||
let selection = self.selections.newest::<OffsetUtf16>(cx);
|
||||
let selection = self
|
||||
.selections
|
||||
.newest::<OffsetUtf16>(&self.display_snapshot(cx));
|
||||
let range = selection.range();
|
||||
|
||||
Some(UTF16Selection {
|
||||
|
|
@ -23910,7 +23987,7 @@ impl EntityInputHandler for Editor {
|
|||
let range_to_replace = new_selected_ranges.as_ref().and_then(|ranges_to_replace| {
|
||||
let newest_selection_id = this.selections.newest_anchor().id;
|
||||
this.selections
|
||||
.all::<OffsetUtf16>(cx)
|
||||
.all::<OffsetUtf16>(&this.display_snapshot(cx))
|
||||
.iter()
|
||||
.zip(ranges_to_replace.iter())
|
||||
.find_map(|(selection, range)| {
|
||||
|
|
@ -23985,7 +24062,7 @@ impl EntityInputHandler for Editor {
|
|||
let range_to_replace = ranges_to_replace.as_ref().and_then(|ranges_to_replace| {
|
||||
let newest_selection_id = this.selections.newest_anchor().id;
|
||||
this.selections
|
||||
.all::<OffsetUtf16>(cx)
|
||||
.all::<OffsetUtf16>(&this.display_snapshot(cx))
|
||||
.iter()
|
||||
.zip(ranges_to_replace.iter())
|
||||
.find_map(|(selection, range)| {
|
||||
|
|
|
|||
|
|
@ -219,7 +219,10 @@ fn test_undo_redo_with_selection_restoration(cx: &mut TestAppContext) {
|
|||
editor.insert("cd", window, cx);
|
||||
editor.end_transaction_at(now, cx);
|
||||
assert_eq!(editor.text(cx), "12cd56");
|
||||
assert_eq!(editor.selections.ranges(cx), vec![4..4]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
vec![4..4]
|
||||
);
|
||||
|
||||
editor.start_transaction_at(now, window, cx);
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
|
|
@ -228,7 +231,10 @@ fn test_undo_redo_with_selection_restoration(cx: &mut TestAppContext) {
|
|||
editor.insert("e", window, cx);
|
||||
editor.end_transaction_at(now, cx);
|
||||
assert_eq!(editor.text(cx), "12cde6");
|
||||
assert_eq!(editor.selections.ranges(cx), vec![5..5]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
vec![5..5]
|
||||
);
|
||||
|
||||
now += group_interval + Duration::from_millis(1);
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
|
|
@ -244,30 +250,45 @@ fn test_undo_redo_with_selection_restoration(cx: &mut TestAppContext) {
|
|||
});
|
||||
|
||||
assert_eq!(editor.text(cx), "ab2cde6");
|
||||
assert_eq!(editor.selections.ranges(cx), vec![3..3]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
vec![3..3]
|
||||
);
|
||||
|
||||
// Last transaction happened past the group interval in a different editor.
|
||||
// Undo it individually and don't restore selections.
|
||||
editor.undo(&Undo, window, cx);
|
||||
assert_eq!(editor.text(cx), "12cde6");
|
||||
assert_eq!(editor.selections.ranges(cx), vec![2..2]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
vec![2..2]
|
||||
);
|
||||
|
||||
// First two transactions happened within the group interval in this editor.
|
||||
// Undo them together and restore selections.
|
||||
editor.undo(&Undo, window, cx);
|
||||
editor.undo(&Undo, window, cx); // Undo stack is empty here, so this is a no-op.
|
||||
assert_eq!(editor.text(cx), "123456");
|
||||
assert_eq!(editor.selections.ranges(cx), vec![0..0]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
vec![0..0]
|
||||
);
|
||||
|
||||
// Redo the first two transactions together.
|
||||
editor.redo(&Redo, window, cx);
|
||||
assert_eq!(editor.text(cx), "12cde6");
|
||||
assert_eq!(editor.selections.ranges(cx), vec![5..5]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
vec![5..5]
|
||||
);
|
||||
|
||||
// Redo the last transaction on its own.
|
||||
editor.redo(&Redo, window, cx);
|
||||
assert_eq!(editor.text(cx), "ab2cde6");
|
||||
assert_eq!(editor.selections.ranges(cx), vec![6..6]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
vec![6..6]
|
||||
);
|
||||
|
||||
// Test empty transactions.
|
||||
editor.start_transaction_at(now, window, cx);
|
||||
|
|
@ -770,10 +791,14 @@ fn test_clone(cx: &mut TestAppContext) {
|
|||
);
|
||||
assert_set_eq!(
|
||||
cloned_editor
|
||||
.update(cx, |editor, _, cx| editor.selections.ranges::<Point>(cx))
|
||||
.update(cx, |editor, _, cx| editor
|
||||
.selections
|
||||
.ranges::<Point>(&editor.display_snapshot(cx)))
|
||||
.unwrap(),
|
||||
editor
|
||||
.update(cx, |editor, _, cx| editor.selections.ranges(cx))
|
||||
.update(cx, |editor, _, cx| editor
|
||||
.selections
|
||||
.ranges(&editor.display_snapshot(cx)))
|
||||
.unwrap()
|
||||
);
|
||||
assert_set_eq!(
|
||||
|
|
@ -3161,7 +3186,7 @@ fn test_newline_with_old_selections(cx: &mut TestAppContext) {
|
|||
);
|
||||
});
|
||||
assert_eq!(
|
||||
editor.selections.ranges(cx),
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
&[
|
||||
Point::new(1, 2)..Point::new(1, 2),
|
||||
Point::new(2, 2)..Point::new(2, 2),
|
||||
|
|
@ -3183,7 +3208,7 @@ fn test_newline_with_old_selections(cx: &mut TestAppContext) {
|
|||
|
||||
// The selections are moved after the inserted newlines
|
||||
assert_eq!(
|
||||
editor.selections.ranges(cx),
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
&[
|
||||
Point::new(2, 0)..Point::new(2, 0),
|
||||
Point::new(4, 0)..Point::new(4, 0),
|
||||
|
|
@ -3673,13 +3698,19 @@ fn test_insert_with_old_selections(cx: &mut TestAppContext) {
|
|||
buffer.edit([(2..5, ""), (10..13, ""), (18..21, "")], None, cx);
|
||||
assert_eq!(buffer.read(cx).text(), "a(), b(), c()".unindent());
|
||||
});
|
||||
assert_eq!(editor.selections.ranges(cx), &[2..2, 7..7, 12..12],);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
&[2..2, 7..7, 12..12],
|
||||
);
|
||||
|
||||
editor.insert("Z", window, cx);
|
||||
assert_eq!(editor.text(cx), "a(Z), b(Z), c(Z)");
|
||||
|
||||
// The selections are moved after the inserted characters
|
||||
assert_eq!(editor.selections.ranges(cx), &[3..3, 9..9, 15..15],);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
&[3..3, 9..9, 15..15],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -4439,7 +4470,9 @@ fn test_join_lines_with_single_selection(cx: &mut TestAppContext) {
|
|||
let buffer = buffer.read(cx).as_singleton().unwrap();
|
||||
|
||||
assert_eq!(
|
||||
editor.selections.ranges::<Point>(cx),
|
||||
editor
|
||||
.selections
|
||||
.ranges::<Point>(&editor.display_snapshot(cx)),
|
||||
&[Point::new(0, 0)..Point::new(0, 0)]
|
||||
);
|
||||
|
||||
|
|
@ -4447,7 +4480,9 @@ fn test_join_lines_with_single_selection(cx: &mut TestAppContext) {
|
|||
editor.join_lines(&JoinLines, window, cx);
|
||||
assert_eq!(buffer.read(cx).text(), "aaa bbb\nccc\nddd\n\n");
|
||||
assert_eq!(
|
||||
editor.selections.ranges::<Point>(cx),
|
||||
editor
|
||||
.selections
|
||||
.ranges::<Point>(&editor.display_snapshot(cx)),
|
||||
&[Point::new(0, 3)..Point::new(0, 3)]
|
||||
);
|
||||
|
||||
|
|
@ -4458,7 +4493,9 @@ fn test_join_lines_with_single_selection(cx: &mut TestAppContext) {
|
|||
editor.join_lines(&JoinLines, window, cx);
|
||||
assert_eq!(buffer.read(cx).text(), "aaa bbb ccc ddd\n\n");
|
||||
assert_eq!(
|
||||
editor.selections.ranges::<Point>(cx),
|
||||
editor
|
||||
.selections
|
||||
.ranges::<Point>(&editor.display_snapshot(cx)),
|
||||
&[Point::new(0, 11)..Point::new(0, 11)]
|
||||
);
|
||||
|
||||
|
|
@ -4466,7 +4503,9 @@ fn test_join_lines_with_single_selection(cx: &mut TestAppContext) {
|
|||
editor.undo(&Undo, window, cx);
|
||||
assert_eq!(buffer.read(cx).text(), "aaa bbb\nccc\nddd\n\n");
|
||||
assert_eq!(
|
||||
editor.selections.ranges::<Point>(cx),
|
||||
editor
|
||||
.selections
|
||||
.ranges::<Point>(&editor.display_snapshot(cx)),
|
||||
&[Point::new(0, 5)..Point::new(2, 2)]
|
||||
);
|
||||
|
||||
|
|
@ -4477,7 +4516,9 @@ fn test_join_lines_with_single_selection(cx: &mut TestAppContext) {
|
|||
editor.join_lines(&JoinLines, window, cx);
|
||||
assert_eq!(buffer.read(cx).text(), "aaa bbb\nccc\nddd\n");
|
||||
assert_eq!(
|
||||
editor.selections.ranges::<Point>(cx),
|
||||
editor
|
||||
.selections
|
||||
.ranges::<Point>(&editor.display_snapshot(cx)),
|
||||
[Point::new(2, 3)..Point::new(2, 3)]
|
||||
);
|
||||
|
||||
|
|
@ -4485,7 +4526,9 @@ fn test_join_lines_with_single_selection(cx: &mut TestAppContext) {
|
|||
editor.join_lines(&JoinLines, window, cx);
|
||||
assert_eq!(buffer.read(cx).text(), "aaa bbb\nccc\nddd");
|
||||
assert_eq!(
|
||||
editor.selections.ranges::<Point>(cx),
|
||||
editor
|
||||
.selections
|
||||
.ranges::<Point>(&editor.display_snapshot(cx)),
|
||||
[Point::new(2, 3)..Point::new(2, 3)]
|
||||
);
|
||||
|
||||
|
|
@ -4493,7 +4536,9 @@ fn test_join_lines_with_single_selection(cx: &mut TestAppContext) {
|
|||
editor.join_lines(&JoinLines, window, cx);
|
||||
assert_eq!(buffer.read(cx).text(), "aaa bbb\nccc\nddd");
|
||||
assert_eq!(
|
||||
editor.selections.ranges::<Point>(cx),
|
||||
editor
|
||||
.selections
|
||||
.ranges::<Point>(&editor.display_snapshot(cx)),
|
||||
[Point::new(2, 3)..Point::new(2, 3)]
|
||||
);
|
||||
|
||||
|
|
@ -4550,7 +4595,9 @@ fn test_join_lines_with_multi_selection(cx: &mut TestAppContext) {
|
|||
assert_eq!(buffer.read(cx).text(), "aaa bbb ccc\nddd\n");
|
||||
|
||||
assert_eq!(
|
||||
editor.selections.ranges::<Point>(cx),
|
||||
editor
|
||||
.selections
|
||||
.ranges::<Point>(&editor.display_snapshot(cx)),
|
||||
[
|
||||
Point::new(0, 7)..Point::new(0, 7),
|
||||
Point::new(1, 3)..Point::new(1, 3)
|
||||
|
|
@ -5908,15 +5955,24 @@ fn test_transpose(cx: &mut TestAppContext) {
|
|||
});
|
||||
editor.transpose(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "bac");
|
||||
assert_eq!(editor.selections.ranges(cx), [2..2]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[2..2]
|
||||
);
|
||||
|
||||
editor.transpose(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "bca");
|
||||
assert_eq!(editor.selections.ranges(cx), [3..3]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[3..3]
|
||||
);
|
||||
|
||||
editor.transpose(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "bac");
|
||||
assert_eq!(editor.selections.ranges(cx), [3..3]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[3..3]
|
||||
);
|
||||
|
||||
editor
|
||||
});
|
||||
|
|
@ -5929,22 +5985,34 @@ fn test_transpose(cx: &mut TestAppContext) {
|
|||
});
|
||||
editor.transpose(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "acb\nde");
|
||||
assert_eq!(editor.selections.ranges(cx), [3..3]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[3..3]
|
||||
);
|
||||
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
s.select_ranges([4..4])
|
||||
});
|
||||
editor.transpose(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "acbd\ne");
|
||||
assert_eq!(editor.selections.ranges(cx), [5..5]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[5..5]
|
||||
);
|
||||
|
||||
editor.transpose(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "acbde\n");
|
||||
assert_eq!(editor.selections.ranges(cx), [6..6]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[6..6]
|
||||
);
|
||||
|
||||
editor.transpose(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "acbd\ne");
|
||||
assert_eq!(editor.selections.ranges(cx), [6..6]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[6..6]
|
||||
);
|
||||
|
||||
editor
|
||||
});
|
||||
|
|
@ -5957,23 +6025,38 @@ fn test_transpose(cx: &mut TestAppContext) {
|
|||
});
|
||||
editor.transpose(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "bacd\ne");
|
||||
assert_eq!(editor.selections.ranges(cx), [2..2, 3..3, 5..5]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[2..2, 3..3, 5..5]
|
||||
);
|
||||
|
||||
editor.transpose(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "bcade\n");
|
||||
assert_eq!(editor.selections.ranges(cx), [3..3, 4..4, 6..6]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[3..3, 4..4, 6..6]
|
||||
);
|
||||
|
||||
editor.transpose(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "bcda\ne");
|
||||
assert_eq!(editor.selections.ranges(cx), [4..4, 6..6]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[4..4, 6..6]
|
||||
);
|
||||
|
||||
editor.transpose(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "bcade\n");
|
||||
assert_eq!(editor.selections.ranges(cx), [4..4, 6..6]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[4..4, 6..6]
|
||||
);
|
||||
|
||||
editor.transpose(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "bcaed\n");
|
||||
assert_eq!(editor.selections.ranges(cx), [5..5, 6..6]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[5..5, 6..6]
|
||||
);
|
||||
|
||||
editor
|
||||
});
|
||||
|
|
@ -5986,15 +6069,24 @@ fn test_transpose(cx: &mut TestAppContext) {
|
|||
});
|
||||
editor.transpose(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "🏀🍐✋");
|
||||
assert_eq!(editor.selections.ranges(cx), [8..8]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[8..8]
|
||||
);
|
||||
|
||||
editor.transpose(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "🏀✋🍐");
|
||||
assert_eq!(editor.selections.ranges(cx), [11..11]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[11..11]
|
||||
);
|
||||
|
||||
editor.transpose(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "🏀🍐✋");
|
||||
assert_eq!(editor.selections.ranges(cx), [11..11]);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[11..11]
|
||||
);
|
||||
|
||||
editor
|
||||
});
|
||||
|
|
@ -9540,7 +9632,7 @@ async fn test_autoindent(cx: &mut TestAppContext) {
|
|||
editor.newline(&Newline, window, cx);
|
||||
assert_eq!(editor.text(cx), "fn a(\n \n) {\n \n}\n");
|
||||
assert_eq!(
|
||||
editor.selections.ranges(cx),
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
&[
|
||||
Point::new(1, 4)..Point::new(1, 4),
|
||||
Point::new(3, 4)..Point::new(3, 4),
|
||||
|
|
@ -9616,7 +9708,7 @@ async fn test_autoindent_disabled(cx: &mut TestAppContext) {
|
|||
)
|
||||
);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(cx),
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
&[
|
||||
Point::new(1, 0)..Point::new(1, 0),
|
||||
Point::new(3, 0)..Point::new(3, 0),
|
||||
|
|
@ -10255,7 +10347,9 @@ async fn test_autoclose_with_embedded_language(cx: &mut TestAppContext) {
|
|||
// Precondition: different languages are active at different locations.
|
||||
cx.update_editor(|editor, window, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let cursors = editor.selections.ranges::<usize>(cx);
|
||||
let cursors = editor
|
||||
.selections
|
||||
.ranges::<usize>(&editor.display_snapshot(cx));
|
||||
let languages = cursors
|
||||
.iter()
|
||||
.map(|c| snapshot.language_at(c.start).unwrap().name())
|
||||
|
|
@ -10700,7 +10794,9 @@ async fn test_delete_autoclose_pair(cx: &mut TestAppContext) {
|
|||
.unindent()
|
||||
);
|
||||
assert_eq!(
|
||||
editor.selections.ranges::<Point>(cx),
|
||||
editor
|
||||
.selections
|
||||
.ranges::<Point>(&editor.display_snapshot(cx)),
|
||||
[
|
||||
Point::new(0, 4)..Point::new(0, 4),
|
||||
Point::new(1, 4)..Point::new(1, 4),
|
||||
|
|
@ -10720,7 +10816,9 @@ async fn test_delete_autoclose_pair(cx: &mut TestAppContext) {
|
|||
.unindent()
|
||||
);
|
||||
assert_eq!(
|
||||
editor.selections.ranges::<Point>(cx),
|
||||
editor
|
||||
.selections
|
||||
.ranges::<Point>(&editor.display_snapshot(cx)),
|
||||
[
|
||||
Point::new(0, 2)..Point::new(0, 2),
|
||||
Point::new(1, 2)..Point::new(1, 2),
|
||||
|
|
@ -10739,7 +10837,9 @@ async fn test_delete_autoclose_pair(cx: &mut TestAppContext) {
|
|||
.unindent()
|
||||
);
|
||||
assert_eq!(
|
||||
editor.selections.ranges::<Point>(cx),
|
||||
editor
|
||||
.selections
|
||||
.ranges::<Point>(&editor.display_snapshot(cx)),
|
||||
[
|
||||
Point::new(0, 1)..Point::new(0, 1),
|
||||
Point::new(1, 1)..Point::new(1, 1),
|
||||
|
|
@ -10945,7 +11045,12 @@ async fn test_snippet_placeholder_choices(cx: &mut TestAppContext) {
|
|||
fn assert(editor: &mut Editor, cx: &mut Context<Editor>, marked_text: &str) {
|
||||
let (expected_text, selection_ranges) = marked_text_ranges(marked_text, false);
|
||||
assert_eq!(editor.text(cx), expected_text);
|
||||
assert_eq!(editor.selections.ranges::<usize>(cx), selection_ranges);
|
||||
assert_eq!(
|
||||
editor
|
||||
.selections
|
||||
.ranges::<usize>(&editor.display_snapshot(cx)),
|
||||
selection_ranges
|
||||
);
|
||||
}
|
||||
|
||||
assert(
|
||||
|
|
@ -10976,7 +11081,7 @@ async fn test_snippets(cx: &mut TestAppContext) {
|
|||
let snippet = Snippet::parse("f(${1:one}, ${2:two}, ${1:three})$0").unwrap();
|
||||
let insertion_ranges = editor
|
||||
.selections
|
||||
.all(cx)
|
||||
.all(&editor.display_snapshot(cx))
|
||||
.iter()
|
||||
.map(|s| s.range())
|
||||
.collect::<Vec<_>>();
|
||||
|
|
@ -11056,7 +11161,7 @@ async fn test_snippet_indentation(cx: &mut TestAppContext) {
|
|||
.unwrap();
|
||||
let insertion_ranges = editor
|
||||
.selections
|
||||
.all(cx)
|
||||
.all(&editor.display_snapshot(cx))
|
||||
.iter()
|
||||
.map(|s| s.range())
|
||||
.collect::<Vec<_>>();
|
||||
|
|
@ -15945,7 +16050,7 @@ fn test_editing_disjoint_excerpts(cx: &mut TestAppContext) {
|
|||
editor.handle_input("X", window, cx);
|
||||
assert_eq!(editor.text(cx), "Xaaaa\nXbbbb");
|
||||
assert_eq!(
|
||||
editor.selections.ranges(cx),
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[
|
||||
Point::new(0, 1)..Point::new(0, 1),
|
||||
Point::new(1, 1)..Point::new(1, 1),
|
||||
|
|
@ -15959,7 +16064,7 @@ fn test_editing_disjoint_excerpts(cx: &mut TestAppContext) {
|
|||
editor.backspace(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "Xa\nbbb");
|
||||
assert_eq!(
|
||||
editor.selections.ranges(cx),
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[Point::new(1, 0)..Point::new(1, 0)]
|
||||
);
|
||||
|
||||
|
|
@ -15969,7 +16074,7 @@ fn test_editing_disjoint_excerpts(cx: &mut TestAppContext) {
|
|||
editor.backspace(&Default::default(), window, cx);
|
||||
assert_eq!(editor.text(cx), "X\nbb");
|
||||
assert_eq!(
|
||||
editor.selections.ranges(cx),
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[Point::new(0, 1)..Point::new(0, 1)]
|
||||
);
|
||||
});
|
||||
|
|
@ -16027,7 +16132,10 @@ fn test_editing_overlapping_excerpts(cx: &mut TestAppContext) {
|
|||
false,
|
||||
);
|
||||
assert_eq!(editor.text(cx), expected_text);
|
||||
assert_eq!(editor.selections.ranges(cx), expected_selections);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
expected_selections
|
||||
);
|
||||
|
||||
editor.newline(&Newline, window, cx);
|
||||
let (expected_text, expected_selections) = marked_text_ranges(
|
||||
|
|
@ -16044,7 +16152,10 @@ fn test_editing_overlapping_excerpts(cx: &mut TestAppContext) {
|
|||
false,
|
||||
);
|
||||
assert_eq!(editor.text(cx), expected_text);
|
||||
assert_eq!(editor.selections.ranges(cx), expected_selections);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
expected_selections
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -16085,7 +16196,7 @@ fn test_refresh_selections(cx: &mut TestAppContext) {
|
|||
cx,
|
||||
);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(cx),
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[
|
||||
Point::new(1, 3)..Point::new(1, 3),
|
||||
Point::new(2, 1)..Point::new(2, 1),
|
||||
|
|
@ -16098,7 +16209,7 @@ fn test_refresh_selections(cx: &mut TestAppContext) {
|
|||
_ = editor.update(cx, |editor, window, cx| {
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| s.refresh());
|
||||
assert_eq!(
|
||||
editor.selections.ranges(cx),
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[
|
||||
Point::new(1, 3)..Point::new(1, 3),
|
||||
Point::new(2, 1)..Point::new(2, 1),
|
||||
|
|
@ -16112,7 +16223,7 @@ fn test_refresh_selections(cx: &mut TestAppContext) {
|
|||
_ = editor.update(cx, |editor, window, cx| {
|
||||
// Removing an excerpt causes the first selection to become degenerate.
|
||||
assert_eq!(
|
||||
editor.selections.ranges(cx),
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[
|
||||
Point::new(0, 0)..Point::new(0, 0),
|
||||
Point::new(0, 1)..Point::new(0, 1)
|
||||
|
|
@ -16123,7 +16234,7 @@ fn test_refresh_selections(cx: &mut TestAppContext) {
|
|||
// location.
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| s.refresh());
|
||||
assert_eq!(
|
||||
editor.selections.ranges(cx),
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[
|
||||
Point::new(0, 1)..Point::new(0, 1),
|
||||
Point::new(0, 3)..Point::new(0, 3)
|
||||
|
|
@ -16167,7 +16278,7 @@ fn test_refresh_selections_while_selecting_with_mouse(cx: &mut TestAppContext) {
|
|||
cx,
|
||||
);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(cx),
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[Point::new(1, 3)..Point::new(1, 3)]
|
||||
);
|
||||
editor
|
||||
|
|
@ -16178,14 +16289,14 @@ fn test_refresh_selections_while_selecting_with_mouse(cx: &mut TestAppContext) {
|
|||
});
|
||||
_ = editor.update(cx, |editor, window, cx| {
|
||||
assert_eq!(
|
||||
editor.selections.ranges(cx),
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[Point::new(0, 0)..Point::new(0, 0)]
|
||||
);
|
||||
|
||||
// Ensure we don't panic when selections are refreshed and that the pending selection is finalized.
|
||||
editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| s.refresh());
|
||||
assert_eq!(
|
||||
editor.selections.ranges(cx),
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
[Point::new(0, 3)..Point::new(0, 3)]
|
||||
);
|
||||
assert!(editor.selections.pending_anchor().is_some());
|
||||
|
|
@ -16435,7 +16546,10 @@ async fn test_following(cx: &mut TestAppContext) {
|
|||
.await
|
||||
.unwrap();
|
||||
_ = follower.update(cx, |follower, _, cx| {
|
||||
assert_eq!(follower.selections.ranges(cx), vec![1..1]);
|
||||
assert_eq!(
|
||||
follower.selections.ranges(&follower.display_snapshot(cx)),
|
||||
vec![1..1]
|
||||
);
|
||||
});
|
||||
assert!(*is_still_following.borrow());
|
||||
assert_eq!(*follower_edit_event_count.borrow(), 0);
|
||||
|
|
@ -16488,7 +16602,10 @@ async fn test_following(cx: &mut TestAppContext) {
|
|||
.unwrap();
|
||||
_ = follower.update(cx, |follower, _, cx| {
|
||||
assert_eq!(follower.scroll_position(cx), gpui::Point::new(1.5, 0.0));
|
||||
assert_eq!(follower.selections.ranges(cx), vec![0..0]);
|
||||
assert_eq!(
|
||||
follower.selections.ranges(&follower.display_snapshot(cx)),
|
||||
vec![0..0]
|
||||
);
|
||||
});
|
||||
assert!(*is_still_following.borrow());
|
||||
|
||||
|
|
@ -16512,7 +16629,10 @@ async fn test_following(cx: &mut TestAppContext) {
|
|||
.await
|
||||
.unwrap();
|
||||
_ = follower.update(cx, |follower, _, cx| {
|
||||
assert_eq!(follower.selections.ranges(cx), vec![0..0, 1..1]);
|
||||
assert_eq!(
|
||||
follower.selections.ranges(&follower.display_snapshot(cx)),
|
||||
vec![0..0, 1..1]
|
||||
);
|
||||
});
|
||||
assert!(*is_still_following.borrow());
|
||||
|
||||
|
|
@ -16533,7 +16653,10 @@ async fn test_following(cx: &mut TestAppContext) {
|
|||
.await
|
||||
.unwrap();
|
||||
_ = follower.update(cx, |follower, _, cx| {
|
||||
assert_eq!(follower.selections.ranges(cx), vec![0..2]);
|
||||
assert_eq!(
|
||||
follower.selections.ranges(&follower.display_snapshot(cx)),
|
||||
vec![0..2]
|
||||
);
|
||||
});
|
||||
|
||||
// Scrolling locally breaks the follow
|
||||
|
|
@ -22668,11 +22791,11 @@ fn add_log_breakpoint_at_cursor(
|
|||
.first()
|
||||
.and_then(|(anchor, bp)| bp.as_ref().map(|bp| (*anchor, bp.clone())))
|
||||
.unwrap_or_else(|| {
|
||||
let cursor_position: Point = editor.selections.newest(cx).head();
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let cursor_position: Point =
|
||||
editor.selections.newest(&snapshot.display_snapshot).head();
|
||||
|
||||
let breakpoint_position = editor
|
||||
.snapshot(window, cx)
|
||||
.display_snapshot
|
||||
let breakpoint_position = snapshot
|
||||
.buffer_snapshot()
|
||||
.anchor_before(Point::new(cursor_position.row, 0));
|
||||
|
||||
|
|
@ -23619,7 +23742,7 @@ println!("5");
|
|||
assert_eq!(
|
||||
editor
|
||||
.selections
|
||||
.all::<Point>(cx)
|
||||
.all::<Point>(&editor.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.map(|s| s.range())
|
||||
.collect::<Vec<_>>(),
|
||||
|
|
@ -23662,7 +23785,7 @@ println!("5");
|
|||
assert_eq!(
|
||||
editor
|
||||
.selections
|
||||
.all::<Point>(cx)
|
||||
.all::<Point>(&editor.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.map(|s| s.range())
|
||||
.collect::<Vec<_>>(),
|
||||
|
|
@ -23788,7 +23911,7 @@ println!("5");
|
|||
assert_eq!(
|
||||
editor
|
||||
.selections
|
||||
.all::<Point>(cx)
|
||||
.all::<Point>(&editor.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.map(|s| s.range())
|
||||
.collect::<Vec<_>>(),
|
||||
|
|
@ -23814,7 +23937,7 @@ println!("5");
|
|||
assert_eq!(
|
||||
editor
|
||||
.selections
|
||||
.all::<Point>(cx)
|
||||
.all::<Point>(&editor.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.map(|s| s.range())
|
||||
.collect::<Vec<_>>(),
|
||||
|
|
@ -25211,7 +25334,7 @@ fn assert_selection_ranges(marked_text: &str, editor: &mut Editor, cx: &mut Cont
|
|||
let (text, ranges) = marked_text_ranges(marked_text, true);
|
||||
assert_eq!(editor.text(cx), text);
|
||||
assert_eq!(
|
||||
editor.selections.ranges(cx),
|
||||
editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
ranges,
|
||||
"Assert selections are {}",
|
||||
marked_text
|
||||
|
|
|
|||
|
|
@ -1377,7 +1377,7 @@ impl EditorElement {
|
|||
editor_with_selections.update(cx, |editor, cx| {
|
||||
if editor.show_local_selections {
|
||||
let mut layouts = Vec::new();
|
||||
let newest = editor.selections.newest(cx);
|
||||
let newest = editor.selections.newest(&editor.display_snapshot(cx));
|
||||
for selection in local_selections.iter().cloned() {
|
||||
let is_empty = selection.start == selection.end;
|
||||
let is_newest = selection == newest;
|
||||
|
|
@ -3195,7 +3195,9 @@ impl EditorElement {
|
|||
|
||||
let (newest_selection_head, is_relative) = self.editor.update(cx, |editor, cx| {
|
||||
let newest_selection_head = newest_selection_head.unwrap_or_else(|| {
|
||||
let newest = editor.selections.newest::<Point>(cx);
|
||||
let newest = editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx));
|
||||
SelectionLayout::new(
|
||||
newest,
|
||||
editor.selections.line_mode(),
|
||||
|
|
@ -8793,7 +8795,8 @@ impl Element for EditorElement {
|
|||
.editor_with_selections(cx)
|
||||
.map(|editor| {
|
||||
editor.update(cx, |editor, cx| {
|
||||
let all_selections = editor.selections.all::<Point>(cx);
|
||||
let all_selections =
|
||||
editor.selections.all::<Point>(&snapshot.display_snapshot);
|
||||
let selected_buffer_ids =
|
||||
if editor.buffer_kind(cx) == ItemBufferKind::Singleton {
|
||||
Vec::new()
|
||||
|
|
@ -8815,10 +8818,12 @@ impl Element for EditorElement {
|
|||
selected_buffer_ids
|
||||
};
|
||||
|
||||
let mut selections = editor
|
||||
.selections
|
||||
.disjoint_in_range(start_anchor..end_anchor, cx);
|
||||
selections.extend(editor.selections.pending(cx));
|
||||
let mut selections = editor.selections.disjoint_in_range(
|
||||
start_anchor..end_anchor,
|
||||
&snapshot.display_snapshot,
|
||||
);
|
||||
selections
|
||||
.extend(editor.selections.pending(&snapshot.display_snapshot));
|
||||
|
||||
(selections, selected_buffer_ids)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Editor>,
|
||||
) -> Option<HashSet<usize>> {
|
||||
let selection = self.selections.newest::<Point>(cx);
|
||||
let selection = self.selections.newest::<Point>(&self.display_snapshot(cx));
|
||||
let cursor_row = MultiBufferRow(selection.head().row);
|
||||
|
||||
let state = &mut self.active_indent_guides_state;
|
||||
|
|
|
|||
|
|
@ -594,7 +594,7 @@ impl Item for Editor {
|
|||
cx: &mut Context<Self>,
|
||||
) -> bool {
|
||||
if let Ok(data) = data.downcast::<NavigationData>() {
|
||||
let newest_selection = self.selections.newest::<Point>(cx);
|
||||
let newest_selection = self.selections.newest::<Point>(&self.display_snapshot(cx));
|
||||
let buffer = self.buffer.read(cx).read(cx);
|
||||
let offset = if buffer.can_resolve(&data.cursor_anchor) {
|
||||
data.cursor_anchor.to_point(&buffer)
|
||||
|
|
@ -1539,13 +1539,13 @@ impl SearchableItem for Editor {
|
|||
fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> String {
|
||||
let setting = EditorSettings::get_global(cx).seed_search_query_from_cursor;
|
||||
let snapshot = self.snapshot(window, cx);
|
||||
let snapshot = snapshot.buffer_snapshot();
|
||||
let selection = self.selections.newest_adjusted(cx);
|
||||
let selection = self.selections.newest_adjusted(&snapshot.display_snapshot);
|
||||
let buffer_snapshot = snapshot.buffer_snapshot();
|
||||
|
||||
match setting {
|
||||
SeedQuerySetting::Never => String::new(),
|
||||
SeedQuerySetting::Selection | SeedQuerySetting::Always if !selection.is_empty() => {
|
||||
let text: String = snapshot
|
||||
let text: String = buffer_snapshot
|
||||
.text_for_range(selection.start..selection.end)
|
||||
.collect();
|
||||
if text.contains('\n') {
|
||||
|
|
@ -1556,10 +1556,10 @@ impl SearchableItem for Editor {
|
|||
}
|
||||
SeedQuerySetting::Selection => String::new(),
|
||||
SeedQuerySetting::Always => {
|
||||
let (range, kind) =
|
||||
snapshot.surrounding_word(selection.start, Some(CharScopeContext::Completion));
|
||||
let (range, kind) = buffer_snapshot
|
||||
.surrounding_word(selection.start, Some(CharScopeContext::Completion));
|
||||
if kind == Some(CharKind::Word) {
|
||||
let text: String = snapshot.text_for_range(range).collect();
|
||||
let text: String = buffer_snapshot.text_for_range(range).collect();
|
||||
if !text.trim().is_empty() {
|
||||
return text;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ pub(super) fn refresh_linked_ranges(
|
|||
let mut applicable_selections = Vec::new();
|
||||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
let selections = editor.selections.all::<usize>(cx);
|
||||
let selections = editor.selections.all::<usize>(&editor.display_snapshot(cx));
|
||||
let snapshot = editor.buffer.read(cx).snapshot(cx);
|
||||
let buffer = editor.buffer.read(cx);
|
||||
for selection in selections {
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ pub fn deploy_context_menu(
|
|||
return;
|
||||
}
|
||||
|
||||
let display_map = editor.selections.display_map(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let source_anchor = display_map.display_point_to_anchor(point, text::Bias::Right);
|
||||
let context_menu = if let Some(custom) = editor.custom_context_menu.take() {
|
||||
let menu = custom(editor, point, window, cx);
|
||||
|
|
@ -169,8 +169,8 @@ pub fn deploy_context_menu(
|
|||
return;
|
||||
};
|
||||
|
||||
let display_map = editor.selections.display_map(cx);
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let buffer = snapshot.buffer_snapshot();
|
||||
let anchor = buffer.anchor_before(point.to_point(&display_map));
|
||||
if !display_ranges(&display_map, &editor.selections).any(|r| r.contains(&point)) {
|
||||
|
|
@ -185,7 +185,7 @@ pub fn deploy_context_menu(
|
|||
let has_reveal_target = editor.target_file(cx).is_some();
|
||||
let has_selections = editor
|
||||
.selections
|
||||
.all::<PointUtf16>(cx)
|
||||
.all::<PointUtf16>(&display_map)
|
||||
.into_iter()
|
||||
.any(|s| !s.is_empty());
|
||||
let has_git_repo = buffer
|
||||
|
|
|
|||
|
|
@ -72,7 +72,12 @@ impl Editor {
|
|||
cx: &mut Context<Editor>,
|
||||
) {
|
||||
let scroll_margin_rows = self.vertical_scroll_margin() as u32;
|
||||
let new_screen_top = self.selections.newest_display(cx).head().row().0;
|
||||
let new_screen_top = self
|
||||
.selections
|
||||
.newest_display(&self.display_snapshot(cx))
|
||||
.head()
|
||||
.row()
|
||||
.0;
|
||||
let new_screen_top = new_screen_top.saturating_sub(scroll_margin_rows);
|
||||
self.set_scroll_top_row(DisplayRow(new_screen_top), window, cx);
|
||||
}
|
||||
|
|
@ -86,7 +91,12 @@ impl Editor {
|
|||
let Some(visible_rows) = self.visible_line_count().map(|count| count as u32) else {
|
||||
return;
|
||||
};
|
||||
let new_screen_top = self.selections.newest_display(cx).head().row().0;
|
||||
let new_screen_top = self
|
||||
.selections
|
||||
.newest_display(&self.display_snapshot(cx))
|
||||
.head()
|
||||
.row()
|
||||
.0;
|
||||
let new_screen_top = new_screen_top.saturating_sub(visible_rows / 2);
|
||||
self.set_scroll_top_row(DisplayRow(new_screen_top), window, cx);
|
||||
}
|
||||
|
|
@ -101,7 +111,12 @@ impl Editor {
|
|||
let Some(visible_rows) = self.visible_line_count().map(|count| count as u32) else {
|
||||
return;
|
||||
};
|
||||
let new_screen_top = self.selections.newest_display(cx).head().row().0;
|
||||
let new_screen_top = self
|
||||
.selections
|
||||
.newest_display(&self.display_snapshot(cx))
|
||||
.head()
|
||||
.row()
|
||||
.0;
|
||||
let new_screen_top =
|
||||
new_screen_top.saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
|
||||
self.set_scroll_top_row(DisplayRow(new_screen_top), window, cx);
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ impl Editor {
|
|||
target_top = first_highlighted_row.as_f64();
|
||||
target_bottom = target_top + 1.;
|
||||
} else {
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let selections = self.selections.all::<Point>(&display_map);
|
||||
|
||||
target_top = selections
|
||||
.first()
|
||||
|
|
@ -293,7 +293,7 @@ impl Editor {
|
|||
let scroll_width = ScrollOffset::from(scroll_width);
|
||||
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let selections = self.selections.all::<Point>(&display_map);
|
||||
let mut scroll_position = self.scroll_manager.scroll_position(&display_map);
|
||||
|
||||
let mut target_left;
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ impl SelectionsCollection {
|
|||
if self.pending.is_none() {
|
||||
self.disjoint_anchors_arc()
|
||||
} else {
|
||||
let all_offset_selections = self.all::<usize>(cx);
|
||||
let all_offset_selections = self.all::<usize>(&self.display_map(cx));
|
||||
let buffer = self.buffer(cx);
|
||||
all_offset_selections
|
||||
.into_iter()
|
||||
|
|
@ -129,25 +129,23 @@ impl SelectionsCollection {
|
|||
|
||||
pub fn pending<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||
&self,
|
||||
cx: &mut App,
|
||||
snapshot: &DisplaySnapshot,
|
||||
) -> Option<Selection<D>> {
|
||||
let map = self.display_map(cx);
|
||||
|
||||
resolve_selections(self.pending_anchor(), &map).next()
|
||||
resolve_selections(self.pending_anchor(), &snapshot).next()
|
||||
}
|
||||
|
||||
pub(crate) fn pending_mode(&self) -> Option<SelectMode> {
|
||||
self.pending.as_ref().map(|pending| pending.mode.clone())
|
||||
}
|
||||
|
||||
pub fn all<'a, D>(&self, cx: &mut App) -> Vec<Selection<D>>
|
||||
pub fn all<'a, D>(&self, snapshot: &DisplaySnapshot) -> Vec<Selection<D>>
|
||||
where
|
||||
D: 'a + TextDimension + Ord + Sub<D, Output = D>,
|
||||
{
|
||||
let map = self.display_map(cx);
|
||||
let disjoint_anchors = &self.disjoint;
|
||||
let mut disjoint = resolve_selections::<D, _>(disjoint_anchors.iter(), &map).peekable();
|
||||
let mut pending_opt = self.pending::<D>(cx);
|
||||
let mut disjoint =
|
||||
resolve_selections::<D, _>(disjoint_anchors.iter(), &snapshot).peekable();
|
||||
let mut pending_opt = self.pending::<D>(&snapshot);
|
||||
iter::from_fn(move || {
|
||||
if let Some(pending) = pending_opt.as_mut() {
|
||||
while let Some(next_selection) = disjoint.peek() {
|
||||
|
|
@ -175,12 +173,11 @@ impl SelectionsCollection {
|
|||
}
|
||||
|
||||
/// Returns all of the selections, adjusted to take into account the selection line_mode
|
||||
pub fn all_adjusted(&self, cx: &mut App) -> Vec<Selection<Point>> {
|
||||
let mut selections = self.all::<Point>(cx);
|
||||
pub fn all_adjusted(&self, snapshot: &DisplaySnapshot) -> Vec<Selection<Point>> {
|
||||
let mut selections = self.all::<Point>(&snapshot);
|
||||
if self.line_mode {
|
||||
let map = self.display_map(cx);
|
||||
for selection in &mut selections {
|
||||
let new_range = map.expand_to_line(selection.range());
|
||||
let new_range = snapshot.expand_to_line(selection.range());
|
||||
selection.start = new_range.start;
|
||||
selection.end = new_range.end;
|
||||
}
|
||||
|
|
@ -210,11 +207,10 @@ impl SelectionsCollection {
|
|||
}
|
||||
|
||||
/// Returns the newest selection, adjusted to take into account the selection line_mode
|
||||
pub fn newest_adjusted(&self, cx: &mut App) -> Selection<Point> {
|
||||
let mut selection = self.newest::<Point>(cx);
|
||||
pub fn newest_adjusted(&self, snapshot: &DisplaySnapshot) -> Selection<Point> {
|
||||
let mut selection = self.newest::<Point>(&snapshot);
|
||||
if self.line_mode {
|
||||
let map = self.display_map(cx);
|
||||
let new_range = map.expand_to_line(selection.range());
|
||||
let new_range = snapshot.expand_to_line(selection.range());
|
||||
selection.start = new_range.start;
|
||||
selection.end = new_range.end;
|
||||
}
|
||||
|
|
@ -223,53 +219,55 @@ impl SelectionsCollection {
|
|||
|
||||
pub fn all_adjusted_display(
|
||||
&self,
|
||||
cx: &mut App,
|
||||
) -> (DisplaySnapshot, Vec<Selection<DisplayPoint>>) {
|
||||
display_map: &DisplaySnapshot,
|
||||
) -> Vec<Selection<DisplayPoint>> {
|
||||
if self.line_mode {
|
||||
let selections = self.all::<Point>(cx);
|
||||
let map = self.display_map(cx);
|
||||
let selections = self.all::<Point>(&display_map);
|
||||
let result = selections
|
||||
.into_iter()
|
||||
.map(|mut selection| {
|
||||
let new_range = map.expand_to_line(selection.range());
|
||||
let new_range = display_map.expand_to_line(selection.range());
|
||||
selection.start = new_range.start;
|
||||
selection.end = new_range.end;
|
||||
selection.map(|point| point.to_display_point(&map))
|
||||
selection.map(|point| point.to_display_point(&display_map))
|
||||
})
|
||||
.collect();
|
||||
(map, result)
|
||||
result
|
||||
} else {
|
||||
self.all_display(cx)
|
||||
self.all_display(display_map)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn disjoint_in_range<'a, D>(&self, range: Range<Anchor>, cx: &mut App) -> Vec<Selection<D>>
|
||||
pub fn disjoint_in_range<'a, D>(
|
||||
&self,
|
||||
range: Range<Anchor>,
|
||||
snapshot: &DisplaySnapshot,
|
||||
) -> Vec<Selection<D>>
|
||||
where
|
||||
D: 'a + TextDimension + Ord + Sub<D, Output = D> + std::fmt::Debug,
|
||||
{
|
||||
let map = self.display_map(cx);
|
||||
let start_ix = match self
|
||||
.disjoint
|
||||
.binary_search_by(|probe| probe.end.cmp(&range.start, map.buffer_snapshot()))
|
||||
.binary_search_by(|probe| probe.end.cmp(&range.start, snapshot.buffer_snapshot()))
|
||||
{
|
||||
Ok(ix) | Err(ix) => ix,
|
||||
};
|
||||
let end_ix = match self
|
||||
.disjoint
|
||||
.binary_search_by(|probe| probe.start.cmp(&range.end, map.buffer_snapshot()))
|
||||
.binary_search_by(|probe| probe.start.cmp(&range.end, snapshot.buffer_snapshot()))
|
||||
{
|
||||
Ok(ix) => ix + 1,
|
||||
Err(ix) => ix,
|
||||
};
|
||||
resolve_selections(&self.disjoint[start_ix..end_ix], &map).collect()
|
||||
resolve_selections(&self.disjoint[start_ix..end_ix], snapshot).collect()
|
||||
}
|
||||
|
||||
pub fn all_display(&self, cx: &mut App) -> (DisplaySnapshot, Vec<Selection<DisplayPoint>>) {
|
||||
let map = self.display_map(cx);
|
||||
pub fn all_display(&self, snapshot: &DisplaySnapshot) -> Vec<Selection<DisplayPoint>> {
|
||||
let disjoint_anchors = &self.disjoint;
|
||||
let mut disjoint = resolve_selections_display(disjoint_anchors.iter(), &map).peekable();
|
||||
let mut pending_opt = resolve_selections_display(self.pending_anchor(), &map).next();
|
||||
let selections = iter::from_fn(move || {
|
||||
let mut disjoint =
|
||||
resolve_selections_display(disjoint_anchors.iter(), &snapshot).peekable();
|
||||
let mut pending_opt = resolve_selections_display(self.pending_anchor(), &snapshot).next();
|
||||
iter::from_fn(move || {
|
||||
if let Some(pending) = pending_opt.as_mut() {
|
||||
while let Some(next_selection) = disjoint.peek() {
|
||||
if pending.start <= next_selection.end && pending.end >= next_selection.start {
|
||||
|
|
@ -292,8 +290,7 @@ impl SelectionsCollection {
|
|||
disjoint.next()
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
(map, selections)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn newest_anchor(&self) -> &Selection<Anchor> {
|
||||
|
|
@ -306,19 +303,15 @@ impl SelectionsCollection {
|
|||
|
||||
pub fn newest<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||
&self,
|
||||
cx: &mut App,
|
||||
snapshot: &DisplaySnapshot,
|
||||
) -> Selection<D> {
|
||||
let map = self.display_map(cx);
|
||||
|
||||
resolve_selections([self.newest_anchor()], &map)
|
||||
resolve_selections([self.newest_anchor()], &snapshot)
|
||||
.next()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn newest_display(&self, cx: &mut App) -> Selection<DisplayPoint> {
|
||||
let map = self.display_map(cx);
|
||||
|
||||
resolve_selections_display([self.newest_anchor()], &map)
|
||||
pub fn newest_display(&self, snapshot: &DisplaySnapshot) -> Selection<DisplayPoint> {
|
||||
resolve_selections_display([self.newest_anchor()], &snapshot)
|
||||
.next()
|
||||
.unwrap()
|
||||
}
|
||||
|
|
@ -333,11 +326,9 @@ impl SelectionsCollection {
|
|||
|
||||
pub fn oldest<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||
&self,
|
||||
cx: &mut App,
|
||||
snapshot: &DisplaySnapshot,
|
||||
) -> Selection<D> {
|
||||
let map = self.display_map(cx);
|
||||
|
||||
resolve_selections([self.oldest_anchor()], &map)
|
||||
resolve_selections([self.oldest_anchor()], &snapshot)
|
||||
.next()
|
||||
.unwrap()
|
||||
}
|
||||
|
|
@ -349,12 +340,18 @@ impl SelectionsCollection {
|
|||
.unwrap_or_else(|| self.disjoint.first().cloned().unwrap())
|
||||
}
|
||||
|
||||
pub fn first<D: TextDimension + Ord + Sub<D, Output = D>>(&self, cx: &mut App) -> Selection<D> {
|
||||
self.all(cx).first().unwrap().clone()
|
||||
pub fn first<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||
&self,
|
||||
snapshot: &DisplaySnapshot,
|
||||
) -> Selection<D> {
|
||||
self.all(snapshot).first().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn last<D: TextDimension + Ord + Sub<D, Output = D>>(&self, cx: &mut App) -> Selection<D> {
|
||||
self.all(cx).last().unwrap().clone()
|
||||
pub fn last<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||
&self,
|
||||
snapshot: &DisplaySnapshot,
|
||||
) -> Selection<D> {
|
||||
self.all(snapshot).last().unwrap().clone()
|
||||
}
|
||||
|
||||
/// Returns a list of (potentially backwards!) ranges representing the selections.
|
||||
|
|
@ -362,9 +359,9 @@ impl SelectionsCollection {
|
|||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn ranges<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||
&self,
|
||||
cx: &mut App,
|
||||
snapshot: &DisplaySnapshot,
|
||||
) -> Vec<Range<D>> {
|
||||
self.all::<D>(cx)
|
||||
self.all::<D>(snapshot)
|
||||
.iter()
|
||||
.map(|s| {
|
||||
if s.reversed {
|
||||
|
|
@ -596,7 +593,8 @@ impl<'a> MutableSelectionsCollection<'a> {
|
|||
where
|
||||
T: 'a + ToOffset + ToPoint + TextDimension + Ord + Sub<T, Output = T> + std::marker::Copy,
|
||||
{
|
||||
let mut selections = self.collection.all(self.cx);
|
||||
let display_map = self.display_map();
|
||||
let mut selections = self.collection.all(&display_map);
|
||||
let mut start = range.start.to_offset(&self.buffer());
|
||||
let mut end = range.end.to_offset(&self.buffer());
|
||||
let reversed = if start > end {
|
||||
|
|
@ -790,7 +788,7 @@ impl<'a> MutableSelectionsCollection<'a> {
|
|||
) {
|
||||
let mut changed = false;
|
||||
let display_map = self.display_map();
|
||||
let (_, selections) = self.collection.all_display(self.cx);
|
||||
let selections = self.collection.all_display(&display_map);
|
||||
let selections = selections
|
||||
.into_iter()
|
||||
.map(|selection| {
|
||||
|
|
@ -814,9 +812,10 @@ impl<'a> MutableSelectionsCollection<'a> {
|
|||
) {
|
||||
let mut changed = false;
|
||||
let snapshot = self.buffer().clone();
|
||||
let display_map = self.display_map();
|
||||
let selections = self
|
||||
.collection
|
||||
.all::<usize>(self.cx)
|
||||
.all::<usize>(&display_map)
|
||||
.into_iter()
|
||||
.map(|selection| {
|
||||
let mut moved_selection = selection.clone();
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ impl Editor {
|
|||
if !(self.signature_help_state.is_shown() || self.auto_signature_help_enabled(cx)) {
|
||||
return false;
|
||||
}
|
||||
let newest_selection = self.selections.newest::<usize>(cx);
|
||||
let newest_selection = self.selections.newest::<usize>(&self.display_snapshot(cx));
|
||||
let head = newest_selection.head();
|
||||
|
||||
if !newest_selection.is_empty() && head != newest_selection.tail() {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ impl Editor {
|
|||
return Task::ready(None);
|
||||
};
|
||||
let (selection, buffer, editor_snapshot) = {
|
||||
let selection = self.selections.newest_adjusted(cx);
|
||||
let selection = self.selections.newest_adjusted(&self.display_snapshot(cx));
|
||||
let Some((buffer, _)) = self
|
||||
.buffer()
|
||||
.read(cx)
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ pub fn assert_text_with_selections(
|
|||
assert_eq!(editor.text(cx), unmarked_text, "text doesn't match");
|
||||
let actual = generate_marked_text(
|
||||
&editor.text(cx),
|
||||
&editor.selections.ranges(cx),
|
||||
&editor.selections.ranges(&editor.display_snapshot(cx)),
|
||||
marked_text.contains("«"),
|
||||
);
|
||||
assert_eq!(actual, marked_text, "Selections don't match");
|
||||
|
|
|
|||
|
|
@ -265,7 +265,10 @@ impl EditorTestContext {
|
|||
|
||||
pub fn pixel_position_for(&mut self, display_point: DisplayPoint) -> Point<Pixels> {
|
||||
self.update_editor(|editor, window, cx| {
|
||||
let newest_point = editor.selections.newest_display(cx).head();
|
||||
let newest_point = editor
|
||||
.selections
|
||||
.newest_display(&editor.display_snapshot(cx))
|
||||
.head();
|
||||
let pixel_position = editor.pixel_position_of_newest_cursor.unwrap();
|
||||
let line_height = editor
|
||||
.style()
|
||||
|
|
@ -590,7 +593,7 @@ impl EditorTestContext {
|
|||
fn editor_selections(&mut self) -> Vec<Range<usize>> {
|
||||
self.editor
|
||||
.update(&mut self.cx, |editor, cx| {
|
||||
editor.selections.all::<usize>(cx)
|
||||
editor.selections.all::<usize>(&editor.display_snapshot(cx))
|
||||
})
|
||||
.into_iter()
|
||||
.map(|s| {
|
||||
|
|
@ -688,9 +691,12 @@ pub fn assert_state_with_diff(
|
|||
expected_diff_text: &str,
|
||||
) {
|
||||
let (snapshot, selections) = editor.update_in(cx, |editor, window, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
(
|
||||
editor.snapshot(window, cx).buffer_snapshot().clone(),
|
||||
editor.selections.ranges::<usize>(cx),
|
||||
snapshot.buffer_snapshot().clone(),
|
||||
editor
|
||||
.selections
|
||||
.ranges::<usize>(&snapshot.display_snapshot),
|
||||
)
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -490,7 +490,7 @@ async fn test_row_column_numbers_query_inside_file(cx: &mut TestAppContext) {
|
|||
cx.executor().advance_clock(Duration::from_secs(2));
|
||||
|
||||
editor.update(cx, |editor, cx| {
|
||||
let all_selections = editor.selections.all_adjusted(cx);
|
||||
let all_selections = editor.selections.all_adjusted(&editor.display_snapshot(cx));
|
||||
assert_eq!(
|
||||
all_selections.len(),
|
||||
1,
|
||||
|
|
@ -565,7 +565,7 @@ async fn test_row_column_numbers_query_outside_file(cx: &mut TestAppContext) {
|
|||
cx.executor().advance_clock(Duration::from_secs(2));
|
||||
|
||||
editor.update(cx, |editor, cx| {
|
||||
let all_selections = editor.selections.all_adjusted(cx);
|
||||
let all_selections = editor.selections.all_adjusted(&editor.display_snapshot(cx));
|
||||
assert_eq!(
|
||||
all_selections.len(),
|
||||
1,
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ impl TextDiffView {
|
|||
let selection_data = source_editor.update(cx, |editor, cx| {
|
||||
let multibuffer = editor.buffer().read(cx);
|
||||
let source_buffer = multibuffer.as_singleton()?;
|
||||
let selections = editor.selections.all::<Point>(cx);
|
||||
let selections = editor.selections.all::<Point>(&editor.display_snapshot(cx));
|
||||
let buffer_snapshot = source_buffer.read(cx);
|
||||
let first_selection = selections.first()?;
|
||||
let max_point = buffer_snapshot.max_point();
|
||||
|
|
|
|||
|
|
@ -74,7 +74,9 @@ impl GoToLine {
|
|||
) -> Self {
|
||||
let (user_caret, last_line, scroll_position) = active_editor.update(cx, |editor, cx| {
|
||||
let user_caret = UserCaretPosition::at_selection_end(
|
||||
&editor.selections.last::<Point>(cx),
|
||||
&editor
|
||||
.selections
|
||||
.last::<Point>(&editor.display_snapshot(cx)),
|
||||
&editor.buffer().read(cx).snapshot(cx),
|
||||
);
|
||||
|
||||
|
|
@ -739,7 +741,7 @@ mod tests {
|
|||
let selections = editor.update(cx, |editor, cx| {
|
||||
editor
|
||||
.selections
|
||||
.all::<rope::Point>(cx)
|
||||
.all::<rope::Point>(&editor.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.map(|s| s.start..s.end)
|
||||
.collect::<Vec<_>>()
|
||||
|
|
|
|||
|
|
@ -229,8 +229,11 @@ impl LspLogView {
|
|||
log_view.editor.update(cx, |editor, cx| {
|
||||
editor.set_read_only(false);
|
||||
let last_offset = editor.buffer().read(cx).len(cx);
|
||||
let newest_cursor_is_at_end =
|
||||
editor.selections.newest::<usize>(cx).start >= last_offset;
|
||||
let newest_cursor_is_at_end = editor
|
||||
.selections
|
||||
.newest::<usize>(&editor.display_snapshot(cx))
|
||||
.start
|
||||
>= last_offset;
|
||||
editor.edit(
|
||||
vec![
|
||||
(last_offset..last_offset, text.as_str()),
|
||||
|
|
|
|||
|
|
@ -252,7 +252,10 @@ impl SyntaxTreeView {
|
|||
.editor
|
||||
.update(cx, |editor, cx| editor.snapshot(window, cx));
|
||||
let (buffer, range, excerpt_id) = editor_state.editor.update(cx, |editor, cx| {
|
||||
let selection_range = editor.selections.last::<usize>(cx).range();
|
||||
let selection_range = editor
|
||||
.selections
|
||||
.last::<usize>(&editor.display_snapshot(cx))
|
||||
.range();
|
||||
let multi_buffer = editor.buffer().read(cx);
|
||||
let (buffer, range, excerpt_id) = snapshot
|
||||
.buffer_snapshot()
|
||||
|
|
|
|||
|
|
@ -278,8 +278,12 @@ impl MarkdownPreviewView {
|
|||
this.parse_markdown_from_active_editor(true, window, cx);
|
||||
}
|
||||
EditorEvent::SelectionsChanged { .. } => {
|
||||
let selection_range = editor
|
||||
.update(cx, |editor, cx| editor.selections.last::<usize>(cx).range());
|
||||
let selection_range = editor.update(cx, |editor, cx| {
|
||||
editor
|
||||
.selections
|
||||
.last::<usize>(&editor.display_snapshot(cx))
|
||||
.range()
|
||||
});
|
||||
this.selected_block = this.get_block_index_under_cursor(selection_range);
|
||||
this.list_state.scroll_to_reveal_item(this.selected_block);
|
||||
cx.notify();
|
||||
|
|
|
|||
|
|
@ -245,7 +245,10 @@ impl PickerDelegate for OutlineViewDelegate {
|
|||
|
||||
let (buffer, cursor_offset) = self.active_editor.update(cx, |editor, cx| {
|
||||
let buffer = editor.buffer().read(cx).snapshot(cx);
|
||||
let cursor_offset = editor.selections.newest::<usize>(cx).head();
|
||||
let cursor_offset = editor
|
||||
.selections
|
||||
.newest::<usize>(&editor.display_snapshot(cx))
|
||||
.head();
|
||||
(buffer, cursor_offset)
|
||||
});
|
||||
selected_index = self
|
||||
|
|
@ -673,7 +676,7 @@ mod tests {
|
|||
let selections = editor.update(cx, |editor, cx| {
|
||||
editor
|
||||
.selections
|
||||
.all::<rope::Point>(cx)
|
||||
.all::<rope::Point>(&editor.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.map(|s| s.start..s.end)
|
||||
.collect::<Vec<_>>()
|
||||
|
|
|
|||
|
|
@ -3099,7 +3099,10 @@ impl OutlinePanel {
|
|||
cx: &mut Context<Self>,
|
||||
) -> Option<PanelEntry> {
|
||||
let selection = editor.update(cx, |editor, cx| {
|
||||
editor.selections.newest::<language::Point>(cx).head()
|
||||
editor
|
||||
.selections
|
||||
.newest::<language::Point>(&editor.display_snapshot(cx))
|
||||
.head()
|
||||
});
|
||||
let editor_snapshot = editor.update(cx, |editor, cx| editor.snapshot(window, cx));
|
||||
let multi_buffer = editor.read(cx).buffer();
|
||||
|
|
@ -6957,13 +6960,13 @@ outline: struct OutlineEntryExcerpt
|
|||
|
||||
fn selected_row_text(editor: &Entity<Editor>, cx: &mut App) -> String {
|
||||
editor.update(cx, |editor, cx| {
|
||||
let selections = editor.selections.all::<language::Point>(cx);
|
||||
assert_eq!(selections.len(), 1, "Active editor should have exactly one selection after any outline panel interactions");
|
||||
let selection = selections.first().unwrap();
|
||||
let multi_buffer_snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
let line_start = language::Point::new(selection.start.row, 0);
|
||||
let line_end = multi_buffer_snapshot.clip_point(language::Point::new(selection.end.row, u32::MAX), language::Bias::Right);
|
||||
multi_buffer_snapshot.text_for_range(line_start..line_end).collect::<String>().trim().to_owned()
|
||||
let selections = editor.selections.all::<language::Point>(&editor.display_snapshot(cx));
|
||||
assert_eq!(selections.len(), 1, "Active editor should have exactly one selection after any outline panel interactions");
|
||||
let selection = selections.first().unwrap();
|
||||
let multi_buffer_snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
let line_start = language::Point::new(selection.start.row, 0);
|
||||
let line_end = multi_buffer_snapshot.clip_point(language::Point::new(selection.end.row, u32::MAX), language::Bias::Right);
|
||||
multi_buffer_snapshot.text_for_range(line_start..line_end).collect::<String>().trim().to_owned()
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -657,7 +657,7 @@ async fn test_editing_files(cx: &mut gpui::TestAppContext) {
|
|||
|
||||
let confirm = panel.update_in(cx, |panel, window, cx| {
|
||||
panel.filename_editor.update(cx, |editor, cx| {
|
||||
let file_name_selections = editor.selections.all::<usize>(cx);
|
||||
let file_name_selections = editor.selections.all::<usize>(&editor.display_snapshot(cx));
|
||||
assert_eq!(
|
||||
file_name_selections.len(),
|
||||
1,
|
||||
|
|
@ -731,7 +731,7 @@ async fn test_editing_files(cx: &mut gpui::TestAppContext) {
|
|||
|
||||
panel.update_in(cx, |panel, window, cx| {
|
||||
panel.filename_editor.update(cx, |editor, cx| {
|
||||
let file_name_selections = editor.selections.all::<usize>(cx);
|
||||
let file_name_selections = editor.selections.all::<usize>(&editor.display_snapshot(cx));
|
||||
assert_eq!(file_name_selections.len(), 1, "File editing should have a single selection, but got: {file_name_selections:?}");
|
||||
let file_name_selection = &file_name_selections[0];
|
||||
assert_eq!(file_name_selection.start, 0, "Should select the file name from the start");
|
||||
|
|
@ -1214,7 +1214,7 @@ async fn test_copy_paste(cx: &mut gpui::TestAppContext) {
|
|||
|
||||
panel.update_in(cx, |panel, window, cx| {
|
||||
panel.filename_editor.update(cx, |editor, cx| {
|
||||
let file_name_selections = editor.selections.all::<usize>(cx);
|
||||
let file_name_selections = editor.selections.all::<usize>(&editor.display_snapshot(cx));
|
||||
assert_eq!(
|
||||
file_name_selections.len(),
|
||||
1,
|
||||
|
|
|
|||
|
|
@ -85,7 +85,11 @@ pub fn run(
|
|||
|
||||
let editor = editor.upgrade().context("editor was dropped")?;
|
||||
let selected_range = editor
|
||||
.update(cx, |editor, cx| editor.selections.newest_adjusted(cx))
|
||||
.update(cx, |editor, cx| {
|
||||
editor
|
||||
.selections
|
||||
.newest_adjusted(&editor.display_snapshot(cx))
|
||||
})
|
||||
.range();
|
||||
let multibuffer = editor.read(cx).buffer().clone();
|
||||
let Some(buffer) = multibuffer.read(cx).as_singleton() else {
|
||||
|
|
@ -473,7 +477,9 @@ fn language_supported(language: &Arc<Language>, cx: &mut App) -> bool {
|
|||
fn get_language(editor: WeakEntity<Editor>, cx: &mut App) -> Option<Arc<Language>> {
|
||||
editor
|
||||
.update(cx, |editor, cx| {
|
||||
let selection = editor.selections.newest::<usize>(cx);
|
||||
let selection = editor
|
||||
.selections
|
||||
.newest::<usize>(&editor.display_snapshot(cx));
|
||||
let buffer = editor.buffer().read(cx).snapshot(cx);
|
||||
buffer.language_at(selection.head()).cloned()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ impl Vim {
|
|||
|
||||
pub(crate) fn push_to_change_list(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let Some((new_positions, buffer)) = self.update_editor(cx, |vim, editor, cx| {
|
||||
let (map, selections) = editor.selections.all_adjusted_display(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let selections = editor.selections.all_adjusted_display(&display_map);
|
||||
let buffer = editor.buffer().clone();
|
||||
|
||||
let pop_state = editor
|
||||
|
|
@ -59,7 +60,7 @@ impl Vim {
|
|||
.map(|previous| {
|
||||
previous.len() == selections.len()
|
||||
&& previous.iter().enumerate().all(|(ix, p)| {
|
||||
p.to_display_point(&map).row() == selections[ix].head().row()
|
||||
p.to_display_point(&display_map).row() == selections[ix].head().row()
|
||||
})
|
||||
})
|
||||
.unwrap_or(false);
|
||||
|
|
@ -68,11 +69,11 @@ impl Vim {
|
|||
.into_iter()
|
||||
.map(|s| {
|
||||
let point = if vim.mode == Mode::Insert {
|
||||
movement::saturating_left(&map, s.head())
|
||||
movement::saturating_left(&display_map, s.head())
|
||||
} else {
|
||||
s.head()
|
||||
};
|
||||
map.display_point_to_anchor(point, Bias::Left)
|
||||
display_map.display_point_to_anchor(point, Bias::Left)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
|
|
|||
|
|
@ -606,7 +606,9 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
|||
let result = vim.update_editor(cx, |vim, editor, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let buffer_row = action.range.head().buffer_row(vim, editor, window, cx)?;
|
||||
let current = editor.selections.newest::<Point>(cx);
|
||||
let current = editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx));
|
||||
let target = snapshot
|
||||
.buffer_snapshot()
|
||||
.clip_point(Point::new(buffer_row.0, current.head().column), Bias::Left);
|
||||
|
|
@ -1903,7 +1905,9 @@ impl OnMatchingLines {
|
|||
});
|
||||
window.dispatch_action(action, cx);
|
||||
cx.defer_in(window, move |editor, window, cx| {
|
||||
let newest = editor.selections.newest::<Point>(cx);
|
||||
let newest = editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx));
|
||||
editor.change_selections(
|
||||
SelectionEffects::no_scroll(),
|
||||
window,
|
||||
|
|
@ -2000,7 +2004,9 @@ impl Vim {
|
|||
};
|
||||
let command = self.update_editor(cx, |_, editor, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let start = editor.selections.newest_display(cx);
|
||||
let start = editor
|
||||
.selections
|
||||
.newest_display(&editor.display_snapshot(cx));
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
let (mut range, _) = motion
|
||||
.range(
|
||||
|
|
@ -2047,7 +2053,9 @@ impl Vim {
|
|||
};
|
||||
let command = self.update_editor(cx, |_, editor, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let start = editor.selections.newest_display(cx);
|
||||
let start = editor
|
||||
.selections
|
||||
.newest_display(&editor.display_snapshot(cx));
|
||||
let range = object
|
||||
.range(&snapshot, start.clone(), around, None)
|
||||
.unwrap_or(start.range());
|
||||
|
|
@ -2156,7 +2164,11 @@ impl ShellExec {
|
|||
Point::new(range.start.0, 0)
|
||||
..snapshot.clip_point(Point::new(range.end.0 + 1, 0), Bias::Right)
|
||||
} else {
|
||||
let mut end = editor.selections.newest::<Point>(cx).range().end;
|
||||
let mut end = editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx))
|
||||
.range()
|
||||
.end;
|
||||
end = snapshot.clip_point(Point::new(end.row + 1, 0), Bias::Right);
|
||||
needs_newline_prefix = end == snapshot.max_point();
|
||||
end..end
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ impl Vim {
|
|||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let has_selection = editor
|
||||
.selections
|
||||
.all_adjusted(cx)
|
||||
.all_adjusted(&editor.display_snapshot(cx))
|
||||
.iter()
|
||||
.any(|selection| !selection.is_empty());
|
||||
|
||||
|
|
@ -478,19 +478,20 @@ impl Vim {
|
|||
pub fn helix_replace(&mut self, text: &str, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let (map, selections) = editor.selections.all_display(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let selections = editor.selections.all_display(&display_map);
|
||||
|
||||
// Store selection info for positioning after edit
|
||||
let selection_info: Vec<_> = selections
|
||||
.iter()
|
||||
.map(|selection| {
|
||||
let range = selection.range();
|
||||
let start_offset = range.start.to_offset(&map, Bias::Left);
|
||||
let end_offset = range.end.to_offset(&map, Bias::Left);
|
||||
let start_offset = range.start.to_offset(&display_map, Bias::Left);
|
||||
let end_offset = range.end.to_offset(&display_map, Bias::Left);
|
||||
let was_empty = range.is_empty();
|
||||
let was_reversed = selection.reversed;
|
||||
(
|
||||
map.buffer_snapshot().anchor_before(start_offset),
|
||||
display_map.buffer_snapshot().anchor_before(start_offset),
|
||||
end_offset - start_offset,
|
||||
was_empty,
|
||||
was_reversed,
|
||||
|
|
@ -504,11 +505,11 @@ impl Vim {
|
|||
|
||||
// For empty selections, extend to replace one character
|
||||
if range.is_empty() {
|
||||
range.end = movement::saturating_right(&map, range.start);
|
||||
range.end = movement::saturating_right(&display_map, range.start);
|
||||
}
|
||||
|
||||
let byte_range = range.start.to_offset(&map, Bias::Left)
|
||||
..range.end.to_offset(&map, Bias::Left);
|
||||
let byte_range = range.start.to_offset(&display_map, Bias::Left)
|
||||
..range.end.to_offset(&display_map, Bias::Left);
|
||||
|
||||
if !byte_range.is_empty() {
|
||||
let replacement_text = text.repeat(byte_range.len());
|
||||
|
|
@ -568,7 +569,7 @@ impl Vim {
|
|||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
|
||||
let display_map = editor.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let mut selections = editor.selections.all::<Point>(cx);
|
||||
let mut selections = editor.selections.all::<Point>(&display_map);
|
||||
let max_point = display_map.buffer_snapshot().max_point();
|
||||
let buffer_snapshot = &display_map.buffer_snapshot();
|
||||
|
||||
|
|
@ -606,7 +607,9 @@ impl Vim {
|
|||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let newest = editor.selections.newest::<usize>(cx);
|
||||
let newest = editor
|
||||
.selections
|
||||
.newest::<usize>(&editor.display_snapshot(cx));
|
||||
editor.change_selections(Default::default(), window, cx, |s| s.select(vec![newest]));
|
||||
});
|
||||
}
|
||||
|
|
@ -633,7 +636,10 @@ impl Vim {
|
|||
if yank {
|
||||
vim.copy_selections_content(editor, MotionKind::Exclusive, window, cx);
|
||||
}
|
||||
let selections = editor.selections.all::<Point>(cx).into_iter();
|
||||
let selections = editor
|
||||
.selections
|
||||
.all::<Point>(&editor.display_snapshot(cx))
|
||||
.into_iter();
|
||||
let edits = selections.map(|selection| (selection.start..selection.end, ""));
|
||||
editor.edit(edits, cx);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -56,7 +56,8 @@ impl Vim {
|
|||
let times = times.unwrap_or(1);
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let mut selections = Vec::new();
|
||||
let (map, mut original_selections) = editor.selections.all_display(cx);
|
||||
let map = editor.display_snapshot(cx);
|
||||
let mut original_selections = editor.selections.all_display(&map);
|
||||
// The order matters, because it is recorded when the selections are added.
|
||||
if above {
|
||||
original_selections.reverse();
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ impl Vim {
|
|||
return;
|
||||
};
|
||||
|
||||
let (display_map, current_selections) = editor.selections.all_adjusted_display(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let current_selections = editor.selections.all_adjusted_display(&display_map);
|
||||
|
||||
// The clipboard can have multiple selections, and there can
|
||||
// be multiple selections. Helix zips them together, so the first
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ impl Vim {
|
|||
self.update_editor(cx, |_, editor, cx| {
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
let mut edits = Vec::new();
|
||||
for selection in editor.selections.all::<Point>(cx) {
|
||||
for selection in editor.selections.all::<Point>(&editor.display_snapshot(cx)) {
|
||||
let point = selection.head();
|
||||
let new_row = match direction {
|
||||
Direction::Next => point.row + 1,
|
||||
|
|
|
|||
|
|
@ -657,7 +657,7 @@ impl Vim {
|
|||
self.switch_mode(Mode::Insert, false, window, cx);
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let selections = editor.selections.all::<Point>(cx);
|
||||
let selections = editor.selections.all::<Point>(&editor.display_snapshot(cx));
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
|
||||
let selection_start_rows: BTreeSet<u32> = selections
|
||||
|
|
@ -699,7 +699,7 @@ impl Vim {
|
|||
self.update_editor(cx, |_, editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let selections = editor.selections.all::<Point>(cx);
|
||||
let selections = editor.selections.all::<Point>(&editor.display_snapshot(cx));
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
|
||||
let selection_end_rows: BTreeSet<u32> = selections
|
||||
|
|
@ -745,7 +745,7 @@ impl Vim {
|
|||
Vim::take_forced_motion(cx);
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, _, cx| {
|
||||
let selections = editor.selections.all::<Point>(cx);
|
||||
let selections = editor.selections.all::<Point>(&editor.display_snapshot(cx));
|
||||
|
||||
let selection_start_rows: BTreeSet<u32> = selections
|
||||
.into_iter()
|
||||
|
|
@ -774,9 +774,10 @@ impl Vim {
|
|||
Vim::take_forced_motion(cx);
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let selections = editor.selections.all::<Point>(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let selections = editor.selections.all::<Point>(&display_map);
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
let (_map, display_selections) = editor.selections.all_display(cx);
|
||||
let display_selections = editor.selections.all_display(&display_map);
|
||||
let original_positions = display_selections
|
||||
.iter()
|
||||
.map(|s| (s.id, s.head()))
|
||||
|
|
@ -937,13 +938,14 @@ impl Vim {
|
|||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let (map, display_selections) = editor.selections.all_display(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let display_selections = editor.selections.all_display(&display_map);
|
||||
|
||||
let mut edits = Vec::new();
|
||||
let mut edits = Vec::with_capacity(display_selections.len());
|
||||
for selection in &display_selections {
|
||||
let mut range = selection.range();
|
||||
for _ in 0..count {
|
||||
let new_point = movement::saturating_right(&map, range.end);
|
||||
let new_point = movement::saturating_right(&display_map, range.end);
|
||||
if range.end == new_point {
|
||||
return;
|
||||
}
|
||||
|
|
@ -951,8 +953,8 @@ impl Vim {
|
|||
}
|
||||
|
||||
edits.push((
|
||||
range.start.to_offset(&map, Bias::Left)
|
||||
..range.end.to_offset(&map, Bias::Left),
|
||||
range.start.to_offset(&display_map, Bias::Left)
|
||||
..range.end.to_offset(&display_map, Bias::Left),
|
||||
text.repeat(if is_return_char { 0 } else { count }),
|
||||
));
|
||||
}
|
||||
|
|
@ -976,16 +978,16 @@ impl Vim {
|
|||
pub fn save_selection_starts(
|
||||
&self,
|
||||
editor: &Editor,
|
||||
|
||||
cx: &mut Context<Editor>,
|
||||
) -> HashMap<usize, Anchor> {
|
||||
let (map, selections) = editor.selections.all_display(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let selections = editor.selections.all_display(&display_map);
|
||||
selections
|
||||
.iter()
|
||||
.map(|selection| {
|
||||
(
|
||||
selection.id,
|
||||
map.display_point_to_anchor(selection.start, Bias::Right),
|
||||
display_map.display_point_to_anchor(selection.start, Bias::Right),
|
||||
)
|
||||
})
|
||||
.collect::<HashMap<_, _>>()
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ impl Vim {
|
|||
let mut ranges = Vec::new();
|
||||
let mut cursor_positions = Vec::new();
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
for selection in editor.selections.all_adjusted(cx) {
|
||||
for selection in editor.selections.all_adjusted(&editor.display_snapshot(cx)) {
|
||||
match vim.mode {
|
||||
Mode::Visual | Mode::VisualLine => {
|
||||
ranges.push(selection.start..selection.end);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ impl Vim {
|
|||
let mut new_anchors = Vec::new();
|
||||
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
for selection in editor.selections.all_adjusted(cx) {
|
||||
for selection in editor.selections.all_adjusted(&editor.display_snapshot(cx)) {
|
||||
if !selection.is_empty()
|
||||
&& (vim.mode != Mode::VisualBlock || new_anchors.is_empty())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -50,16 +50,19 @@ impl Vim {
|
|||
let mut reversed = vec![];
|
||||
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let (map, selections) = editor.selections.all_display(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let selections = editor.selections.all_display(&display_map);
|
||||
for selection in selections {
|
||||
let end = movement::saturating_left(&map, selection.end);
|
||||
let end = movement::saturating_left(&display_map, selection.end);
|
||||
ends.push(
|
||||
map.buffer_snapshot()
|
||||
.anchor_before(end.to_offset(&map, Bias::Left)),
|
||||
display_map
|
||||
.buffer_snapshot()
|
||||
.anchor_before(end.to_offset(&display_map, Bias::Left)),
|
||||
);
|
||||
starts.push(
|
||||
map.buffer_snapshot()
|
||||
.anchor_before(selection.start.to_offset(&map, Bias::Left)),
|
||||
display_map
|
||||
.buffer_snapshot()
|
||||
.anchor_before(selection.start.to_offset(&display_map, Bias::Left)),
|
||||
);
|
||||
reversed.push(selection.reversed)
|
||||
}
|
||||
|
|
@ -301,19 +304,21 @@ impl Vim {
|
|||
name = "'";
|
||||
}
|
||||
if matches!(name, "{" | "}" | "(" | ")") {
|
||||
let (map, selections) = editor.selections.all_display(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let selections = editor.selections.all_display(&display_map);
|
||||
let anchors = selections
|
||||
.into_iter()
|
||||
.map(|selection| {
|
||||
let point = match name {
|
||||
"{" => movement::start_of_paragraph(&map, selection.head(), 1),
|
||||
"}" => movement::end_of_paragraph(&map, selection.head(), 1),
|
||||
"(" => motion::sentence_backwards(&map, selection.head(), 1),
|
||||
")" => motion::sentence_forwards(&map, selection.head(), 1),
|
||||
"{" => movement::start_of_paragraph(&display_map, selection.head(), 1),
|
||||
"}" => movement::end_of_paragraph(&display_map, selection.head(), 1),
|
||||
"(" => motion::sentence_backwards(&display_map, selection.head(), 1),
|
||||
")" => motion::sentence_forwards(&display_map, selection.head(), 1),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
map.buffer_snapshot()
|
||||
.anchor_before(point.to_offset(&map, Bias::Left))
|
||||
display_map
|
||||
.buffer_snapshot()
|
||||
.anchor_before(point.to_offset(&display_map, Bias::Left))
|
||||
})
|
||||
.collect::<Vec<Anchor>>();
|
||||
return Some(Mark::Local(anchors));
|
||||
|
|
|
|||
|
|
@ -56,7 +56,8 @@ impl Vim {
|
|||
vim.copy_selections_content(editor, MotionKind::for_mode(vim.mode), window, cx);
|
||||
}
|
||||
|
||||
let (display_map, current_selections) = editor.selections.all_adjusted_display(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let current_selections = editor.selections.all_adjusted_display(&display_map);
|
||||
|
||||
// unlike zed, if you have a multi-cursor selection from vim block mode,
|
||||
// pasting it will paste it on subsequent lines, even if you don't yet
|
||||
|
|
@ -173,7 +174,7 @@ impl Vim {
|
|||
original_indent_columns.push(original_indent_column);
|
||||
}
|
||||
|
||||
let cursor_offset = editor.selections.last::<usize>(cx).head();
|
||||
let cursor_offset = editor.selections.last::<usize>(&display_map).head();
|
||||
if editor
|
||||
.buffer()
|
||||
.read(cx)
|
||||
|
|
|
|||
|
|
@ -363,7 +363,10 @@ mod test {
|
|||
point(0., 3.0)
|
||||
);
|
||||
assert_eq!(
|
||||
editor.selections.newest(cx).range(),
|
||||
editor
|
||||
.selections
|
||||
.newest(&editor.display_snapshot(cx))
|
||||
.range(),
|
||||
Point::new(6, 0)..Point::new(6, 0)
|
||||
)
|
||||
});
|
||||
|
|
@ -380,7 +383,10 @@ mod test {
|
|||
point(0., 3.0)
|
||||
);
|
||||
assert_eq!(
|
||||
editor.selections.newest(cx).range(),
|
||||
editor
|
||||
.selections
|
||||
.newest(&editor.display_snapshot(cx))
|
||||
.range(),
|
||||
Point::new(0, 0)..Point::new(6, 1)
|
||||
)
|
||||
});
|
||||
|
|
|
|||
|
|
@ -94,7 +94,10 @@ impl Vim {
|
|||
MotionKind::Exclusive
|
||||
};
|
||||
vim.copy_selections_content(editor, kind, window, cx);
|
||||
let selections = editor.selections.all::<Point>(cx).into_iter();
|
||||
let selections = editor
|
||||
.selections
|
||||
.all::<Point>(&editor.display_snapshot(cx))
|
||||
.into_iter();
|
||||
let edits = selections.map(|selection| (selection.start..selection.end, ""));
|
||||
editor.edit(edits, cx);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ impl Vim {
|
|||
true,
|
||||
editor
|
||||
.selections
|
||||
.all_adjusted(cx)
|
||||
.all_adjusted(&editor.display_snapshot(cx))
|
||||
.iter()
|
||||
.map(|s| s.range())
|
||||
.collect(),
|
||||
|
|
@ -128,7 +128,7 @@ impl Vim {
|
|||
false,
|
||||
editor
|
||||
.selections
|
||||
.all_adjusted(cx)
|
||||
.all_adjusted(&editor.display_snapshot(cx))
|
||||
.iter()
|
||||
.map(|s| s.range())
|
||||
.collect(),
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ impl Vim {
|
|||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let map = editor.snapshot(window, cx);
|
||||
let display_selections = editor.selections.all::<Point>(cx);
|
||||
let display_selections = editor.selections.all::<Point>(&map.display_snapshot);
|
||||
|
||||
// Handles all string that require manipulation, including inserts and replaces
|
||||
let edits = display_selections
|
||||
|
|
@ -98,7 +98,7 @@ impl Vim {
|
|||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let map = editor.snapshot(window, cx);
|
||||
let selections = editor.selections.all::<Point>(cx);
|
||||
let selections = editor.selections.all::<Point>(&map.display_snapshot);
|
||||
let mut new_selections = vec![];
|
||||
let edits: Vec<(Range<Point>, String)> = selections
|
||||
.into_iter()
|
||||
|
|
@ -150,7 +150,9 @@ impl Vim {
|
|||
self.stop_recording(cx);
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let mut selection = editor.selections.newest_display(cx);
|
||||
let mut selection = editor
|
||||
.selections
|
||||
.newest_display(&editor.display_snapshot(cx));
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
object.expand_selection(&snapshot, &mut selection, around, None);
|
||||
let start = snapshot
|
||||
|
|
@ -196,7 +198,9 @@ impl Vim {
|
|||
self.update_editor(cx, |vim, editor, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
let mut selection = editor.selections.newest_display(cx);
|
||||
let mut selection = editor
|
||||
.selections
|
||||
.newest_display(&editor.display_snapshot(cx));
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
motion.expand_selection(
|
||||
&snapshot,
|
||||
|
|
|
|||
|
|
@ -863,7 +863,9 @@ impl VimGlobals {
|
|||
}
|
||||
}
|
||||
'%' => editor.and_then(|editor| {
|
||||
let selection = editor.selections.newest::<Point>(cx);
|
||||
let selection = editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx));
|
||||
if let Some((_, buffer, _)) = editor
|
||||
.buffer()
|
||||
.read(cx)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ impl Vim {
|
|||
},
|
||||
};
|
||||
let surround = pair.end != surround_alias((*text).as_ref());
|
||||
let (display_map, display_selections) = editor.selections.all_adjusted_display(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let display_selections = editor.selections.all_adjusted_display(&display_map);
|
||||
let mut edits = Vec::new();
|
||||
let mut anchors = Vec::new();
|
||||
|
||||
|
|
@ -144,7 +145,8 @@ impl Vim {
|
|||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
|
||||
let (display_map, display_selections) = editor.selections.all_display(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let display_selections = editor.selections.all_display(&display_map);
|
||||
let mut edits = Vec::new();
|
||||
let mut anchors = Vec::new();
|
||||
|
||||
|
|
@ -256,7 +258,8 @@ impl Vim {
|
|||
let preserve_space =
|
||||
will_replace_pair.start == will_replace_pair.end || !opening;
|
||||
|
||||
let (display_map, selections) = editor.selections.all_adjusted_display(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let selections = editor.selections.all_adjusted_display(&display_map);
|
||||
let mut edits = Vec::new();
|
||||
let mut anchors = Vec::new();
|
||||
|
||||
|
|
@ -382,7 +385,8 @@ impl Vim {
|
|||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let (display_map, selections) = editor.selections.all_adjusted_display(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let selections = editor.selections.all_adjusted_display(&display_map);
|
||||
let mut anchors = Vec::new();
|
||||
|
||||
for selection in &selections {
|
||||
|
|
@ -500,7 +504,8 @@ impl Vim {
|
|||
let mut min_range_size = usize::MAX;
|
||||
|
||||
let _ = self.editor.update(cx, |editor, cx| {
|
||||
let (display_map, selections) = editor.selections.all_adjusted_display(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let selections = editor.selections.all_adjusted_display(&display_map);
|
||||
// Even if there's multiple cursors, we'll simply rely on
|
||||
// the first one to understand what bracket pair to map to.
|
||||
// I believe we could, if worth it, go one step above and
|
||||
|
|
|
|||
|
|
@ -2295,7 +2295,10 @@ async fn test_clipping_on_mode_change(cx: &mut gpui::TestAppContext) {
|
|||
|
||||
let mut pixel_position = cx.update_editor(|editor, window, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let current_head = editor.selections.newest_display(cx).end;
|
||||
let current_head = editor
|
||||
.selections
|
||||
.newest_display(&snapshot.display_snapshot)
|
||||
.end;
|
||||
editor.last_bounds().unwrap().origin
|
||||
+ editor
|
||||
.display_to_pixel_point(current_head, &snapshot, window)
|
||||
|
|
|
|||
|
|
@ -1359,7 +1359,10 @@ impl Vim {
|
|||
return;
|
||||
};
|
||||
let newest_selection_empty = editor.update(cx, |editor, cx| {
|
||||
editor.selections.newest::<usize>(cx).is_empty()
|
||||
editor
|
||||
.selections
|
||||
.newest::<usize>(&editor.display_snapshot(cx))
|
||||
.is_empty()
|
||||
});
|
||||
let editor = editor.read(cx);
|
||||
let editor_mode = editor.mode();
|
||||
|
|
@ -1455,9 +1458,11 @@ impl Vim {
|
|||
cx: &mut Context<Self>,
|
||||
) -> Option<String> {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let selection = editor.selections.newest::<usize>(cx);
|
||||
let snapshot = &editor.snapshot(window, cx);
|
||||
let selection = editor
|
||||
.selections
|
||||
.newest::<usize>(&snapshot.display_snapshot);
|
||||
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let snapshot = snapshot.buffer_snapshot();
|
||||
let (range, kind) =
|
||||
snapshot.surrounding_word(selection.start, Some(CharScopeContext::Completion));
|
||||
|
|
@ -1484,9 +1489,11 @@ impl Vim {
|
|||
|
||||
let selections = self.editor().map(|editor| {
|
||||
editor.update(cx, |editor, cx| {
|
||||
let snapshot = editor.display_snapshot(cx);
|
||||
|
||||
(
|
||||
editor.selections.oldest::<Point>(cx),
|
||||
editor.selections.newest::<Point>(cx),
|
||||
editor.selections.oldest::<Point>(&snapshot),
|
||||
editor.selections.newest::<Point>(&snapshot),
|
||||
)
|
||||
})
|
||||
});
|
||||
|
|
|
|||
|
|
@ -747,7 +747,8 @@ impl Vim {
|
|||
self.stop_recording(cx);
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
let (display_map, selections) = editor.selections.all_adjusted_display(cx);
|
||||
let display_map = editor.display_snapshot(cx);
|
||||
let selections = editor.selections.all_adjusted_display(&display_map);
|
||||
|
||||
// Selections are biased right at the start. So we need to store
|
||||
// anchors that are biased left so that we can restore the selections
|
||||
|
|
@ -858,7 +859,9 @@ impl Vim {
|
|||
});
|
||||
}
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let latest = editor.selections.newest::<usize>(cx);
|
||||
let latest = editor
|
||||
.selections
|
||||
.newest::<usize>(&editor.display_snapshot(cx));
|
||||
start_selection = latest.start;
|
||||
end_selection = latest.end;
|
||||
});
|
||||
|
|
@ -879,7 +882,9 @@ impl Vim {
|
|||
return;
|
||||
}
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
let latest = editor.selections.newest::<usize>(cx);
|
||||
let latest = editor
|
||||
.selections
|
||||
.newest::<usize>(&editor.display_snapshot(cx));
|
||||
if vim_is_normal {
|
||||
start_selection = latest.start;
|
||||
end_selection = latest.end;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ impl QuickActionBar {
|
|||
.count()
|
||||
.ne(&0)
|
||||
.then(|| {
|
||||
let latest = this.selections.newest_display(cx);
|
||||
let snapshot = this.display_snapshot(cx);
|
||||
let latest = this.selections.newest_display(&snapshot);
|
||||
!latest.is_empty()
|
||||
})
|
||||
.unwrap_or_default()
|
||||
|
|
|
|||
Loading…
Reference in a new issue