More messy progress towards selections in editors
This commit is contained in:
parent
0639c8331c
commit
4dd0752e80
11 changed files with 298 additions and 479 deletions
|
@ -23,7 +23,7 @@ use gpui::{
|
||||||
use items::BufferItemHandle;
|
use items::BufferItemHandle;
|
||||||
use language::{
|
use language::{
|
||||||
BracketPair, Buffer, Diagnostic, DiagnosticSeverity, Language, Point, Selection, SelectionGoal,
|
BracketPair, Buffer, Diagnostic, DiagnosticSeverity, Language, Point, Selection, SelectionGoal,
|
||||||
SelectionSetId, TransactionId,
|
TransactionId,
|
||||||
};
|
};
|
||||||
pub use multi_buffer::MultiBuffer;
|
pub use multi_buffer::MultiBuffer;
|
||||||
use multi_buffer::{
|
use multi_buffer::{
|
||||||
|
@ -638,11 +638,11 @@ impl Editor {
|
||||||
let first_cursor_top;
|
let first_cursor_top;
|
||||||
let last_cursor_bottom;
|
let last_cursor_bottom;
|
||||||
if autoscroll == Autoscroll::Newest {
|
if autoscroll == Autoscroll::Newest {
|
||||||
let newest_selection = self.newest_selection::<Point>(&display_map.buffer_snapshot, cx);
|
let newest_selection = self.newest_selection::<Point>(&display_map.buffer_snapshot);
|
||||||
first_cursor_top = newest_selection.head().to_display_point(&display_map).row() as f32;
|
first_cursor_top = newest_selection.head().to_display_point(&display_map).row() as f32;
|
||||||
last_cursor_bottom = first_cursor_top + 1.;
|
last_cursor_bottom = first_cursor_top + 1.;
|
||||||
} else {
|
} else {
|
||||||
let selections = self.selections::<Point>(cx);
|
let selections = self.local_selections::<Point>(cx);
|
||||||
first_cursor_top = selections
|
first_cursor_top = selections
|
||||||
.first()
|
.first()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -702,7 +702,7 @@ impl Editor {
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let selections = self.selections::<Point>(cx);
|
let selections = self.local_selections::<Point>(cx);
|
||||||
let mut target_left = std::f32::INFINITY;
|
let mut target_left = std::f32::INFINITY;
|
||||||
let mut target_right = 0.0_f32;
|
let mut target_right = 0.0_f32;
|
||||||
for selection in selections {
|
for selection in selections {
|
||||||
|
@ -772,7 +772,7 @@ impl Editor {
|
||||||
) {
|
) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let tail = self
|
let tail = self
|
||||||
.newest_selection::<usize>(&display_map.buffer_snapshot, cx)
|
.newest_selection::<usize>(&display_map.buffer_snapshot)
|
||||||
.tail();
|
.tail();
|
||||||
self.begin_selection(position, false, click_count, cx);
|
self.begin_selection(position, false, click_count, cx);
|
||||||
|
|
||||||
|
@ -855,8 +855,8 @@ impl Editor {
|
||||||
self.update_selections::<usize>(Vec::new(), None, cx);
|
self.update_selections::<usize>(Vec::new(), None, cx);
|
||||||
} else if click_count > 1 {
|
} else if click_count > 1 {
|
||||||
// Remove the newest selection since it was only added as part of this multi-click.
|
// Remove the newest selection since it was only added as part of this multi-click.
|
||||||
let newest_selection = self.newest_selection::<usize>(buffer, cx);
|
let newest_selection = self.newest_selection::<usize>(buffer);
|
||||||
let mut selections = self.selections(cx);
|
let mut selections = self.local_selections(cx);
|
||||||
selections.retain(|selection| selection.id != newest_selection.id);
|
selections.retain(|selection| selection.id != newest_selection.id);
|
||||||
self.update_selections::<usize>(selections, None, cx)
|
self.update_selections::<usize>(selections, None, cx)
|
||||||
}
|
}
|
||||||
|
@ -879,7 +879,7 @@ impl Editor {
|
||||||
|
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let tail = self
|
let tail = self
|
||||||
.newest_selection::<Point>(&display_map.buffer_snapshot, cx)
|
.newest_selection::<Point>(&display_map.buffer_snapshot)
|
||||||
.tail();
|
.tail();
|
||||||
self.columnar_selection_tail = Some(display_map.buffer_snapshot.anchor_before(tail));
|
self.columnar_selection_tail = Some(display_map.buffer_snapshot.anchor_before(tail));
|
||||||
|
|
||||||
|
@ -986,7 +986,7 @@ impl Editor {
|
||||||
fn end_selection(&mut self, cx: &mut ViewContext<Self>) {
|
fn end_selection(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
self.columnar_selection_tail.take();
|
self.columnar_selection_tail.take();
|
||||||
if self.pending_selection.is_some() {
|
if self.pending_selection.is_some() {
|
||||||
let selections = self.selections::<usize>(cx);
|
let selections = self.local_selections::<usize>(cx);
|
||||||
self.update_selections(selections, None, cx);
|
self.update_selections(selections, None, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1047,13 +1047,13 @@ impl Editor {
|
||||||
reversed: selection.reversed,
|
reversed: selection.reversed,
|
||||||
goal: selection.goal,
|
goal: selection.goal,
|
||||||
};
|
};
|
||||||
if self.selections::<Point>(cx).is_empty() {
|
if self.local_selections::<Point>(cx).is_empty() {
|
||||||
self.update_selections(vec![selection], Some(Autoscroll::Fit), cx);
|
self.update_selections(vec![selection], Some(Autoscroll::Fit), cx);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||||
let mut oldest_selection = self.oldest_selection::<usize>(&buffer, cx);
|
let mut oldest_selection = self.oldest_selection::<usize>(&buffer);
|
||||||
if self.selection_count(cx) == 1 {
|
if self.selection_count() == 1 {
|
||||||
oldest_selection.start = oldest_selection.head().clone();
|
oldest_selection.start = oldest_selection.head().clone();
|
||||||
oldest_selection.end = oldest_selection.head().clone();
|
oldest_selection.end = oldest_selection.head().clone();
|
||||||
}
|
}
|
||||||
|
@ -1142,7 +1142,7 @@ impl Editor {
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
let mut old_selections = SmallVec::<[_; 32]>::new();
|
let mut old_selections = SmallVec::<[_; 32]>::new();
|
||||||
{
|
{
|
||||||
let selections = self.selections::<Point>(cx);
|
let selections = self.local_selections::<Point>(cx);
|
||||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||||
for selection in selections.iter() {
|
for selection in selections.iter() {
|
||||||
let start_point = selection.start;
|
let start_point = selection.start;
|
||||||
|
@ -1264,7 +1264,7 @@ impl Editor {
|
||||||
|
|
||||||
fn insert(&mut self, text: &str, cx: &mut ViewContext<Self>) {
|
fn insert(&mut self, text: &str, cx: &mut ViewContext<Self>) {
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
let old_selections = self.selections::<usize>(cx);
|
let old_selections = self.local_selections::<usize>(cx);
|
||||||
let mut new_selections = Vec::new();
|
let mut new_selections = Vec::new();
|
||||||
self.buffer.update(cx, |buffer, cx| {
|
self.buffer.update(cx, |buffer, cx| {
|
||||||
let edit_ranges = old_selections.iter().map(|s| s.start..s.end);
|
let edit_ranges = old_selections.iter().map(|s| s.start..s.end);
|
||||||
|
@ -1295,7 +1295,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn autoclose_pairs(&mut self, cx: &mut ViewContext<Self>) {
|
fn autoclose_pairs(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
let selections = self.selections::<usize>(cx);
|
let selections = self.local_selections::<usize>(cx);
|
||||||
let new_autoclose_pair = self.buffer.update(cx, |buffer, cx| {
|
let new_autoclose_pair = self.buffer.update(cx, |buffer, cx| {
|
||||||
let snapshot = buffer.snapshot(cx);
|
let snapshot = buffer.snapshot(cx);
|
||||||
let autoclose_pair = snapshot.language().and_then(|language| {
|
let autoclose_pair = snapshot.language().and_then(|language| {
|
||||||
|
@ -1356,7 +1356,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn skip_autoclose_end(&mut self, text: &str, cx: &mut ViewContext<Self>) -> bool {
|
fn skip_autoclose_end(&mut self, text: &str, cx: &mut ViewContext<Self>) -> bool {
|
||||||
let old_selections = self.selections::<usize>(cx);
|
let old_selections = self.local_selections::<usize>(cx);
|
||||||
let autoclose_pair = if let Some(autoclose_pair) = self.autoclose_stack.last() {
|
let autoclose_pair = if let Some(autoclose_pair) = self.autoclose_stack.last() {
|
||||||
autoclose_pair
|
autoclose_pair
|
||||||
} else {
|
} else {
|
||||||
|
@ -1407,7 +1407,7 @@ impl Editor {
|
||||||
|
|
||||||
pub fn backspace(&mut self, _: &Backspace, cx: &mut ViewContext<Self>) {
|
pub fn backspace(&mut self, _: &Backspace, cx: &mut ViewContext<Self>) {
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
if selection.is_empty() {
|
if selection.is_empty() {
|
||||||
|
@ -1427,7 +1427,7 @@ impl Editor {
|
||||||
pub fn delete(&mut self, _: &Delete, cx: &mut ViewContext<Self>) {
|
pub fn delete(&mut self, _: &Delete, cx: &mut ViewContext<Self>) {
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
if selection.is_empty() {
|
if selection.is_empty() {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(&display_map);
|
||||||
|
@ -1446,7 +1446,7 @@ impl Editor {
|
||||||
pub fn tab(&mut self, _: &Tab, cx: &mut ViewContext<Self>) {
|
pub fn tab(&mut self, _: &Tab, cx: &mut ViewContext<Self>) {
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
let tab_size = self.build_settings.borrow()(cx).tab_size;
|
let tab_size = self.build_settings.borrow()(cx).tab_size;
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
let mut last_indent = None;
|
let mut last_indent = None;
|
||||||
self.buffer.update(cx, |buffer, cx| {
|
self.buffer.update(cx, |buffer, cx| {
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
|
@ -1518,7 +1518,7 @@ impl Editor {
|
||||||
pub fn outdent(&mut self, _: &Outdent, cx: &mut ViewContext<Self>) {
|
pub fn outdent(&mut self, _: &Outdent, cx: &mut ViewContext<Self>) {
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
let tab_size = self.build_settings.borrow()(cx).tab_size;
|
let tab_size = self.build_settings.borrow()(cx).tab_size;
|
||||||
let selections = self.selections::<Point>(cx);
|
let selections = self.local_selections::<Point>(cx);
|
||||||
let mut deletion_ranges = Vec::new();
|
let mut deletion_ranges = Vec::new();
|
||||||
let mut last_outdent = None;
|
let mut last_outdent = None;
|
||||||
{
|
{
|
||||||
|
@ -1558,14 +1558,18 @@ impl Editor {
|
||||||
buffer.edit(deletion_ranges, "", cx);
|
buffer.edit(deletion_ranges, "", cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
self.update_selections(self.selections::<usize>(cx), Some(Autoscroll::Fit), cx);
|
self.update_selections(
|
||||||
|
self.local_selections::<usize>(cx),
|
||||||
|
Some(Autoscroll::Fit),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
self.end_transaction(cx);
|
self.end_transaction(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_line(&mut self, _: &DeleteLine, cx: &mut ViewContext<Self>) {
|
pub fn delete_line(&mut self, _: &DeleteLine, cx: &mut ViewContext<Self>) {
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
|
|
||||||
let selections = self.selections::<Point>(cx);
|
let selections = self.local_selections::<Point>(cx);
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||||
|
|
||||||
|
@ -1634,7 +1638,7 @@ impl Editor {
|
||||||
pub fn duplicate_line(&mut self, _: &DuplicateLine, cx: &mut ViewContext<Self>) {
|
pub fn duplicate_line(&mut self, _: &DuplicateLine, cx: &mut ViewContext<Self>) {
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
|
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let buffer = &display_map.buffer_snapshot;
|
let buffer = &display_map.buffer_snapshot;
|
||||||
|
|
||||||
|
@ -1692,7 +1696,7 @@ impl Editor {
|
||||||
pub fn move_line_up(&mut self, _: &MoveLineUp, cx: &mut ViewContext<Self>) {
|
pub fn move_line_up(&mut self, _: &MoveLineUp, cx: &mut ViewContext<Self>) {
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
|
|
||||||
let selections = self.selections::<Point>(cx);
|
let selections = self.local_selections::<Point>(cx);
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||||
|
|
||||||
|
@ -1782,7 +1786,7 @@ impl Editor {
|
||||||
pub fn move_line_down(&mut self, _: &MoveLineDown, cx: &mut ViewContext<Self>) {
|
pub fn move_line_down(&mut self, _: &MoveLineDown, cx: &mut ViewContext<Self>) {
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
|
|
||||||
let selections = self.selections::<Point>(cx);
|
let selections = self.local_selections::<Point>(cx);
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||||
|
|
||||||
|
@ -1869,7 +1873,7 @@ impl Editor {
|
||||||
pub fn cut(&mut self, _: &Cut, cx: &mut ViewContext<Self>) {
|
pub fn cut(&mut self, _: &Cut, cx: &mut ViewContext<Self>) {
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
let mut text = String::new();
|
let mut text = String::new();
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
let mut clipboard_selections = Vec::with_capacity(selections.len());
|
let mut clipboard_selections = Vec::with_capacity(selections.len());
|
||||||
{
|
{
|
||||||
let buffer = self.buffer.read(cx).read(cx);
|
let buffer = self.buffer.read(cx).read(cx);
|
||||||
|
@ -1900,7 +1904,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy(&mut self, _: &Copy, cx: &mut ViewContext<Self>) {
|
pub fn copy(&mut self, _: &Copy, cx: &mut ViewContext<Self>) {
|
||||||
let selections = self.selections::<Point>(cx);
|
let selections = self.local_selections::<Point>(cx);
|
||||||
let mut text = String::new();
|
let mut text = String::new();
|
||||||
let mut clipboard_selections = Vec::with_capacity(selections.len());
|
let mut clipboard_selections = Vec::with_capacity(selections.len());
|
||||||
{
|
{
|
||||||
|
@ -1934,7 +1938,7 @@ impl Editor {
|
||||||
if let Some(item) = cx.as_mut().read_from_clipboard() {
|
if let Some(item) = cx.as_mut().read_from_clipboard() {
|
||||||
let clipboard_text = item.text();
|
let clipboard_text = item.text();
|
||||||
if let Some(mut clipboard_selections) = item.metadata::<Vec<ClipboardSelection>>() {
|
if let Some(mut clipboard_selections) = item.metadata::<Vec<ClipboardSelection>>() {
|
||||||
let mut selections = self.selections::<usize>(cx);
|
let mut selections = self.local_selections::<usize>(cx);
|
||||||
let all_selections_were_entire_line =
|
let all_selections_were_entire_line =
|
||||||
clipboard_selections.iter().all(|s| s.is_entire_line);
|
clipboard_selections.iter().all(|s| s.is_entire_line);
|
||||||
if clipboard_selections.len() != selections.len() {
|
if clipboard_selections.len() != selections.len() {
|
||||||
|
@ -1997,7 +2001,7 @@ impl Editor {
|
||||||
|
|
||||||
pub fn move_left(&mut self, _: &MoveLeft, cx: &mut ViewContext<Self>) {
|
pub fn move_left(&mut self, _: &MoveLeft, cx: &mut ViewContext<Self>) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let start = selection.start.to_display_point(&display_map);
|
let start = selection.start.to_display_point(&display_map);
|
||||||
let end = selection.end.to_display_point(&display_map);
|
let end = selection.end.to_display_point(&display_map);
|
||||||
|
@ -2019,7 +2023,7 @@ impl Editor {
|
||||||
|
|
||||||
pub fn select_left(&mut self, _: &SelectLeft, cx: &mut ViewContext<Self>) {
|
pub fn select_left(&mut self, _: &SelectLeft, cx: &mut ViewContext<Self>) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(&display_map);
|
||||||
let cursor = movement::left(&display_map, head)
|
let cursor = movement::left(&display_map, head)
|
||||||
|
@ -2033,7 +2037,7 @@ impl Editor {
|
||||||
|
|
||||||
pub fn move_right(&mut self, _: &MoveRight, cx: &mut ViewContext<Self>) {
|
pub fn move_right(&mut self, _: &MoveRight, cx: &mut ViewContext<Self>) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let start = selection.start.to_display_point(&display_map);
|
let start = selection.start.to_display_point(&display_map);
|
||||||
let end = selection.end.to_display_point(&display_map);
|
let end = selection.end.to_display_point(&display_map);
|
||||||
|
@ -2055,7 +2059,7 @@ impl Editor {
|
||||||
|
|
||||||
pub fn select_right(&mut self, _: &SelectRight, cx: &mut ViewContext<Self>) {
|
pub fn select_right(&mut self, _: &SelectRight, cx: &mut ViewContext<Self>) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(&display_map);
|
||||||
let cursor = movement::right(&display_map, head)
|
let cursor = movement::right(&display_map, head)
|
||||||
|
@ -2074,7 +2078,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let start = selection.start.to_display_point(&display_map);
|
let start = selection.start.to_display_point(&display_map);
|
||||||
let end = selection.end.to_display_point(&display_map);
|
let end = selection.end.to_display_point(&display_map);
|
||||||
|
@ -2094,7 +2098,7 @@ impl Editor {
|
||||||
|
|
||||||
pub fn select_up(&mut self, _: &SelectUp, cx: &mut ViewContext<Self>) {
|
pub fn select_up(&mut self, _: &SelectUp, cx: &mut ViewContext<Self>) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(&display_map);
|
||||||
let (head, goal) = movement::up(&display_map, head, selection.goal).unwrap();
|
let (head, goal) = movement::up(&display_map, head, selection.goal).unwrap();
|
||||||
|
@ -2112,7 +2116,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let start = selection.start.to_display_point(&display_map);
|
let start = selection.start.to_display_point(&display_map);
|
||||||
let end = selection.end.to_display_point(&display_map);
|
let end = selection.end.to_display_point(&display_map);
|
||||||
|
@ -2132,7 +2136,7 @@ impl Editor {
|
||||||
|
|
||||||
pub fn select_down(&mut self, _: &SelectDown, cx: &mut ViewContext<Self>) {
|
pub fn select_down(&mut self, _: &SelectDown, cx: &mut ViewContext<Self>) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(&display_map);
|
||||||
let (head, goal) = movement::down(&display_map, head, selection.goal).unwrap();
|
let (head, goal) = movement::down(&display_map, head, selection.goal).unwrap();
|
||||||
|
@ -2149,7 +2153,7 @@ impl Editor {
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(&display_map);
|
||||||
let cursor = movement::prev_word_boundary(&display_map, head).to_point(&display_map);
|
let cursor = movement::prev_word_boundary(&display_map, head).to_point(&display_map);
|
||||||
|
@ -2167,7 +2171,7 @@ impl Editor {
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(&display_map);
|
||||||
let cursor = movement::prev_word_boundary(&display_map, head).to_point(&display_map);
|
let cursor = movement::prev_word_boundary(&display_map, head).to_point(&display_map);
|
||||||
|
@ -2184,7 +2188,7 @@ impl Editor {
|
||||||
) {
|
) {
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
if selection.is_empty() {
|
if selection.is_empty() {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(&display_map);
|
||||||
|
@ -2205,7 +2209,7 @@ impl Editor {
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(&display_map);
|
||||||
let cursor = movement::next_word_boundary(&display_map, head).to_point(&display_map);
|
let cursor = movement::next_word_boundary(&display_map, head).to_point(&display_map);
|
||||||
|
@ -2223,7 +2227,7 @@ impl Editor {
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(&display_map);
|
||||||
let cursor = movement::next_word_boundary(&display_map, head).to_point(&display_map);
|
let cursor = movement::next_word_boundary(&display_map, head).to_point(&display_map);
|
||||||
|
@ -2240,7 +2244,7 @@ impl Editor {
|
||||||
) {
|
) {
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
if selection.is_empty() {
|
if selection.is_empty() {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(&display_map);
|
||||||
|
@ -2261,7 +2265,7 @@ impl Editor {
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(&display_map);
|
||||||
let new_head = movement::line_beginning(&display_map, head, true);
|
let new_head = movement::line_beginning(&display_map, head, true);
|
||||||
|
@ -2280,7 +2284,7 @@ impl Editor {
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(&display_map);
|
||||||
let new_head = movement::line_beginning(&display_map, head, *toggle_indent);
|
let new_head = movement::line_beginning(&display_map, head, *toggle_indent);
|
||||||
|
@ -2303,7 +2307,7 @@ impl Editor {
|
||||||
|
|
||||||
pub fn move_to_end_of_line(&mut self, _: &MoveToEndOfLine, cx: &mut ViewContext<Self>) {
|
pub fn move_to_end_of_line(&mut self, _: &MoveToEndOfLine, cx: &mut ViewContext<Self>) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
{
|
{
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(&display_map);
|
||||||
|
@ -2320,7 +2324,7 @@ impl Editor {
|
||||||
|
|
||||||
pub fn select_to_end_of_line(&mut self, _: &SelectToEndOfLine, cx: &mut ViewContext<Self>) {
|
pub fn select_to_end_of_line(&mut self, _: &SelectToEndOfLine, cx: &mut ViewContext<Self>) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(&display_map);
|
||||||
let new_head = movement::line_end(&display_map, head);
|
let new_head = movement::line_end(&display_map, head);
|
||||||
|
@ -2356,7 +2360,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_to_beginning(&mut self, _: &SelectToBeginning, cx: &mut ViewContext<Self>) {
|
pub fn select_to_beginning(&mut self, _: &SelectToBeginning, cx: &mut ViewContext<Self>) {
|
||||||
let mut selection = self.selections::<Point>(cx).last().unwrap().clone();
|
let mut selection = self.local_selections::<Point>(cx).last().unwrap().clone();
|
||||||
selection.set_head(Point::zero());
|
selection.set_head(Point::zero());
|
||||||
self.update_selections(vec![selection], Some(Autoscroll::Fit), cx);
|
self.update_selections(vec![selection], Some(Autoscroll::Fit), cx);
|
||||||
}
|
}
|
||||||
|
@ -2374,7 +2378,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_to_end(&mut self, _: &SelectToEnd, cx: &mut ViewContext<Self>) {
|
pub fn select_to_end(&mut self, _: &SelectToEnd, cx: &mut ViewContext<Self>) {
|
||||||
let mut selection = self.selections::<usize>(cx).first().unwrap().clone();
|
let mut selection = self.local_selections::<usize>(cx).first().unwrap().clone();
|
||||||
selection.set_head(self.buffer.read(cx).read(cx).len());
|
selection.set_head(self.buffer.read(cx).read(cx).len());
|
||||||
self.update_selections(vec![selection], Some(Autoscroll::Fit), cx);
|
self.update_selections(vec![selection], Some(Autoscroll::Fit), cx);
|
||||||
}
|
}
|
||||||
|
@ -2392,7 +2396,7 @@ impl Editor {
|
||||||
|
|
||||||
pub fn select_line(&mut self, _: &SelectLine, cx: &mut ViewContext<Self>) {
|
pub fn select_line(&mut self, _: &SelectLine, cx: &mut ViewContext<Self>) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
let max_point = display_map.buffer_snapshot.max_point();
|
let max_point = display_map.buffer_snapshot.max_point();
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
let rows = selection.spanned_rows(true, &display_map).buffer_rows;
|
let rows = selection.spanned_rows(true, &display_map).buffer_rows;
|
||||||
|
@ -2411,7 +2415,7 @@ impl Editor {
|
||||||
let mut to_unfold = Vec::new();
|
let mut to_unfold = Vec::new();
|
||||||
let mut new_selections = Vec::new();
|
let mut new_selections = Vec::new();
|
||||||
{
|
{
|
||||||
let selections = self.selections::<Point>(cx);
|
let selections = self.local_selections::<Point>(cx);
|
||||||
let buffer = self.buffer.read(cx).read(cx);
|
let buffer = self.buffer.read(cx).read(cx);
|
||||||
for selection in selections {
|
for selection in selections {
|
||||||
for row in selection.start.row..selection.end.row {
|
for row in selection.start.row..selection.end.row {
|
||||||
|
@ -2448,7 +2452,7 @@ impl Editor {
|
||||||
|
|
||||||
fn add_selection(&mut self, above: bool, cx: &mut ViewContext<Self>) {
|
fn add_selection(&mut self, above: bool, cx: &mut ViewContext<Self>) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
let mut state = self.add_selections_state.take().unwrap_or_else(|| {
|
let mut state = self.add_selections_state.take().unwrap_or_else(|| {
|
||||||
let oldest_selection = selections.iter().min_by_key(|s| s.id).unwrap().clone();
|
let oldest_selection = selections.iter().min_by_key(|s| s.id).unwrap().clone();
|
||||||
let range = oldest_selection.display_range(&display_map).sorted();
|
let range = oldest_selection.display_range(&display_map).sorted();
|
||||||
|
@ -2543,7 +2547,7 @@ impl Editor {
|
||||||
let replace_newest = action.0;
|
let replace_newest = action.0;
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let buffer = &display_map.buffer_snapshot;
|
let buffer = &display_map.buffer_snapshot;
|
||||||
let mut selections = self.selections::<usize>(cx);
|
let mut selections = self.local_selections::<usize>(cx);
|
||||||
if let Some(mut select_next_state) = self.select_next_state.take() {
|
if let Some(mut select_next_state) = self.select_next_state.take() {
|
||||||
let query = &select_next_state.query;
|
let query = &select_next_state.query;
|
||||||
if !select_next_state.done {
|
if !select_next_state.done {
|
||||||
|
@ -2650,7 +2654,7 @@ impl Editor {
|
||||||
let comment_prefix_whitespace = &full_comment_prefix[comment_prefix.len()..];
|
let comment_prefix_whitespace = &full_comment_prefix[comment_prefix.len()..];
|
||||||
|
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
let mut selections = self.selections::<Point>(cx);
|
let mut selections = self.local_selections::<Point>(cx);
|
||||||
let mut all_selection_lines_are_comments = true;
|
let mut all_selection_lines_are_comments = true;
|
||||||
let mut edit_ranges = Vec::new();
|
let mut edit_ranges = Vec::new();
|
||||||
let mut last_toggled_row = None;
|
let mut last_toggled_row = None;
|
||||||
|
@ -2727,7 +2731,11 @@ impl Editor {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
self.update_selections(self.selections::<usize>(cx), Some(Autoscroll::Fit), cx);
|
self.update_selections(
|
||||||
|
self.local_selections::<usize>(cx),
|
||||||
|
Some(Autoscroll::Fit),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
self.end_transaction(cx);
|
self.end_transaction(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2736,7 +2744,7 @@ impl Editor {
|
||||||
_: &SelectLargerSyntaxNode,
|
_: &SelectLargerSyntaxNode,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
let old_selections = self.selections::<usize>(cx).into_boxed_slice();
|
let old_selections = self.local_selections::<usize>(cx).into_boxed_slice();
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||||
|
|
||||||
|
@ -2794,7 +2802,7 @@ impl Editor {
|
||||||
_: &MoveToEnclosingBracket,
|
_: &MoveToEnclosingBracket,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
let mut selections = self.selections::<usize>(cx);
|
let mut selections = self.local_selections::<usize>(cx);
|
||||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||||
for selection in &mut selections {
|
for selection in &mut selections {
|
||||||
if let Some((open_range, close_range)) =
|
if let Some((open_range, close_range)) =
|
||||||
|
@ -2818,7 +2826,7 @@ impl Editor {
|
||||||
|
|
||||||
pub fn show_next_diagnostic(&mut self, _: &ShowNextDiagnostic, cx: &mut ViewContext<Self>) {
|
pub fn show_next_diagnostic(&mut self, _: &ShowNextDiagnostic, cx: &mut ViewContext<Self>) {
|
||||||
let buffer = self.buffer.read(cx).snapshot(cx);
|
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||||
let selection = self.newest_selection::<usize>(&buffer, cx);
|
let selection = self.newest_selection::<usize>(&buffer);
|
||||||
let active_primary_range = self.active_diagnostics.as_ref().map(|active_diagnostics| {
|
let active_primary_range = self.active_diagnostics.as_ref().map(|active_diagnostics| {
|
||||||
active_diagnostics
|
active_diagnostics
|
||||||
.primary_range
|
.primary_range
|
||||||
|
@ -2998,54 +3006,65 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intersecting_selections<'a>(
|
pub fn all_selections_in_range<'a, D>(
|
||||||
&'a self,
|
&'a self,
|
||||||
set_id: SelectionSetId,
|
|
||||||
range: Range<DisplayPoint>,
|
range: Range<DisplayPoint>,
|
||||||
cx: &'a mut MutableAppContext,
|
cx: &'a mut MutableAppContext,
|
||||||
) -> Vec<Selection<DisplayPoint>> {
|
) -> HashMap<ReplicaId, Vec<Selection<D>>>
|
||||||
todo!()
|
where
|
||||||
// let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
D: TextDimension + Ord + Sub<D, Output = D>,
|
||||||
// let buffer = self.buffer.read(cx);
|
{
|
||||||
|
let mut result = HashMap::new();
|
||||||
|
|
||||||
// let pending_selection = if set_id == self.selection_set_id {
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
// self.pending_selection.as_ref().and_then(|pending| {
|
let buffer = &display_map.buffer_snapshot;
|
||||||
// let selection_start = pending.selection.start.to_display_point(&display_map);
|
let range = range.start.to_offset(&display_map, Bias::Left)
|
||||||
// let selection_end = pending.selection.end.to_display_point(&display_map);
|
..range.end.to_offset(&display_map, Bias::Left);
|
||||||
// if selection_start <= range.end || selection_end <= range.end {
|
|
||||||
// Some(Selection {
|
|
||||||
// id: pending.selection.id,
|
|
||||||
// start: selection_start,
|
|
||||||
// end: selection_end,
|
|
||||||
// reversed: pending.selection.reversed,
|
|
||||||
// goal: pending.selection.goal,
|
|
||||||
// })
|
|
||||||
// } else {
|
|
||||||
// None
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// } else {
|
|
||||||
// None
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let range = (range.start.to_offset(&display_map, Bias::Left), Bias::Left)
|
let anchor_range = buffer.anchor_before(range.start)..buffer.anchor_after(range.end);
|
||||||
// ..(range.end.to_offset(&display_map, Bias::Left), Bias::Right);
|
let start_ix = match self
|
||||||
// buffer
|
.selections
|
||||||
// .selection_set(set_id, cx)
|
.binary_search_by(|probe| probe.end.cmp(&anchor_range.start, &buffer).unwrap())
|
||||||
// .unwrap()
|
{
|
||||||
// .intersecting_selections::<Point, _>(range, &buffer.read(cx))
|
Ok(ix) | Err(ix) => ix,
|
||||||
// .map(move |s| Selection {
|
};
|
||||||
// id: s.id,
|
let end_ix = match self
|
||||||
// start: s.start.to_display_point(&display_map),
|
.selections
|
||||||
// end: s.end.to_display_point(&display_map),
|
.binary_search_by(|probe| probe.start.cmp(&anchor_range.end, &buffer).unwrap())
|
||||||
// reversed: s.reversed,
|
{
|
||||||
// goal: s.goal,
|
Ok(ix) | Err(ix) => ix,
|
||||||
// })
|
};
|
||||||
// .chain(pending_selection)
|
|
||||||
// .collect()
|
let selections = &self.selections[start_ix..end_ix];
|
||||||
|
let mut summaries = buffer
|
||||||
|
.summaries_for_anchors::<D, _>(selections.iter().flat_map(|s| [&s.start, &s.end]))
|
||||||
|
.into_iter();
|
||||||
|
|
||||||
|
result.insert(
|
||||||
|
self.replica_id(cx),
|
||||||
|
selections
|
||||||
|
.iter()
|
||||||
|
.map(|s| Selection {
|
||||||
|
id: s.id,
|
||||||
|
start: summaries.next().unwrap(),
|
||||||
|
end: summaries.next().unwrap(),
|
||||||
|
reversed: s.reversed,
|
||||||
|
goal: s.goal,
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
);
|
||||||
|
|
||||||
|
for (replica_id, selections) in display_map
|
||||||
|
.buffer_snapshot
|
||||||
|
.remote_selections_in_range(range)
|
||||||
|
{
|
||||||
|
result.insert(replica_id, selections.collect());
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn selections<'a, D>(&self, cx: &'a AppContext) -> Vec<Selection<D>>
|
pub fn local_selections<'a, D>(&self, cx: &'a AppContext) -> Vec<Selection<D>>
|
||||||
where
|
where
|
||||||
D: 'a + TextDimension + Ord + Sub<D, Output = D>,
|
D: 'a + TextDimension + Ord + Sub<D, Output = D>,
|
||||||
{
|
{
|
||||||
|
@ -3067,7 +3086,7 @@ impl Editor {
|
||||||
})
|
})
|
||||||
.peekable();
|
.peekable();
|
||||||
|
|
||||||
let mut pending_selection = self.pending_selection::<D>(&buffer, cx);
|
let mut pending_selection = self.pending_selection::<D>(&buffer);
|
||||||
|
|
||||||
iter::from_fn(move || {
|
iter::from_fn(move || {
|
||||||
if let Some(pending) = pending_selection.as_mut() {
|
if let Some(pending) = pending_selection.as_mut() {
|
||||||
|
@ -3098,18 +3117,16 @@ impl Editor {
|
||||||
fn pending_selection<D: TextDimension + Ord + Sub<D, Output = D>>(
|
fn pending_selection<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||||
&self,
|
&self,
|
||||||
snapshot: &MultiBufferSnapshot,
|
snapshot: &MultiBufferSnapshot,
|
||||||
cx: &AppContext,
|
|
||||||
) -> Option<Selection<D>> {
|
) -> Option<Selection<D>> {
|
||||||
self.pending_selection
|
self.pending_selection
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|pending| self.resolve_selection(&pending.selection, &snapshot, cx))
|
.map(|pending| self.resolve_selection(&pending.selection, &snapshot))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_selection<D: TextDimension + Ord + Sub<D, Output = D>>(
|
fn resolve_selection<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||||
&self,
|
&self,
|
||||||
selection: &Selection<Anchor>,
|
selection: &Selection<Anchor>,
|
||||||
buffer: &MultiBufferSnapshot,
|
buffer: &MultiBufferSnapshot,
|
||||||
cx: &AppContext,
|
|
||||||
) -> Selection<D> {
|
) -> Selection<D> {
|
||||||
Selection {
|
Selection {
|
||||||
id: selection.id,
|
id: selection.id,
|
||||||
|
@ -3120,7 +3137,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn selection_count<'a>(&self, cx: &'a AppContext) -> usize {
|
fn selection_count<'a>(&self) -> usize {
|
||||||
let mut count = self.selections.len();
|
let mut count = self.selections.len();
|
||||||
if self.pending_selection.is_some() {
|
if self.pending_selection.is_some() {
|
||||||
count += 1;
|
count += 1;
|
||||||
|
@ -3131,27 +3148,25 @@ impl Editor {
|
||||||
pub fn oldest_selection<D: TextDimension + Ord + Sub<D, Output = D>>(
|
pub fn oldest_selection<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||||
&self,
|
&self,
|
||||||
snapshot: &MultiBufferSnapshot,
|
snapshot: &MultiBufferSnapshot,
|
||||||
cx: &AppContext,
|
|
||||||
) -> Selection<D> {
|
) -> Selection<D> {
|
||||||
self.selections
|
self.selections
|
||||||
.iter()
|
.iter()
|
||||||
.min_by_key(|s| s.id)
|
.min_by_key(|s| s.id)
|
||||||
.map(|selection| self.resolve_selection(selection, snapshot, cx))
|
.map(|selection| self.resolve_selection(selection, snapshot))
|
||||||
.or_else(|| self.pending_selection(snapshot, cx))
|
.or_else(|| self.pending_selection(snapshot))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn newest_selection<D: TextDimension + Ord + Sub<D, Output = D>>(
|
pub fn newest_selection<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||||
&self,
|
&self,
|
||||||
snapshot: &MultiBufferSnapshot,
|
snapshot: &MultiBufferSnapshot,
|
||||||
cx: &AppContext,
|
|
||||||
) -> Selection<D> {
|
) -> Selection<D> {
|
||||||
self.pending_selection(snapshot, cx)
|
self.pending_selection(snapshot)
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
self.selections
|
self.selections
|
||||||
.iter()
|
.iter()
|
||||||
.min_by_key(|s| s.id)
|
.min_by_key(|s| s.id)
|
||||||
.map(|selection| self.resolve_selection(selection, snapshot, cx))
|
.map(|selection| self.resolve_selection(selection, snapshot))
|
||||||
})
|
})
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
@ -3249,7 +3264,7 @@ impl Editor {
|
||||||
pub fn fold(&mut self, _: &Fold, cx: &mut ViewContext<Self>) {
|
pub fn fold(&mut self, _: &Fold, cx: &mut ViewContext<Self>) {
|
||||||
let mut fold_ranges = Vec::new();
|
let mut fold_ranges = Vec::new();
|
||||||
|
|
||||||
let selections = self.selections::<Point>(cx);
|
let selections = self.local_selections::<Point>(cx);
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
for selection in selections {
|
for selection in selections {
|
||||||
let range = selection.display_range(&display_map).sorted();
|
let range = selection.display_range(&display_map).sorted();
|
||||||
|
@ -3272,7 +3287,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unfold(&mut self, _: &Unfold, cx: &mut ViewContext<Self>) {
|
pub fn unfold(&mut self, _: &Unfold, cx: &mut ViewContext<Self>) {
|
||||||
let selections = self.selections::<Point>(cx);
|
let selections = self.local_selections::<Point>(cx);
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let buffer = &display_map.buffer_snapshot;
|
let buffer = &display_map.buffer_snapshot;
|
||||||
let ranges = selections
|
let ranges = selections
|
||||||
|
@ -3332,7 +3347,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fold_selected_ranges(&mut self, _: &FoldSelectedRanges, cx: &mut ViewContext<Self>) {
|
pub fn fold_selected_ranges(&mut self, _: &FoldSelectedRanges, cx: &mut ViewContext<Self>) {
|
||||||
let selections = self.selections::<Point>(cx);
|
let selections = self.local_selections::<Point>(cx);
|
||||||
let ranges = selections.into_iter().map(|s| s.start..s.end);
|
let ranges = selections.into_iter().map(|s| s.start..s.end);
|
||||||
self.fold_ranges(ranges, cx);
|
self.fold_ranges(ranges, cx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,7 +249,7 @@ impl CursorPosition {
|
||||||
|
|
||||||
self.selected_count = 0;
|
self.selected_count = 0;
|
||||||
let mut last_selection: Option<Selection<usize>> = None;
|
let mut last_selection: Option<Selection<usize>> = None;
|
||||||
for selection in editor.selections::<usize>(cx) {
|
for selection in editor.local_selections::<usize>(cx) {
|
||||||
self.selected_count += selection.end - selection.start;
|
self.selected_count += selection.end - selection.start;
|
||||||
if last_selection
|
if last_selection
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -323,9 +323,7 @@ impl DiagnosticMessage {
|
||||||
fn update(&mut self, editor: ViewHandle<Editor>, cx: &mut ViewContext<Self>) {
|
fn update(&mut self, editor: ViewHandle<Editor>, cx: &mut ViewContext<Self>) {
|
||||||
let editor = editor.read(cx);
|
let editor = editor.read(cx);
|
||||||
let buffer = editor.buffer().read(cx);
|
let buffer = editor.buffer().read(cx);
|
||||||
let cursor_position = editor
|
let cursor_position = editor.newest_selection::<usize>(&buffer.read(cx)).head();
|
||||||
.newest_selection::<usize>(&buffer.read(cx), cx)
|
|
||||||
.head();
|
|
||||||
let new_diagnostic = buffer
|
let new_diagnostic = buffer
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.diagnostics_in_range::<_, usize>(cursor_position..cursor_position)
|
.diagnostics_in_range::<_, usize>(cursor_position..cursor_position)
|
||||||
|
|
|
@ -7,10 +7,9 @@ use clock::ReplicaId;
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use gpui::{AppContext, Entity, ModelContext, ModelHandle, MutableAppContext, Task};
|
use gpui::{AppContext, Entity, ModelContext, ModelHandle, MutableAppContext, Task};
|
||||||
use language::{
|
use language::{
|
||||||
Buffer, BufferChunks, BufferSnapshot, Chunk, DiagnosticEntry, Event, File, Language,
|
Buffer, BufferChunks, BufferSnapshot, Chunk, DiagnosticEntry, Event, File, Language, Selection,
|
||||||
ToOffset as _, ToPoint as _, TransactionId,
|
ToOffset as _, ToPoint as _, TransactionId,
|
||||||
};
|
};
|
||||||
pub use selection::SelectionSet;
|
|
||||||
use std::{
|
use std::{
|
||||||
cell::{Ref, RefCell},
|
cell::{Ref, RefCell},
|
||||||
cmp, io,
|
cmp, io,
|
||||||
|
@ -24,7 +23,7 @@ use text::{
|
||||||
locator::Locator,
|
locator::Locator,
|
||||||
rope::TextDimension,
|
rope::TextDimension,
|
||||||
subscription::{Subscription, Topic},
|
subscription::{Subscription, Topic},
|
||||||
AnchorRangeExt as _, Edit, Point, PointUtf16, SelectionSetId, TextSummary,
|
AnchorRangeExt as _, Edit, Point, PointUtf16, TextSummary,
|
||||||
};
|
};
|
||||||
use theme::SyntaxTheme;
|
use theme::SyntaxTheme;
|
||||||
|
|
||||||
|
@ -36,7 +35,6 @@ pub struct MultiBuffer {
|
||||||
snapshot: RefCell<MultiBufferSnapshot>,
|
snapshot: RefCell<MultiBufferSnapshot>,
|
||||||
buffers: HashMap<usize, BufferState>,
|
buffers: HashMap<usize, BufferState>,
|
||||||
subscriptions: Topic,
|
subscriptions: Topic,
|
||||||
selection_sets: HashMap<SelectionSetId, SelectionSet>,
|
|
||||||
singleton: bool,
|
singleton: bool,
|
||||||
replica_id: ReplicaId,
|
replica_id: ReplicaId,
|
||||||
}
|
}
|
||||||
|
@ -104,7 +102,6 @@ impl MultiBuffer {
|
||||||
snapshot: Default::default(),
|
snapshot: Default::default(),
|
||||||
buffers: Default::default(),
|
buffers: Default::default(),
|
||||||
subscriptions: Default::default(),
|
subscriptions: Default::default(),
|
||||||
selection_sets: Default::default(),
|
|
||||||
singleton: false,
|
singleton: false,
|
||||||
replica_id,
|
replica_id,
|
||||||
}
|
}
|
||||||
|
@ -937,6 +934,19 @@ impl MultiBufferSnapshot {
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remote_selections_in_range<'a, I, O>(
|
||||||
|
&'a self,
|
||||||
|
range: Range<I>,
|
||||||
|
) -> impl 'a + Iterator<Item = (ReplicaId, impl 'a + Iterator<Item = Selection<O>>)>
|
||||||
|
where
|
||||||
|
I: ToOffset,
|
||||||
|
O: TextDimension,
|
||||||
|
{
|
||||||
|
self.as_singleton()
|
||||||
|
.unwrap()
|
||||||
|
.remote_selections_in_range(range.start.to_offset(self)..range.end.to_offset(self))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Excerpt {
|
impl Excerpt {
|
||||||
|
|
|
@ -1,85 +1,6 @@
|
||||||
use super::{Anchor, MultiBufferSnapshot, ToOffset};
|
use super::{Anchor, MultiBufferSnapshot};
|
||||||
use std::{
|
use std::ops::Sub;
|
||||||
ops::{Range, Sub},
|
use text::{rope::TextDimension, Selection};
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
use sum_tree::Bias;
|
|
||||||
use text::{rope::TextDimension, Selection, SelectionSetId};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
||||||
pub struct SelectionSet {
|
|
||||||
pub id: SelectionSetId,
|
|
||||||
pub active: bool,
|
|
||||||
pub selections: Arc<[Selection<Anchor>]>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SelectionSet {
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.selections.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn selections<'a, D>(
|
|
||||||
&'a self,
|
|
||||||
snapshot: &'a MultiBufferSnapshot,
|
|
||||||
) -> impl 'a + Iterator<Item = Selection<D>>
|
|
||||||
where
|
|
||||||
D: TextDimension + Ord + Sub<D, Output = D>,
|
|
||||||
{
|
|
||||||
resolve_selections(&self.selections, snapshot)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn intersecting_selections<'a, D, I>(
|
|
||||||
&'a self,
|
|
||||||
range: Range<(I, Bias)>,
|
|
||||||
snapshot: &'a MultiBufferSnapshot,
|
|
||||||
) -> impl 'a + Iterator<Item = Selection<D>>
|
|
||||||
where
|
|
||||||
D: TextDimension + Ord + Sub<D, Output = D>,
|
|
||||||
I: 'a + ToOffset,
|
|
||||||
{
|
|
||||||
let start = snapshot.anchor_at(range.start.0, range.start.1);
|
|
||||||
let end = snapshot.anchor_at(range.end.0, range.end.1);
|
|
||||||
let start_ix = match self
|
|
||||||
.selections
|
|
||||||
.binary_search_by(|probe| probe.end.cmp(&start, snapshot).unwrap())
|
|
||||||
{
|
|
||||||
Ok(ix) | Err(ix) => ix,
|
|
||||||
};
|
|
||||||
let end_ix = match self
|
|
||||||
.selections
|
|
||||||
.binary_search_by(|probe| probe.start.cmp(&end, snapshot).unwrap())
|
|
||||||
{
|
|
||||||
Ok(ix) | Err(ix) => ix,
|
|
||||||
};
|
|
||||||
resolve_selections(&self.selections[start_ix..end_ix], snapshot)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn oldest_selection<'a, D>(
|
|
||||||
&'a self,
|
|
||||||
snapshot: &'a MultiBufferSnapshot,
|
|
||||||
) -> Option<Selection<D>>
|
|
||||||
where
|
|
||||||
D: TextDimension + Ord + Sub<D, Output = D>,
|
|
||||||
{
|
|
||||||
self.selections
|
|
||||||
.iter()
|
|
||||||
.min_by_key(|selection| selection.id)
|
|
||||||
.map(|selection| resolve_selection(selection, snapshot))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn newest_selection<'a, D>(
|
|
||||||
&'a self,
|
|
||||||
snapshot: &'a MultiBufferSnapshot,
|
|
||||||
) -> Option<Selection<D>>
|
|
||||||
where
|
|
||||||
D: TextDimension + Ord + Sub<D, Output = D>,
|
|
||||||
{
|
|
||||||
self.selections
|
|
||||||
.iter()
|
|
||||||
.max_by_key(|selection| selection.id)
|
|
||||||
.map(|selection| resolve_selection(selection, snapshot))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_selection<'a, D>(
|
fn resolve_selection<'a, D>(
|
||||||
selection: &'a Selection<Anchor>,
|
selection: &'a Selection<Anchor>,
|
||||||
|
|
|
@ -67,13 +67,14 @@ impl GoToLine {
|
||||||
let (restore_state, cursor_point, max_point) = active_editor.update(cx, |editor, cx| {
|
let (restore_state, cursor_point, max_point) = active_editor.update(cx, |editor, cx| {
|
||||||
let restore_state = Some(RestoreState {
|
let restore_state = Some(RestoreState {
|
||||||
scroll_position: editor.scroll_position(cx),
|
scroll_position: editor.scroll_position(cx),
|
||||||
selections: editor.selections::<usize>(cx),
|
selections: editor.local_selections::<usize>(cx),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let buffer = editor.buffer().read(cx).read(cx);
|
||||||
(
|
(
|
||||||
restore_state,
|
restore_state,
|
||||||
editor.newest_selection(cx).head(),
|
editor.newest_selection(&buffer).head(),
|
||||||
editor.buffer().read(cx).read(cx).max_point(),
|
buffer.max_point(),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -143,7 +144,7 @@ impl GoToLine {
|
||||||
let display_point = point.to_display_point(&snapshot);
|
let display_point = point.to_display_point(&snapshot);
|
||||||
active_editor.select_ranges([point..point], Some(Autoscroll::Center), cx);
|
active_editor.select_ranges([point..point], Some(Autoscroll::Center), cx);
|
||||||
active_editor.set_highlighted_row(Some(display_point.row()));
|
active_editor.set_highlighted_row(Some(display_point.row()));
|
||||||
Some(active_editor.newest_selection(cx))
|
Some(active_editor.newest_selection(&snapshot.buffer_snapshot))
|
||||||
});
|
});
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
@ -162,7 +163,9 @@ impl Entity for GoToLine {
|
||||||
self.active_editor.update(cx, |editor, cx| {
|
self.active_editor.update(cx, |editor, cx| {
|
||||||
editor.set_highlighted_row(None);
|
editor.set_highlighted_row(None);
|
||||||
if let Some((line_selection, restore_state)) = line_selection.zip(restore_state) {
|
if let Some((line_selection, restore_state)) = line_selection.zip(restore_state) {
|
||||||
if line_selection.id == editor.newest_selection::<usize>(cx).id {
|
let newest_selection =
|
||||||
|
editor.newest_selection::<usize>(&editor.buffer().read(cx).read(cx));
|
||||||
|
if line_selection.id == newest_selection.id {
|
||||||
editor.set_scroll_position(restore_state.scroll_position, cx);
|
editor.set_scroll_position(restore_state.scroll_position, cx);
|
||||||
editor.update_selections(restore_state.selections, None, cx);
|
editor.update_selections(restore_state.selections, None, cx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,8 @@ use std::{
|
||||||
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
|
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
|
||||||
vec,
|
vec,
|
||||||
};
|
};
|
||||||
use text::operation_queue::OperationQueue;
|
use sum_tree::TreeMap;
|
||||||
|
use text::{operation_queue::OperationQueue, rope::TextDimension};
|
||||||
pub use text::{Buffer as TextBuffer, Operation as _, *};
|
pub use text::{Buffer as TextBuffer, Operation as _, *};
|
||||||
use theme::SyntaxTheme;
|
use theme::SyntaxTheme;
|
||||||
use tree_sitter::{InputEdit, Parser, QueryCursor, Tree};
|
use tree_sitter::{InputEdit, Parser, QueryCursor, Tree};
|
||||||
|
@ -64,6 +65,7 @@ pub struct Buffer {
|
||||||
syntax_tree: Mutex<Option<SyntaxTree>>,
|
syntax_tree: Mutex<Option<SyntaxTree>>,
|
||||||
parsing_in_background: bool,
|
parsing_in_background: bool,
|
||||||
parse_count: usize,
|
parse_count: usize,
|
||||||
|
remote_selections: TreeMap<ReplicaId, Arc<[Selection<Anchor>]>>,
|
||||||
diagnostics: DiagnosticSet,
|
diagnostics: DiagnosticSet,
|
||||||
diagnostics_update_count: usize,
|
diagnostics_update_count: usize,
|
||||||
language_server: Option<LanguageServerState>,
|
language_server: Option<LanguageServerState>,
|
||||||
|
@ -76,6 +78,7 @@ pub struct BufferSnapshot {
|
||||||
text: text::BufferSnapshot,
|
text: text::BufferSnapshot,
|
||||||
tree: Option<Tree>,
|
tree: Option<Tree>,
|
||||||
diagnostics: DiagnosticSet,
|
diagnostics: DiagnosticSet,
|
||||||
|
remote_selections: TreeMap<ReplicaId, Arc<[Selection<Anchor>]>>,
|
||||||
diagnostics_update_count: usize,
|
diagnostics_update_count: usize,
|
||||||
is_parsing: bool,
|
is_parsing: bool,
|
||||||
language: Option<Arc<Language>>,
|
language: Option<Arc<Language>>,
|
||||||
|
@ -112,6 +115,15 @@ pub enum Operation {
|
||||||
diagnostics: Arc<[DiagnosticEntry<Anchor>]>,
|
diagnostics: Arc<[DiagnosticEntry<Anchor>]>,
|
||||||
lamport_timestamp: clock::Lamport,
|
lamport_timestamp: clock::Lamport,
|
||||||
},
|
},
|
||||||
|
UpdateSelections {
|
||||||
|
replica_id: ReplicaId,
|
||||||
|
selections: Arc<[Selection<Anchor>]>,
|
||||||
|
lamport_timestamp: clock::Lamport,
|
||||||
|
},
|
||||||
|
RemoveSelections {
|
||||||
|
replica_id: ReplicaId,
|
||||||
|
lamport_timestamp: clock::Lamport,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
@ -329,6 +341,7 @@ impl Buffer {
|
||||||
autoindent_requests: Default::default(),
|
autoindent_requests: Default::default(),
|
||||||
pending_autoindent: Default::default(),
|
pending_autoindent: Default::default(),
|
||||||
language: None,
|
language: None,
|
||||||
|
remote_selections: Default::default(),
|
||||||
diagnostics: Default::default(),
|
diagnostics: Default::default(),
|
||||||
diagnostics_update_count: 0,
|
diagnostics_update_count: 0,
|
||||||
language_server: None,
|
language_server: None,
|
||||||
|
@ -342,6 +355,7 @@ impl Buffer {
|
||||||
BufferSnapshot {
|
BufferSnapshot {
|
||||||
text: self.text.snapshot(),
|
text: self.text.snapshot(),
|
||||||
tree: self.syntax_tree(),
|
tree: self.syntax_tree(),
|
||||||
|
remote_selections: self.remote_selections.clone(),
|
||||||
diagnostics: self.diagnostics.clone(),
|
diagnostics: self.diagnostics.clone(),
|
||||||
diagnostics_update_count: self.diagnostics_update_count,
|
diagnostics_update_count: self.diagnostics_update_count,
|
||||||
is_parsing: self.parsing_in_background,
|
is_parsing: self.parsing_in_background,
|
||||||
|
@ -1286,6 +1300,10 @@ impl Buffer {
|
||||||
&& self.text.can_resolve(&diagnostic.range.end)
|
&& self.text.can_resolve(&diagnostic.range.end)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Operation::UpdateSelections { selections, .. } => selections
|
||||||
|
.iter()
|
||||||
|
.all(|s| self.can_resolve(&s.start) && self.can_resolve(&s.end)),
|
||||||
|
Operation::RemoveSelections { .. } => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1297,6 +1315,21 @@ impl Buffer {
|
||||||
Operation::UpdateDiagnostics { diagnostics, .. } => {
|
Operation::UpdateDiagnostics { diagnostics, .. } => {
|
||||||
self.apply_diagnostic_update(diagnostics, cx);
|
self.apply_diagnostic_update(diagnostics, cx);
|
||||||
}
|
}
|
||||||
|
Operation::UpdateSelections {
|
||||||
|
replica_id,
|
||||||
|
selections,
|
||||||
|
lamport_timestamp,
|
||||||
|
} => {
|
||||||
|
self.remote_selections.insert(replica_id, selections);
|
||||||
|
self.text.observe_lamport_timestamp(lamport_timestamp);
|
||||||
|
}
|
||||||
|
Operation::RemoveSelections {
|
||||||
|
replica_id: set_id,
|
||||||
|
lamport_timestamp,
|
||||||
|
} => {
|
||||||
|
self.remote_selections.remove(&set_id);
|
||||||
|
self.text.observe_lamport_timestamp(lamport_timestamp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1323,7 +1356,7 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_peer(&mut self, replica_id: ReplicaId, cx: &mut ModelContext<Self>) {
|
pub fn remove_peer(&mut self, replica_id: ReplicaId, cx: &mut ModelContext<Self>) {
|
||||||
self.text.remove_peer(replica_id);
|
self.remote_selections.remove(&replica_id);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1615,6 +1648,43 @@ impl BufferSnapshot {
|
||||||
.min_by_key(|(open_range, close_range)| close_range.end - open_range.start)
|
.min_by_key(|(open_range, close_range)| close_range.end - open_range.start)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remote_selections_in_range<'a, I, O>(
|
||||||
|
&'a self,
|
||||||
|
range: Range<I>,
|
||||||
|
) -> impl 'a + Iterator<Item = (ReplicaId, impl 'a + Iterator<Item = Selection<O>>)>
|
||||||
|
where
|
||||||
|
I: ToOffset,
|
||||||
|
O: TextDimension,
|
||||||
|
{
|
||||||
|
let range = self.anchor_before(range.start)..self.anchor_after(range.end);
|
||||||
|
self.remote_selections
|
||||||
|
.iter()
|
||||||
|
.map(move |(replica_id, selections)| {
|
||||||
|
let start_ix = match selections
|
||||||
|
.binary_search_by(|probe| probe.end.cmp(&range.start, self).unwrap())
|
||||||
|
{
|
||||||
|
Ok(ix) | Err(ix) => ix,
|
||||||
|
};
|
||||||
|
let end_ix = match selections
|
||||||
|
.binary_search_by(|probe| probe.start.cmp(&range.end, self).unwrap())
|
||||||
|
{
|
||||||
|
Ok(ix) | Err(ix) => ix,
|
||||||
|
};
|
||||||
|
|
||||||
|
let selections = &selections[start_ix..end_ix];
|
||||||
|
let mut summaries =
|
||||||
|
self.summaries_for_anchors(selections.iter().flat_map(|s| [&s.start, &s.end]));
|
||||||
|
let resolved = selections.iter().map(move |s| Selection {
|
||||||
|
id: s.id,
|
||||||
|
start: summaries.next().unwrap(),
|
||||||
|
end: summaries.next().unwrap(),
|
||||||
|
reversed: s.reversed,
|
||||||
|
goal: s.goal,
|
||||||
|
});
|
||||||
|
(*replica_id, resolved)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn diagnostics_in_range<'a, T, O>(
|
pub fn diagnostics_in_range<'a, T, O>(
|
||||||
&'a self,
|
&'a self,
|
||||||
search_range: Range<T>,
|
search_range: Range<T>,
|
||||||
|
@ -1650,6 +1720,7 @@ impl Clone for BufferSnapshot {
|
||||||
Self {
|
Self {
|
||||||
text: self.text.clone(),
|
text: self.text.clone(),
|
||||||
tree: self.tree.clone(),
|
tree: self.tree.clone(),
|
||||||
|
remote_selections: self.remote_selections.clone(),
|
||||||
diagnostics: self.diagnostics.clone(),
|
diagnostics: self.diagnostics.clone(),
|
||||||
diagnostics_update_count: self.diagnostics_update_count,
|
diagnostics_update_count: self.diagnostics_update_count,
|
||||||
is_parsing: self.is_parsing,
|
is_parsing: self.is_parsing,
|
||||||
|
@ -1889,6 +1960,12 @@ impl operation_queue::Operation for Operation {
|
||||||
}
|
}
|
||||||
Operation::UpdateDiagnostics {
|
Operation::UpdateDiagnostics {
|
||||||
lamport_timestamp, ..
|
lamport_timestamp, ..
|
||||||
|
}
|
||||||
|
| Operation::UpdateSelections {
|
||||||
|
lamport_timestamp, ..
|
||||||
|
}
|
||||||
|
| Operation::RemoveSelections {
|
||||||
|
lamport_timestamp, ..
|
||||||
} => *lamport_timestamp,
|
} => *lamport_timestamp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,13 +41,12 @@ pub fn serialize_operation(operation: &Operation) -> proto::Operation {
|
||||||
.collect(),
|
.collect(),
|
||||||
version: From::from(&undo.version),
|
version: From::from(&undo.version),
|
||||||
}),
|
}),
|
||||||
Operation::Buffer(text::Operation::UpdateSelections {
|
Operation::UpdateSelections {
|
||||||
set_id,
|
replica_id,
|
||||||
selections,
|
selections,
|
||||||
lamport_timestamp,
|
lamport_timestamp,
|
||||||
}) => proto::operation::Variant::UpdateSelections(proto::operation::UpdateSelections {
|
} => proto::operation::Variant::UpdateSelections(proto::operation::UpdateSelections {
|
||||||
replica_id: set_id.replica_id as u32,
|
replica_id: *replica_id as u32,
|
||||||
local_timestamp: set_id.value,
|
|
||||||
lamport_timestamp: lamport_timestamp.value,
|
lamport_timestamp: lamport_timestamp.value,
|
||||||
selections: selections
|
selections: selections
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -59,24 +58,13 @@ pub fn serialize_operation(operation: &Operation) -> proto::Operation {
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
}),
|
}),
|
||||||
Operation::Buffer(text::Operation::RemoveSelections {
|
Operation::RemoveSelections {
|
||||||
set_id,
|
replica_id,
|
||||||
lamport_timestamp,
|
lamport_timestamp,
|
||||||
}) => proto::operation::Variant::RemoveSelections(proto::operation::RemoveSelections {
|
} => proto::operation::Variant::RemoveSelections(proto::operation::RemoveSelections {
|
||||||
replica_id: set_id.replica_id as u32,
|
replica_id: *replica_id as u32,
|
||||||
local_timestamp: set_id.value,
|
|
||||||
lamport_timestamp: lamport_timestamp.value,
|
lamport_timestamp: lamport_timestamp.value,
|
||||||
}),
|
}),
|
||||||
Operation::Buffer(text::Operation::SetActiveSelections {
|
|
||||||
set_id,
|
|
||||||
lamport_timestamp,
|
|
||||||
}) => proto::operation::Variant::SetActiveSelections(
|
|
||||||
proto::operation::SetActiveSelections {
|
|
||||||
replica_id: lamport_timestamp.replica_id as u32,
|
|
||||||
local_timestamp: set_id.map(|set_id| set_id.value),
|
|
||||||
lamport_timestamp: lamport_timestamp.value,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Operation::UpdateDiagnostics {
|
Operation::UpdateDiagnostics {
|
||||||
diagnostics,
|
diagnostics,
|
||||||
lamport_timestamp,
|
lamport_timestamp,
|
||||||
|
@ -108,22 +96,16 @@ pub fn serialize_edit_operation(operation: &EditOperation) -> proto::operation::
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serialize_selection_set(set: &SelectionSet) -> proto::SelectionSet {
|
pub fn serialize_selections(selections: &Arc<[Selection<Anchor>]>) -> Vec<proto::Selection> {
|
||||||
proto::SelectionSet {
|
selections
|
||||||
replica_id: set.id.replica_id as u32,
|
.iter()
|
||||||
lamport_timestamp: set.id.value as u32,
|
.map(|selection| proto::Selection {
|
||||||
is_active: set.active,
|
id: selection.id as u64,
|
||||||
selections: set
|
start: Some(serialize_anchor(&selection.start)),
|
||||||
.selections
|
end: Some(serialize_anchor(&selection.end)),
|
||||||
.iter()
|
reversed: selection.reversed,
|
||||||
.map(|selection| proto::Selection {
|
})
|
||||||
id: selection.id as u64,
|
.collect()
|
||||||
start: Some(serialize_anchor(&selection.start)),
|
|
||||||
end: Some(serialize_anchor(&selection.end)),
|
|
||||||
reversed: selection.reversed,
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serialize_diagnostics<'a>(
|
pub fn serialize_diagnostics<'a>(
|
||||||
|
@ -215,42 +197,22 @@ pub fn deserialize_operation(message: proto::Operation) -> Result<Operation> {
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
Operation::Buffer(text::Operation::UpdateSelections {
|
Operation::UpdateSelections {
|
||||||
set_id: clock::Lamport {
|
replica_id: message.replica_id as ReplicaId,
|
||||||
replica_id: message.replica_id as ReplicaId,
|
|
||||||
value: message.local_timestamp,
|
|
||||||
},
|
|
||||||
lamport_timestamp: clock::Lamport {
|
lamport_timestamp: clock::Lamport {
|
||||||
replica_id: message.replica_id as ReplicaId,
|
replica_id: message.replica_id as ReplicaId,
|
||||||
value: message.lamport_timestamp,
|
value: message.lamport_timestamp,
|
||||||
},
|
},
|
||||||
selections: Arc::from(selections),
|
selections: Arc::from(selections),
|
||||||
})
|
}
|
||||||
}
|
|
||||||
proto::operation::Variant::RemoveSelections(message) => {
|
|
||||||
Operation::Buffer(text::Operation::RemoveSelections {
|
|
||||||
set_id: clock::Lamport {
|
|
||||||
replica_id: message.replica_id as ReplicaId,
|
|
||||||
value: message.local_timestamp,
|
|
||||||
},
|
|
||||||
lamport_timestamp: clock::Lamport {
|
|
||||||
replica_id: message.replica_id as ReplicaId,
|
|
||||||
value: message.lamport_timestamp,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
proto::operation::Variant::SetActiveSelections(message) => {
|
|
||||||
Operation::Buffer(text::Operation::SetActiveSelections {
|
|
||||||
set_id: message.local_timestamp.map(|value| clock::Lamport {
|
|
||||||
replica_id: message.replica_id as ReplicaId,
|
|
||||||
value,
|
|
||||||
}),
|
|
||||||
lamport_timestamp: clock::Lamport {
|
|
||||||
replica_id: message.replica_id as ReplicaId,
|
|
||||||
value: message.lamport_timestamp,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
proto::operation::Variant::RemoveSelections(message) => Operation::RemoveSelections {
|
||||||
|
replica_id: message.replica_id as ReplicaId,
|
||||||
|
lamport_timestamp: clock::Lamport {
|
||||||
|
replica_id: message.replica_id as ReplicaId,
|
||||||
|
value: message.lamport_timestamp,
|
||||||
|
},
|
||||||
|
},
|
||||||
proto::operation::Variant::UpdateDiagnostics(message) => Operation::UpdateDiagnostics {
|
proto::operation::Variant::UpdateDiagnostics(message) => Operation::UpdateDiagnostics {
|
||||||
diagnostics: Arc::from(deserialize_diagnostics(message.diagnostics)),
|
diagnostics: Arc::from(deserialize_diagnostics(message.diagnostics)),
|
||||||
lamport_timestamp: clock::Lamport {
|
lamport_timestamp: clock::Lamport {
|
||||||
|
@ -280,28 +242,21 @@ pub fn deserialize_edit_operation(edit: proto::operation::Edit) -> EditOperation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deserialize_selection_set(set: proto::SelectionSet) -> SelectionSet {
|
pub fn deserialize_selections(selections: Vec<proto::Selection>) -> Arc<[Selection<Anchor>]> {
|
||||||
SelectionSet {
|
Arc::from(
|
||||||
id: clock::Lamport {
|
selections
|
||||||
replica_id: set.replica_id as u16,
|
.into_iter()
|
||||||
value: set.lamport_timestamp,
|
.filter_map(|selection| {
|
||||||
},
|
Some(Selection {
|
||||||
active: set.is_active,
|
id: selection.id as usize,
|
||||||
selections: Arc::from(
|
start: deserialize_anchor(selection.start?)?,
|
||||||
set.selections
|
end: deserialize_anchor(selection.end?)?,
|
||||||
.into_iter()
|
reversed: selection.reversed,
|
||||||
.filter_map(|selection| {
|
goal: SelectionGoal::None,
|
||||||
Some(Selection {
|
|
||||||
id: selection.id as usize,
|
|
||||||
start: deserialize_anchor(selection.start?)?,
|
|
||||||
end: deserialize_anchor(selection.end?)?,
|
|
||||||
reversed: selection.reversed,
|
|
||||||
goal: SelectionGoal::None,
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>(),
|
})
|
||||||
),
|
.collect::<Vec<_>>(),
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deserialize_diagnostics(
|
pub fn deserialize_diagnostics(
|
||||||
|
|
|
@ -286,8 +286,7 @@ message Operation {
|
||||||
Undo undo = 2;
|
Undo undo = 2;
|
||||||
UpdateSelections update_selections = 3;
|
UpdateSelections update_selections = 3;
|
||||||
RemoveSelections remove_selections = 4;
|
RemoveSelections remove_selections = 4;
|
||||||
SetActiveSelections set_active_selections = 5;
|
UpdateDiagnostics update_diagnostics = 5;
|
||||||
UpdateDiagnostics update_diagnostics = 6;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message Edit {
|
message Edit {
|
||||||
|
@ -316,20 +315,12 @@ message Operation {
|
||||||
|
|
||||||
message UpdateSelections {
|
message UpdateSelections {
|
||||||
uint32 replica_id = 1;
|
uint32 replica_id = 1;
|
||||||
uint32 local_timestamp = 2;
|
|
||||||
uint32 lamport_timestamp = 3;
|
uint32 lamport_timestamp = 3;
|
||||||
repeated Selection selections = 4;
|
repeated Selection selections = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message RemoveSelections {
|
message RemoveSelections {
|
||||||
uint32 replica_id = 1;
|
uint32 replica_id = 1;
|
||||||
uint32 local_timestamp = 2;
|
|
||||||
uint32 lamport_timestamp = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SetActiveSelections {
|
|
||||||
uint32 replica_id = 1;
|
|
||||||
optional uint32 local_timestamp = 2;
|
|
||||||
uint32 lamport_timestamp = 3;
|
uint32 lamport_timestamp = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ use std::{cmp::Ordering, fmt::Debug};
|
||||||
|
|
||||||
use crate::{Bias, Dimension, Item, KeyedItem, SeekTarget, SumTree, Summary};
|
use crate::{Bias, Dimension, Item, KeyedItem, SeekTarget, SumTree, Summary};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct TreeMap<K, V>(SumTree<MapEntry<K, V>>)
|
pub struct TreeMap<K, V>(SumTree<MapEntry<K, V>>)
|
||||||
where
|
where
|
||||||
K: Clone + Debug + Default,
|
K: Clone + Debug + Default,
|
||||||
|
@ -19,7 +20,7 @@ pub struct MapKey<K>(K);
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct MapKeyRef<'a, K>(Option<&'a K>);
|
pub struct MapKeyRef<'a, K>(Option<&'a K>);
|
||||||
|
|
||||||
impl<K: Clone + Debug + Default + Ord, V: Clone + Debug + Default> TreeMap<K, V> {
|
impl<K: Clone + Debug + Default + Ord, V: Clone + Debug> TreeMap<K, V> {
|
||||||
pub fn get<'a>(&self, key: &'a K) -> Option<&V> {
|
pub fn get<'a>(&self, key: &'a K) -> Option<&V> {
|
||||||
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>();
|
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>();
|
||||||
let key = MapKeyRef(Some(key));
|
let key = MapKeyRef(Some(key));
|
||||||
|
@ -49,6 +50,20 @@ impl<K: Clone + Debug + Default + Ord, V: Clone + Debug + Default> TreeMap<K, V>
|
||||||
self.0 = new_tree;
|
self.0 = new_tree;
|
||||||
removed
|
removed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn iter<'a>(&'a self) -> impl 'a + Iterator<Item = (&'a K, &'a V)> {
|
||||||
|
self.0.iter().map(|entry| (&entry.key, &entry.value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K, V> Default for TreeMap<K, V>
|
||||||
|
where
|
||||||
|
K: Clone + Debug + Default,
|
||||||
|
V: Clone + Debug,
|
||||||
|
{
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(Default::default())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K, V> Item for MapEntry<K, V>
|
impl<K, V> Item for MapEntry<K, V>
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
use crate::Anchor;
|
use crate::Anchor;
|
||||||
use crate::{rope::TextDimension, BufferSnapshot, ToOffset, ToPoint};
|
use crate::{rope::TextDimension, BufferSnapshot, ToOffset, ToPoint};
|
||||||
use std::{cmp::Ordering, ops::Range, sync::Arc};
|
use std::cmp::Ordering;
|
||||||
use sum_tree::Bias;
|
|
||||||
|
|
||||||
pub type SelectionSetId = clock::Lamport;
|
|
||||||
pub type SelectionsVersion = usize;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum SelectionGoal {
|
pub enum SelectionGoal {
|
||||||
|
@ -22,20 +18,6 @@ pub struct Selection<T> {
|
||||||
pub goal: SelectionGoal,
|
pub goal: SelectionGoal,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
||||||
pub struct SelectionSet {
|
|
||||||
pub id: SelectionSetId,
|
|
||||||
pub active: bool,
|
|
||||||
pub selections: Arc<[Selection<Anchor>]>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
|
||||||
pub struct SelectionState {
|
|
||||||
pub id: usize,
|
|
||||||
pub reversed: bool,
|
|
||||||
pub goal: SelectionGoal,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Clone> Selection<T> {
|
impl<T: Clone> Selection<T> {
|
||||||
pub fn head(&self) -> T {
|
pub fn head(&self) -> T {
|
||||||
if self.reversed {
|
if self.reversed {
|
||||||
|
@ -90,78 +72,3 @@ impl Selection<Anchor> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SelectionSet {
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.selections.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn selections<'a, D>(
|
|
||||||
&'a self,
|
|
||||||
snapshot: &'a BufferSnapshot,
|
|
||||||
) -> impl 'a + Iterator<Item = Selection<D>>
|
|
||||||
where
|
|
||||||
D: TextDimension,
|
|
||||||
{
|
|
||||||
let anchors = self
|
|
||||||
.selections
|
|
||||||
.iter()
|
|
||||||
.flat_map(|selection| [&selection.start, &selection.end].into_iter());
|
|
||||||
let mut positions = snapshot.summaries_for_anchors::<D, _>(anchors);
|
|
||||||
self.selections.iter().map(move |selection| Selection {
|
|
||||||
start: positions.next().unwrap(),
|
|
||||||
end: positions.next().unwrap(),
|
|
||||||
goal: selection.goal,
|
|
||||||
reversed: selection.reversed,
|
|
||||||
id: selection.id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn intersecting_selections<'a, D, I>(
|
|
||||||
&'a self,
|
|
||||||
range: Range<(I, Bias)>,
|
|
||||||
snapshot: &'a BufferSnapshot,
|
|
||||||
) -> impl 'a + Iterator<Item = Selection<D>>
|
|
||||||
where
|
|
||||||
D: TextDimension,
|
|
||||||
I: 'a + ToOffset,
|
|
||||||
{
|
|
||||||
let start = snapshot.anchor_at(range.start.0, range.start.1);
|
|
||||||
let end = snapshot.anchor_at(range.end.0, range.end.1);
|
|
||||||
let start_ix = match self
|
|
||||||
.selections
|
|
||||||
.binary_search_by(|probe| probe.end.cmp(&start, snapshot).unwrap())
|
|
||||||
{
|
|
||||||
Ok(ix) | Err(ix) => ix,
|
|
||||||
};
|
|
||||||
let end_ix = match self
|
|
||||||
.selections
|
|
||||||
.binary_search_by(|probe| probe.start.cmp(&end, snapshot).unwrap())
|
|
||||||
{
|
|
||||||
Ok(ix) | Err(ix) => ix,
|
|
||||||
};
|
|
||||||
self.selections[start_ix..end_ix]
|
|
||||||
.iter()
|
|
||||||
.map(|s| s.resolve(snapshot))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn oldest_selection<'a, D>(&'a self, snapshot: &'a BufferSnapshot) -> Option<Selection<D>>
|
|
||||||
where
|
|
||||||
D: TextDimension,
|
|
||||||
{
|
|
||||||
self.selections
|
|
||||||
.iter()
|
|
||||||
.min_by_key(|s| s.id)
|
|
||||||
.map(|s| s.resolve(snapshot))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn newest_selection<'a, D>(&'a self, snapshot: &'a BufferSnapshot) -> Option<Selection<D>>
|
|
||||||
where
|
|
||||||
D: TextDimension,
|
|
||||||
{
|
|
||||||
self.selections
|
|
||||||
.iter()
|
|
||||||
.max_by_key(|s| s.id)
|
|
||||||
.map(|s| s.resolve(snapshot))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -44,7 +44,6 @@ pub struct Buffer {
|
||||||
snapshot: BufferSnapshot,
|
snapshot: BufferSnapshot,
|
||||||
last_edit: clock::Local,
|
last_edit: clock::Local,
|
||||||
history: History,
|
history: History,
|
||||||
selection_sets: HashMap<SelectionSetId, SelectionSet>,
|
|
||||||
deferred_ops: OperationQueue<Operation>,
|
deferred_ops: OperationQueue<Operation>,
|
||||||
deferred_replicas: HashSet<ReplicaId>,
|
deferred_replicas: HashSet<ReplicaId>,
|
||||||
replica_id: ReplicaId,
|
replica_id: ReplicaId,
|
||||||
|
@ -413,19 +412,6 @@ pub enum Operation {
|
||||||
undo: UndoOperation,
|
undo: UndoOperation,
|
||||||
lamport_timestamp: clock::Lamport,
|
lamport_timestamp: clock::Lamport,
|
||||||
},
|
},
|
||||||
UpdateSelections {
|
|
||||||
set_id: SelectionSetId,
|
|
||||||
selections: Arc<[Selection<Anchor>]>,
|
|
||||||
lamport_timestamp: clock::Lamport,
|
|
||||||
},
|
|
||||||
RemoveSelections {
|
|
||||||
set_id: SelectionSetId,
|
|
||||||
lamport_timestamp: clock::Lamport,
|
|
||||||
},
|
|
||||||
SetActiveSelections {
|
|
||||||
set_id: Option<SelectionSetId>,
|
|
||||||
lamport_timestamp: clock::Lamport,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
@ -487,7 +473,6 @@ impl Buffer {
|
||||||
},
|
},
|
||||||
last_edit: clock::Local::default(),
|
last_edit: clock::Local::default(),
|
||||||
history,
|
history,
|
||||||
selection_sets: Default::default(),
|
|
||||||
deferred_ops: OperationQueue::new(),
|
deferred_ops: OperationQueue::new(),
|
||||||
deferred_replicas: HashSet::default(),
|
deferred_replicas: HashSet::default(),
|
||||||
replica_id,
|
replica_id,
|
||||||
|
@ -514,6 +499,10 @@ impl Buffer {
|
||||||
self.lamport_clock
|
self.lamport_clock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn observe_lamport_timestamp(&mut self, timestamp: clock::Lamport) {
|
||||||
|
self.lamport_clock.observe(timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn remote_id(&self) -> u64 {
|
pub fn remote_id(&self) -> u64 {
|
||||||
self.remote_id
|
self.remote_id
|
||||||
}
|
}
|
||||||
|
@ -754,47 +743,6 @@ impl Buffer {
|
||||||
self.lamport_clock.observe(lamport_timestamp);
|
self.lamport_clock.observe(lamport_timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Operation::UpdateSelections {
|
|
||||||
set_id,
|
|
||||||
selections,
|
|
||||||
lamport_timestamp,
|
|
||||||
} => {
|
|
||||||
if let Some(set) = self.selection_sets.get_mut(&set_id) {
|
|
||||||
set.selections = selections;
|
|
||||||
} else {
|
|
||||||
self.selection_sets.insert(
|
|
||||||
set_id,
|
|
||||||
SelectionSet {
|
|
||||||
id: set_id,
|
|
||||||
selections,
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
self.lamport_clock.observe(lamport_timestamp);
|
|
||||||
}
|
|
||||||
Operation::RemoveSelections {
|
|
||||||
set_id,
|
|
||||||
lamport_timestamp,
|
|
||||||
} => {
|
|
||||||
self.selection_sets.remove(&set_id);
|
|
||||||
self.lamport_clock.observe(lamport_timestamp);
|
|
||||||
}
|
|
||||||
Operation::SetActiveSelections {
|
|
||||||
set_id,
|
|
||||||
lamport_timestamp,
|
|
||||||
} => {
|
|
||||||
for (id, set) in &mut self.selection_sets {
|
|
||||||
if id.replica_id == lamport_timestamp.replica_id {
|
|
||||||
if Some(*id) == set_id {
|
|
||||||
set.active = true;
|
|
||||||
} else {
|
|
||||||
set.active = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.lamport_clock.observe(lamport_timestamp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1107,13 +1055,6 @@ impl Buffer {
|
||||||
match op {
|
match op {
|
||||||
Operation::Edit(edit) => self.version.ge(&edit.version),
|
Operation::Edit(edit) => self.version.ge(&edit.version),
|
||||||
Operation::Undo { undo, .. } => self.version.ge(&undo.version),
|
Operation::Undo { undo, .. } => self.version.ge(&undo.version),
|
||||||
Operation::UpdateSelections { selections, .. } => selections
|
|
||||||
.iter()
|
|
||||||
.all(|s| self.can_resolve(&s.start) && self.can_resolve(&s.end)),
|
|
||||||
Operation::RemoveSelections { .. } => true,
|
|
||||||
Operation::SetActiveSelections { set_id, .. } => {
|
|
||||||
set_id.map_or(true, |set_id| self.selection_sets.contains_key(&set_id))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1151,11 +1092,6 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_peer(&mut self, replica_id: ReplicaId) {
|
|
||||||
self.selection_sets
|
|
||||||
.retain(|set_id, _| set_id.replica_id != replica_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn base_text(&self) -> &Arc<str> {
|
pub fn base_text(&self) -> &Arc<str> {
|
||||||
&self.history.base_text
|
&self.history.base_text
|
||||||
}
|
}
|
||||||
|
@ -2007,15 +1943,6 @@ impl operation_queue::Operation for Operation {
|
||||||
Operation::Undo {
|
Operation::Undo {
|
||||||
lamport_timestamp, ..
|
lamport_timestamp, ..
|
||||||
} => *lamport_timestamp,
|
} => *lamport_timestamp,
|
||||||
Operation::UpdateSelections {
|
|
||||||
lamport_timestamp, ..
|
|
||||||
} => *lamport_timestamp,
|
|
||||||
Operation::RemoveSelections {
|
|
||||||
lamport_timestamp, ..
|
|
||||||
} => *lamport_timestamp,
|
|
||||||
Operation::SetActiveSelections {
|
|
||||||
lamport_timestamp, ..
|
|
||||||
} => *lamport_timestamp,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue