Compare commits
3 Commits
vim-syntax
...
always-adj
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d063874f49 | ||
|
|
5d7b63ca87 | ||
|
|
29db144434 |
@@ -1667,8 +1667,10 @@ impl ContextEditor {
|
||||
});
|
||||
}
|
||||
|
||||
fn cursors(&self, cx: &AppContext) -> Vec<usize> {
|
||||
let selections = self.editor.read(cx).selections.all::<usize>(cx);
|
||||
fn cursors(&self, cx: &mut WindowContext) -> Vec<usize> {
|
||||
let selections = self
|
||||
.editor
|
||||
.update(cx, |editor, cx| editor.selections.all::<usize>(cx));
|
||||
selections
|
||||
.into_iter()
|
||||
.map(|selection| selection.head())
|
||||
@@ -2964,7 +2966,7 @@ impl ContextEditor {
|
||||
|
||||
let mut creases = vec![];
|
||||
editor.update(cx, |editor, cx| {
|
||||
let selections = editor.selections.all_adjusted(cx);
|
||||
let selections = editor.selections.all::<Point>(cx);
|
||||
let buffer = editor.buffer().read(cx).snapshot(cx);
|
||||
for selection in selections {
|
||||
let range = editor::ToOffset::to_offset(&selection.start, &buffer)
|
||||
|
||||
@@ -189,11 +189,16 @@ impl InlineAssistant {
|
||||
initial_prompt: Option<String>,
|
||||
cx: &mut WindowContext,
|
||||
) {
|
||||
let snapshot = editor.read(cx).buffer().read(cx).snapshot(cx);
|
||||
let (snapshot, initial_selections) = editor.update(cx, |editor, cx| {
|
||||
(
|
||||
editor.buffer().read(cx).snapshot(cx),
|
||||
editor.selections.all::<Point>(cx),
|
||||
)
|
||||
});
|
||||
|
||||
let mut selections = Vec::<Selection<Point>>::new();
|
||||
let mut newest_selection = None;
|
||||
for mut selection in editor.read(cx).selections.all::<Point>(cx) {
|
||||
for mut selection in initial_selections {
|
||||
if selection.end > selection.start {
|
||||
selection.start.column = 0;
|
||||
// If the selection ends at the start of the line, we don't want to include it.
|
||||
|
||||
@@ -1957,9 +1957,10 @@ async fn test_following_to_channel_notes_without_a_shared_project(
|
||||
});
|
||||
channel_notes_1_b.update(cx_b, |notes, cx| {
|
||||
assert_eq!(notes.channel(cx).unwrap().name, "channel-1");
|
||||
let editor = notes.editor.read(cx);
|
||||
assert_eq!(editor.text(cx), "Hello from A.");
|
||||
assert_eq!(editor.selections.ranges::<usize>(cx), &[3..4]);
|
||||
notes.editor.update(cx, |editor, cx| {
|
||||
assert_eq!(editor.text(cx), "Hello from A.");
|
||||
assert_eq!(editor.selections.ranges::<usize>(cx), &[3..4]);
|
||||
})
|
||||
});
|
||||
|
||||
// Client A opens the notes for channel 2.
|
||||
|
||||
@@ -3218,7 +3218,7 @@ impl Editor {
|
||||
return;
|
||||
}
|
||||
|
||||
let selections = self.selections.all_adjusted(cx);
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let mut bracket_inserted = false;
|
||||
let mut edits = Vec::new();
|
||||
let mut linked_edits = HashMap::<_, Vec<_>>::default();
|
||||
@@ -3731,7 +3731,7 @@ 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::<Point>(cx).into_iter().enumerate() {
|
||||
let cursor = selection.head();
|
||||
let row = cursor.row;
|
||||
|
||||
@@ -3789,7 +3789,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::<Point>(cx) {
|
||||
let cursor = selection.head();
|
||||
let row = cursor.row;
|
||||
|
||||
@@ -3860,7 +3860,7 @@ impl Editor {
|
||||
|
||||
let text: Arc<str> = text.into();
|
||||
self.transact(cx, |this, cx| {
|
||||
let old_selections = this.selections.all_adjusted(cx);
|
||||
let old_selections = this.selections.all::<Point>(cx);
|
||||
let selection_anchors = this.buffer.update(cx, |buffer, cx| {
|
||||
let anchors = {
|
||||
let snapshot = buffer.read(cx);
|
||||
@@ -5818,7 +5818,7 @@ impl Editor {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut selections = self.selections.all_adjusted(cx);
|
||||
let mut selections = self.selections.all::<Point>(cx);
|
||||
let buffer = self.buffer.read(cx);
|
||||
let snapshot = buffer.snapshot(cx);
|
||||
let rows_iter = selections.iter().map(|s| s.head().row);
|
||||
@@ -10392,7 +10392,7 @@ impl Editor {
|
||||
|
||||
let selections = self
|
||||
.selections
|
||||
.all_adjusted(cx)
|
||||
.all::<Point>(cx)
|
||||
.into_iter()
|
||||
.filter(|s| !s.is_empty())
|
||||
.collect_vec();
|
||||
@@ -10701,7 +10701,7 @@ impl Editor {
|
||||
pub fn fold(&mut self, _: &actions::Fold, cx: &mut ViewContext<Self>) {
|
||||
let mut fold_ranges = 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::<Point>(cx);
|
||||
|
||||
for selection in selections {
|
||||
let range = selection.range().sorted();
|
||||
@@ -10790,7 +10790,7 @@ impl Editor {
|
||||
pub fn fold_recursive(&mut self, _: &actions::FoldRecursive, cx: &mut ViewContext<Self>) {
|
||||
let mut fold_ranges = 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::<Point>(cx);
|
||||
|
||||
for selection in selections {
|
||||
let range = selection.range().sorted();
|
||||
@@ -12372,9 +12372,10 @@ impl Editor {
|
||||
return;
|
||||
};
|
||||
|
||||
let selections = self.selections.all::<usize>(cx);
|
||||
let buffer = self.buffer.read(cx);
|
||||
let mut new_selections_by_buffer = HashMap::default();
|
||||
for selection in self.selections.all::<usize>(cx) {
|
||||
for selection in selections {
|
||||
for (buffer, range, _) in
|
||||
buffer.range_to_buffer_ranges(selection.start..selection.end, cx)
|
||||
{
|
||||
@@ -12419,6 +12420,7 @@ impl Editor {
|
||||
}
|
||||
|
||||
fn open_excerpts_common(&mut self, split: bool, cx: &mut ViewContext<Self>) {
|
||||
let selections = self.selections.all::<usize>(cx);
|
||||
let buffer = self.buffer.read(cx);
|
||||
if buffer.is_singleton() {
|
||||
cx.propagate();
|
||||
@@ -12431,7 +12433,7 @@ impl Editor {
|
||||
};
|
||||
|
||||
let mut new_selections_by_buffer = HashMap::default();
|
||||
for selection in self.selections.all::<usize>(cx) {
|
||||
for selection in selections {
|
||||
for (mut buffer_handle, mut range, _) in
|
||||
buffer.range_to_buffer_ranges(selection.range(), cx)
|
||||
{
|
||||
@@ -12547,7 +12549,7 @@ impl Editor {
|
||||
fn selection_replacement_ranges(
|
||||
&self,
|
||||
range: Range<OffsetUtf16>,
|
||||
cx: &AppContext,
|
||||
cx: &mut AppContext,
|
||||
) -> Vec<Range<OffsetUtf16>> {
|
||||
let selections = self.selections.all::<OffsetUtf16>(cx);
|
||||
let newest_selection = selections
|
||||
|
||||
@@ -41,9 +41,9 @@ pub(super) fn refresh_linked_ranges(this: &mut Editor, cx: &mut ViewContext<Edit
|
||||
return None;
|
||||
}
|
||||
let project = this.project.clone()?;
|
||||
let selections = this.selections.all::<usize>(cx);
|
||||
let buffer = this.buffer.read(cx);
|
||||
let mut applicable_selections = vec![];
|
||||
let selections = this.selections.all::<usize>(cx);
|
||||
let snapshot = buffer.snapshot(cx);
|
||||
for selection in selections {
|
||||
let cursor_position = selection.head();
|
||||
|
||||
@@ -8,14 +8,15 @@ use std::{
|
||||
use collections::HashMap;
|
||||
use gpui::{AppContext, Model, Pixels};
|
||||
use itertools::Itertools;
|
||||
use language::{Bias, Point, Selection, SelectionGoal, TextDimension, ToPoint};
|
||||
use language::{Bias, Point, Selection, SelectionGoal, TextDimension};
|
||||
use multi_buffer::AnchorRangeExt as _;
|
||||
use util::post_inc;
|
||||
|
||||
use crate::{
|
||||
display_map::{DisplayMap, DisplaySnapshot, ToDisplayPoint},
|
||||
movement::TextLayoutDetails,
|
||||
Anchor, DisplayPoint, DisplayRow, ExcerptId, MultiBuffer, MultiBufferSnapshot, SelectMode,
|
||||
ToOffset,
|
||||
ToOffset, ToPoint,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -96,28 +97,68 @@ impl SelectionsCollection {
|
||||
|
||||
pub fn pending<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||
&self,
|
||||
cx: &AppContext,
|
||||
cx: &mut AppContext,
|
||||
) -> Option<Selection<D>> {
|
||||
self.pending_anchor()
|
||||
.as_ref()
|
||||
.map(|pending| pending.map(|p| p.summary::<D>(&self.buffer(cx))))
|
||||
let selection = self.pending_anchor()?;
|
||||
if self.line_mode {
|
||||
let map = self.display_map(cx);
|
||||
let range = selection.range().to_point(&map.buffer_snapshot);
|
||||
let expanded_range = map.expand_to_line(range);
|
||||
let mut endpoints = map
|
||||
.buffer_snapshot
|
||||
.dimensions_from_points::<D>([expanded_range.start, expanded_range.end]);
|
||||
let start = endpoints.next().unwrap();
|
||||
let end = endpoints.next().unwrap();
|
||||
Some(Selection {
|
||||
id: selection.id,
|
||||
start,
|
||||
end,
|
||||
reversed: selection.reversed,
|
||||
goal: selection.goal,
|
||||
})
|
||||
} else {
|
||||
Some(selection.map(|p| p.summary::<D>(&self.buffer(cx))))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn pending_mode(&self) -> Option<SelectMode> {
|
||||
self.pending.as_ref().map(|pending| pending.mode.clone())
|
||||
}
|
||||
|
||||
pub fn all<'a, D>(&self, cx: &AppContext) -> Vec<Selection<D>>
|
||||
pub fn all<'a, D>(&self, cx: &mut AppContext) -> Vec<Selection<D>>
|
||||
where
|
||||
D: 'a + TextDimension + Ord + Sub<D, Output = D>,
|
||||
{
|
||||
// todo!()
|
||||
// let mut selections = self.all::<Point>(cx);
|
||||
// if self.line_mode {
|
||||
// let map = self.display_map(cx);
|
||||
// for selection in &mut selections {
|
||||
// let new_range = map.expand_to_line(selection.range());
|
||||
// selection.start = new_range.start;
|
||||
// selection.end = new_range.end;
|
||||
// }
|
||||
// }
|
||||
let map = self.display_map(cx);
|
||||
let disjoint_anchors = &self.disjoint;
|
||||
let mut disjoint =
|
||||
resolve_multiple::<D, _>(disjoint_anchors.iter(), &self.buffer(cx)).peekable();
|
||||
let mut disjoint = resolve_multiple::<Point, _>(disjoint_anchors.iter(), &self.buffer(cx))
|
||||
.map(|mut selection| {
|
||||
if self.line_mode {
|
||||
let new_range = map.expand_to_line(selection.range());
|
||||
selection.start = new_range.start;
|
||||
selection.end = new_range.end;
|
||||
}
|
||||
// todo!(expand selection to encompass folds and blocks)
|
||||
// let start = map.display_point_to_point(map.point_to_display_point(selection.start, Bias::Left), Bias::Left);
|
||||
// let end = map.display_point_to_point(map.point_to_display_point(selection.end, Bias::Right), Bias::Right);
|
||||
selection
|
||||
})
|
||||
.peekable();
|
||||
|
||||
let mut pending_opt = self.pending::<D>(cx);
|
||||
let mut pending_opt = self.pending::<Point>(cx);
|
||||
|
||||
iter::from_fn(move || {
|
||||
// todo!(return merged selections)
|
||||
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 {
|
||||
@@ -140,23 +181,10 @@ impl SelectionsCollection {
|
||||
disjoint.next()
|
||||
}
|
||||
})
|
||||
// todo!("convert selections to D in a batched way")
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Returns all of the selections, adjusted to take into account the selection line_mode
|
||||
pub fn all_adjusted(&self, cx: &mut AppContext) -> Vec<Selection<Point>> {
|
||||
let mut selections = self.all::<Point>(cx);
|
||||
if self.line_mode {
|
||||
let map = self.display_map(cx);
|
||||
for selection in &mut selections {
|
||||
let new_range = map.expand_to_line(selection.range());
|
||||
selection.start = new_range.start;
|
||||
selection.end = new_range.end;
|
||||
}
|
||||
}
|
||||
selections
|
||||
}
|
||||
|
||||
/// Returns the newest selection, adjusted to take into account the selection line_mode
|
||||
pub fn newest_adjusted(&self, cx: &mut AppContext) -> Selection<Point> {
|
||||
let mut selection = self.newest::<Point>(cx);
|
||||
@@ -276,14 +304,14 @@ impl SelectionsCollection {
|
||||
|
||||
pub fn first<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||
&self,
|
||||
cx: &AppContext,
|
||||
cx: &mut AppContext,
|
||||
) -> Selection<D> {
|
||||
self.all(cx).first().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn last<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||
&self,
|
||||
cx: &AppContext,
|
||||
cx: &mut AppContext,
|
||||
) -> Selection<D> {
|
||||
self.all(cx).last().unwrap().clone()
|
||||
}
|
||||
@@ -298,7 +326,7 @@ impl SelectionsCollection {
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn ranges<D: TextDimension + Ord + Sub<D, Output = D> + std::fmt::Debug>(
|
||||
&self,
|
||||
cx: &AppContext,
|
||||
cx: &mut AppContext,
|
||||
) -> Vec<Range<D>> {
|
||||
self.all::<D>(cx)
|
||||
.iter()
|
||||
@@ -475,7 +503,7 @@ impl<'a> MutableSelectionsCollection<'a> {
|
||||
where
|
||||
T: 'a + ToOffset + ToPoint + TextDimension + Ord + Sub<T, Output = T> + std::marker::Copy,
|
||||
{
|
||||
let mut selections = self.all(self.cx);
|
||||
let mut selections = self.collection.all(self.cx);
|
||||
let mut start = range.start.to_offset(&self.buffer());
|
||||
let mut end = range.end.to_offset(&self.buffer());
|
||||
let reversed = if start > end {
|
||||
@@ -649,6 +677,7 @@ impl<'a> MutableSelectionsCollection<'a> {
|
||||
let mut changed = false;
|
||||
let display_map = self.display_map();
|
||||
let selections = self
|
||||
.collection
|
||||
.all::<Point>(self.cx)
|
||||
.into_iter()
|
||||
.map(|selection| {
|
||||
@@ -676,6 +705,7 @@ impl<'a> MutableSelectionsCollection<'a> {
|
||||
let mut changed = false;
|
||||
let snapshot = self.buffer().clone();
|
||||
let selections = self
|
||||
.collection
|
||||
.all::<usize>(self.cx)
|
||||
.into_iter()
|
||||
.map(|selection| {
|
||||
|
||||
@@ -242,7 +242,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::<Point>(cx);
|
||||
assert_eq!(
|
||||
all_selections.len(),
|
||||
1,
|
||||
@@ -317,7 +317,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::<Point>(cx);
|
||||
assert_eq!(
|
||||
all_selections.len(),
|
||||
1,
|
||||
|
||||
@@ -37,34 +37,34 @@ impl CursorPosition {
|
||||
}
|
||||
|
||||
fn update_position(&mut self, editor: View<Editor>, cx: &mut ViewContext<Self>) {
|
||||
let editor = editor.read(cx);
|
||||
let buffer = editor.buffer().read(cx).snapshot(cx);
|
||||
editor.update(cx, |editor, cx| {
|
||||
let buffer = editor.buffer().read(cx).snapshot(cx);
|
||||
|
||||
self.selected_count = Default::default();
|
||||
self.selected_count.selections = editor.selections.count();
|
||||
let mut last_selection: Option<Selection<usize>> = None;
|
||||
for selection in editor.selections.all::<usize>(cx) {
|
||||
self.selected_count.characters += buffer
|
||||
.text_for_range(selection.start..selection.end)
|
||||
.map(|t| t.chars().count())
|
||||
.sum::<usize>();
|
||||
if last_selection
|
||||
.as_ref()
|
||||
.map_or(true, |last_selection| selection.id > last_selection.id)
|
||||
{
|
||||
last_selection = Some(selection);
|
||||
}
|
||||
}
|
||||
for selection in editor.selections.all::<Point>(cx) {
|
||||
if selection.end != selection.start {
|
||||
self.selected_count.lines += (selection.end.row - selection.start.row) as usize;
|
||||
if selection.end.column != 0 {
|
||||
self.selected_count.lines += 1;
|
||||
self.selected_count = Default::default();
|
||||
self.selected_count.selections = editor.selections.count();
|
||||
let mut last_selection: Option<Selection<usize>> = None;
|
||||
for selection in editor.selections.all::<usize>(cx) {
|
||||
self.selected_count.characters += buffer
|
||||
.text_for_range(selection.start..selection.end)
|
||||
.map(|t| t.chars().count())
|
||||
.sum::<usize>();
|
||||
if last_selection
|
||||
.as_ref()
|
||||
.map_or(true, |last_selection| selection.id > last_selection.id)
|
||||
{
|
||||
last_selection = Some(selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.position = last_selection.map(|s| s.head().to_point(&buffer));
|
||||
|
||||
for selection in editor.selections.all::<Point>(cx) {
|
||||
if selection.end != selection.start {
|
||||
self.selected_count.lines += (selection.end.row - selection.start.row) as usize;
|
||||
if selection.end.column != 0 {
|
||||
self.selected_count.lines += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.position = last_selection.map(|s| s.head().to_point(&buffer));
|
||||
});
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,8 @@ impl GoToLine {
|
||||
}
|
||||
|
||||
pub fn new(active_editor: View<Editor>, cx: &mut ViewContext<Self>) -> Self {
|
||||
let editor = active_editor.read(cx);
|
||||
let cursor = editor.selections.last::<Point>(cx).head();
|
||||
let cursor =
|
||||
active_editor.update(cx, |editor, cx| editor.selections.last::<Point>(cx).head());
|
||||
|
||||
let line = cursor.row + 1;
|
||||
let column = cursor.column + 1;
|
||||
|
||||
@@ -128,12 +128,16 @@ impl SyntaxTreeView {
|
||||
fn editor_updated(&mut self, did_reparse: bool, cx: &mut ViewContext<Self>) -> Option<()> {
|
||||
// Find which excerpt the cursor is in, and the position within that excerpted buffer.
|
||||
let editor_state = self.editor.as_mut()?;
|
||||
let editor = &editor_state.editor.read(cx);
|
||||
let selection_range = editor.selections.last::<usize>(cx).range();
|
||||
let multibuffer = editor.buffer().read(cx);
|
||||
let (buffer, range, excerpt_id) = multibuffer
|
||||
.range_to_buffer_ranges(selection_range, cx)
|
||||
.pop()?;
|
||||
let (buffer, range, excerpt_id) = editor_state.editor.update(cx, |editor, cx| {
|
||||
let selection_range = editor.selections.last::<usize>(cx).range();
|
||||
Some(
|
||||
editor
|
||||
.buffer()
|
||||
.read(cx)
|
||||
.range_to_buffer_ranges(selection_range, cx)
|
||||
.pop()?,
|
||||
)
|
||||
})?;
|
||||
|
||||
// If the cursor has moved into a different excerpt, retrieve a new syntax layer
|
||||
// from that buffer.
|
||||
|
||||
@@ -301,8 +301,8 @@ impl MarkdownPreviewView {
|
||||
this.parse_markdown_from_active_editor(true, cx);
|
||||
}
|
||||
EditorEvent::SelectionsChanged { .. } => {
|
||||
let editor = editor.read(cx);
|
||||
let selection_range = editor.selections.last::<usize>(cx).range();
|
||||
let selection_range =
|
||||
editor.update(cx, |editor, cx| editor.selections.last::<usize>(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();
|
||||
|
||||
@@ -2937,6 +2937,58 @@ impl MultiBufferSnapshot {
|
||||
self.excerpts.summary().text.clone()
|
||||
}
|
||||
|
||||
pub fn dimensions_from_points<'a, D>(
|
||||
&'a self,
|
||||
points: impl 'a + IntoIterator<Item = Point>,
|
||||
) -> impl 'a + Iterator<Item = D>
|
||||
where
|
||||
D: TextDimension,
|
||||
{
|
||||
let mut cursor = self.excerpts.cursor::<TextSummary>(&());
|
||||
let mut memoized_source_start: Option<Point> = None;
|
||||
let mut points = points.into_iter();
|
||||
std::iter::from_fn(move || {
|
||||
let point = points.next()?;
|
||||
|
||||
// Clear the memoized source start if the point is in a different excerpt than previous.
|
||||
if memoized_source_start.map_or(false, |_| point >= cursor.end(&()).lines) {
|
||||
memoized_source_start = None;
|
||||
}
|
||||
|
||||
// Now determine where the excerpt containing the point starts in its source buffer.
|
||||
// We'll use this value to calculate overshoot next.
|
||||
let source_start = if let Some(source_start) = memoized_source_start {
|
||||
source_start
|
||||
} else {
|
||||
cursor.seek_forward(&point, Bias::Right, &());
|
||||
if let Some(excerpt) = cursor.item() {
|
||||
let source_start = excerpt.range.context.start.to_point(&excerpt.buffer);
|
||||
memoized_source_start = Some(source_start);
|
||||
source_start
|
||||
} else {
|
||||
return Some(D::from_text_summary(cursor.start()));
|
||||
}
|
||||
};
|
||||
|
||||
// First, assume the output dimension is at least the start of the excerpt containing the point
|
||||
let mut output = D::from_text_summary(cursor.start());
|
||||
|
||||
// If the point lands within its excerpt, calculate and add the overshoot in dimension D.
|
||||
if let Some(excerpt) = cursor.item() {
|
||||
let overshoot = point - cursor.start().lines;
|
||||
if !overshoot.is_zero() {
|
||||
let end_in_excerpt = source_start + overshoot;
|
||||
output.add_assign(
|
||||
&excerpt
|
||||
.buffer
|
||||
.text_summary_for_range::<D, _>(source_start..end_in_excerpt),
|
||||
);
|
||||
}
|
||||
}
|
||||
Some(output)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn text_summary_for_range<D, O>(&self, range: Range<O>) -> D
|
||||
where
|
||||
D: TextDimension,
|
||||
@@ -4706,6 +4758,12 @@ impl<'a> sum_tree::SeekTarget<'a, ExcerptSummary, ExcerptSummary> for usize {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> sum_tree::SeekTarget<'a, ExcerptSummary, TextSummary> for Point {
|
||||
fn cmp(&self, cursor_location: &TextSummary, _: &()) -> cmp::Ordering {
|
||||
Ord::cmp(self, &cursor_location.lines)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> sum_tree::SeekTarget<'a, ExcerptSummary, Option<&'a Locator>> for Locator {
|
||||
fn cmp(&self, cursor_location: &Option<&'a Locator>, _: &()) -> cmp::Ordering {
|
||||
Ord::cmp(&Some(self), cursor_location)
|
||||
|
||||
@@ -46,7 +46,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::<Point>(cx) {
|
||||
if !selection.is_empty()
|
||||
&& (vim.mode != Mode::VisualBlock || new_anchors.is_empty())
|
||||
{
|
||||
|
||||
@@ -79,7 +79,7 @@ impl Vim {
|
||||
true,
|
||||
editor
|
||||
.selections
|
||||
.all_adjusted(cx)
|
||||
.all::<Point>(cx)
|
||||
.iter()
|
||||
.map(|s| s.range())
|
||||
.collect(),
|
||||
@@ -99,7 +99,7 @@ impl Vim {
|
||||
false,
|
||||
editor
|
||||
.selections
|
||||
.all_adjusted(cx)
|
||||
.all::<Point>(cx)
|
||||
.iter()
|
||||
.map(|s| s.range())
|
||||
.collect(),
|
||||
|
||||
Reference in New Issue
Block a user