Detailed changes
@@ -2325,6 +2325,7 @@ dependencies = [
"log",
"lsp",
"menu",
+ "multi_buffer",
"nanoid",
"node_runtime",
"notifications",
@@ -6282,6 +6283,7 @@ dependencies = [
"log",
"parking_lot",
"rand 0.8.5",
+ "serde",
"settings",
"smallvec",
"sum_tree",
@@ -11315,6 +11317,7 @@ dependencies = [
"language",
"log",
"lsp",
+ "multi_buffer",
"nvim-rs",
"parking_lot",
"regex",
@@ -18,7 +18,7 @@ use editor::{
},
scroll::{Autoscroll, AutoscrollStrategy},
Anchor, Editor, EditorElement, EditorEvent, EditorStyle, MultiBuffer, MultiBufferSnapshot,
- ToOffset as _, ToPoint,
+ RowExt, ToOffset as _, ToPoint,
};
use file_icons::FileIcons;
use fs::Fs;
@@ -32,6 +32,7 @@ use gpui::{
View, ViewContext, VisualContext, WeakModel, WeakView, WhiteSpace, WindowContext,
};
use language::{language_settings::SoftWrap, Buffer, LanguageRegistry, ToOffset as _};
+use multi_buffer::MultiBufferRow;
use parking_lot::Mutex;
use project::Project;
use search::{buffer_search::DivRegistrar, BufferSearchBar};
@@ -306,7 +307,7 @@ impl AssistantPanel {
if point_selection.end.column == 0 {
point_selection.end.row -= 1;
}
- point_selection.end.column = snapshot.line_len(point_selection.end.row);
+ point_selection.end.column = snapshot.line_len(MultiBufferRow(point_selection.end.row));
}
let codegen_kind = if point_selection.start == point_selection.end {
@@ -2168,7 +2169,7 @@ impl ConversationEditor {
let snapshot = editor.snapshot(cx);
let cursor_point = scroll_position.cursor.to_display_point(&snapshot);
let scroll_top =
- cursor_point.row() as f32 - scroll_position.offset_before_cursor.y;
+ cursor_point.row().as_f32() - scroll_position.offset_before_cursor.y;
editor.set_scroll_position(
point(scroll_position.offset_before_cursor.x, scroll_top),
cx,
@@ -2236,7 +2237,10 @@ impl ConversationEditor {
self.editor.update(cx, |editor, cx| {
let snapshot = editor.snapshot(cx);
let cursor = editor.selections.newest_anchor().head();
- let cursor_row = cursor.to_display_point(&snapshot.display_snapshot).row() as f32;
+ let cursor_row = cursor
+ .to_display_point(&snapshot.display_snapshot)
+ .row()
+ .as_f32();
let scroll_position = editor
.scroll_manager
.anchor()
@@ -7,6 +7,7 @@ use editor::{Anchor, MultiBuffer, MultiBufferSnapshot, ToOffset, ToPoint};
use futures::{channel::mpsc, SinkExt, Stream, StreamExt};
use gpui::{EventEmitter, Model, ModelContext, Task};
use language::{Rope, TransactionId};
+use multi_buffer::MultiBufferRow;
use std::{cmp, future, ops::Range};
pub enum Event {
@@ -100,7 +101,7 @@ impl Codegen {
.suggested_indents(selection_start.row..selection_start.row + 1, cx)
.into_values()
.next()
- .unwrap_or_else(|| snapshot.indent_size_for_line(selection_start.row));
+ .unwrap_or_else(|| snapshot.indent_size_for_line(MultiBufferRow(selection_start.row)));
let response = CompletionProvider::global(cx).complete(prompt);
self.generation = cx.spawn(|this, mut cx| {
@@ -90,6 +90,7 @@ language = { workspace = true, features = ["test-support"] }
live_kit_client = { workspace = true, features = ["test-support"] }
lsp = { workspace = true, features = ["test-support"] }
menu.workspace = true
+multi_buffer = { workspace = true, features = ["test-support"] }
node_runtime.workspace = true
notifications = { workspace = true, features = ["test-support"] }
pretty_assertions.workspace = true
@@ -9,6 +9,7 @@ use editor::{
ConfirmCodeAction, ConfirmCompletion, ConfirmRename, ContextMenuFirst, Redo, Rename,
RevertSelectedHunks, ToggleCodeActions, Undo,
},
+ display_map::DisplayRow,
test::{
editor_hunks,
editor_test_context::{AssertionContextManager, EditorTestContext},
@@ -24,6 +25,7 @@ use language::{
language_settings::{AllLanguageSettings, InlayHintSettings},
FakeLspAdapter,
};
+use multi_buffer::MultiBufferRow;
use project::{
project_settings::{InlineBlameSettings, ProjectSettings},
SERVER_PROGRESS_DEBOUNCE_TIMEOUT,
@@ -2114,14 +2116,30 @@ struct Row10;"#};
assert_eq!(
all_hunks,
vec![
- ("".to_string(), DiffHunkStatus::Added, 1..3),
- ("struct Row2;\n".to_string(), DiffHunkStatus::Removed, 4..4),
- ("struct Row5;\n".to_string(), DiffHunkStatus::Modified, 6..7),
- ("struct Row8;\n".to_string(), DiffHunkStatus::Removed, 9..9),
+ (
+ "".to_string(),
+ DiffHunkStatus::Added,
+ DisplayRow(1)..DisplayRow(3)
+ ),
+ (
+ "struct Row2;\n".to_string(),
+ DiffHunkStatus::Removed,
+ DisplayRow(4)..DisplayRow(4)
+ ),
+ (
+ "struct Row5;\n".to_string(),
+ DiffHunkStatus::Modified,
+ DisplayRow(6)..DisplayRow(7)
+ ),
+ (
+ "struct Row8;\n".to_string(),
+ DiffHunkStatus::Removed,
+ DisplayRow(9)..DisplayRow(9)
+ ),
(
"struct Row10;".to_string(),
DiffHunkStatus::Modified,
- 10..10,
+ DisplayRow(10)..DisplayRow(10),
),
]
);
@@ -2133,23 +2151,35 @@ struct Row10;"#};
let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx);
assert_eq!(
expanded_hunks_background_highlights(editor, cx),
- vec![1..=2, 8..=8],
+ vec![DisplayRow(1)..=DisplayRow(2), DisplayRow(8)..=DisplayRow(8)],
);
assert_eq!(
all_hunks,
vec![
- ("".to_string(), DiffHunkStatus::Added, 1..3),
- ("struct Row2;\n".to_string(), DiffHunkStatus::Removed, 5..5),
- ("struct Row5;\n".to_string(), DiffHunkStatus::Modified, 8..9),
+ (
+ "".to_string(),
+ DiffHunkStatus::Added,
+ DisplayRow(1)..DisplayRow(3)
+ ),
+ (
+ "struct Row2;\n".to_string(),
+ DiffHunkStatus::Removed,
+ DisplayRow(5)..DisplayRow(5)
+ ),
+ (
+ "struct Row5;\n".to_string(),
+ DiffHunkStatus::Modified,
+ DisplayRow(8)..DisplayRow(9)
+ ),
(
"struct Row8;\n".to_string(),
DiffHunkStatus::Removed,
- 12..12
+ DisplayRow(12)..DisplayRow(12)
),
(
"struct Row10;".to_string(),
DiffHunkStatus::Modified,
- 13..13,
+ DisplayRow(13)..DisplayRow(13),
),
]
);
@@ -2173,7 +2203,7 @@ struct Row10;"#};
vec![(
"struct Row10;".to_string(),
DiffHunkStatus::Modified,
- 10..10,
+ DisplayRow(10)..DisplayRow(10),
)]
);
assert_eq!(all_expanded_hunks, Vec::new());
@@ -2184,14 +2214,14 @@ struct Row10;"#};
let all_expanded_hunks = expanded_hunks(&editor, &snapshot, cx);
assert_eq!(
expanded_hunks_background_highlights(editor, cx),
- vec![5..=5]
+ vec![DisplayRow(5)..=DisplayRow(5)]
);
assert_eq!(
all_hunks,
vec![(
"struct Row10;".to_string(),
DiffHunkStatus::Modified,
- 10..10,
+ DisplayRow(10)..DisplayRow(10),
)]
);
assert_eq!(all_expanded_hunks, Vec::new());
@@ -2330,7 +2360,7 @@ async fn test_git_blame_is_forwarded(cx_a: &mut TestAppContext, cx_b: &mut TestA
let blame = editor_b.blame().expect("editor_b should have blame now");
let entries = blame.update(cx, |blame, cx| {
blame
- .blame_for_rows((0..4).map(Some), cx)
+ .blame_for_rows((0..4).map(MultiBufferRow).map(Some), cx)
.collect::<Vec<_>>()
});
@@ -2369,7 +2399,7 @@ async fn test_git_blame_is_forwarded(cx_a: &mut TestAppContext, cx_b: &mut TestA
let blame = editor_b.blame().expect("editor_b should have blame now");
let entries = blame.update(cx, |blame, cx| {
blame
- .blame_for_rows((0..4).map(Some), cx)
+ .blame_for_rows((0..4).map(MultiBufferRow).map(Some), cx)
.collect::<Vec<_>>()
});
@@ -2396,7 +2426,7 @@ async fn test_git_blame_is_forwarded(cx_a: &mut TestAppContext, cx_b: &mut TestA
let blame = editor_b.blame().expect("editor_b should have blame now");
let entries = blame.update(cx, |blame, cx| {
blame
- .blame_for_rows((0..4).map(Some), cx)
+ .blame_for_rows((0..4).map(MultiBufferRow).map(Some), cx)
.collect::<Vec<_>>()
});
@@ -1,7 +1,7 @@
use super::*;
use collections::HashMap;
use editor::{
- display_map::{BlockContext, TransformBlock},
+ display_map::{BlockContext, DisplayRow, TransformBlock},
DisplayPoint, GutterDimensions,
};
use gpui::{px, AvailableSpace, Stateful, TestAppContext, VisualTestContext};
@@ -158,11 +158,11 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
assert_eq!(
editor_blocks(&editor, cx),
[
- (0, "path header block".into()),
- (2, "diagnostic header".into()),
- (15, "collapsed context".into()),
- (16, "diagnostic header".into()),
- (25, "collapsed context".into()),
+ (DisplayRow(0), "path header block".into()),
+ (DisplayRow(2), "diagnostic header".into()),
+ (DisplayRow(15), "collapsed context".into()),
+ (DisplayRow(16), "diagnostic header".into()),
+ (DisplayRow(25), "collapsed context".into()),
]
);
assert_eq!(
@@ -210,7 +210,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
editor.update(cx, |editor, cx| {
assert_eq!(
editor.selections.display_ranges(cx),
- [DisplayPoint::new(12, 6)..DisplayPoint::new(12, 6)]
+ [DisplayPoint::new(DisplayRow(12), 6)..DisplayPoint::new(DisplayRow(12), 6)]
);
});
@@ -243,13 +243,13 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
assert_eq!(
editor_blocks(&editor, cx),
[
- (0, "path header block".into()),
- (2, "diagnostic header".into()),
- (7, "path header block".into()),
- (9, "diagnostic header".into()),
- (22, "collapsed context".into()),
- (23, "diagnostic header".into()),
- (32, "collapsed context".into()),
+ (DisplayRow(0), "path header block".into()),
+ (DisplayRow(2), "diagnostic header".into()),
+ (DisplayRow(7), "path header block".into()),
+ (DisplayRow(9), "diagnostic header".into()),
+ (DisplayRow(22), "collapsed context".into()),
+ (DisplayRow(23), "diagnostic header".into()),
+ (DisplayRow(32), "collapsed context".into()),
]
);
@@ -309,7 +309,7 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
editor.update(cx, |editor, cx| {
assert_eq!(
editor.selections.display_ranges(cx),
- [DisplayPoint::new(19, 6)..DisplayPoint::new(19, 6)]
+ [DisplayPoint::new(DisplayRow(19), 6)..DisplayPoint::new(DisplayRow(19), 6)]
);
});
@@ -355,15 +355,15 @@ async fn test_diagnostics(cx: &mut TestAppContext) {
assert_eq!(
editor_blocks(&editor, cx),
[
- (0, "path header block".into()),
- (2, "diagnostic header".into()),
- (7, "collapsed context".into()),
- (8, "diagnostic header".into()),
- (13, "path header block".into()),
- (15, "diagnostic header".into()),
- (28, "collapsed context".into()),
- (29, "diagnostic header".into()),
- (38, "collapsed context".into()),
+ (DisplayRow(0), "path header block".into()),
+ (DisplayRow(2), "diagnostic header".into()),
+ (DisplayRow(7), "collapsed context".into()),
+ (DisplayRow(8), "diagnostic header".into()),
+ (DisplayRow(13), "path header block".into()),
+ (DisplayRow(15), "diagnostic header".into()),
+ (DisplayRow(28), "collapsed context".into()),
+ (DisplayRow(29), "diagnostic header".into()),
+ (DisplayRow(38), "collapsed context".into()),
]
);
@@ -493,8 +493,8 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
assert_eq!(
editor_blocks(&editor, cx),
[
- (0, "path header block".into()),
- (2, "diagnostic header".into()),
+ (DisplayRow(0), "path header block".into()),
+ (DisplayRow(2), "diagnostic header".into()),
]
);
assert_eq!(
@@ -539,10 +539,10 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
assert_eq!(
editor_blocks(&editor, cx),
[
- (0, "path header block".into()),
- (2, "diagnostic header".into()),
- (6, "collapsed context".into()),
- (7, "diagnostic header".into()),
+ (DisplayRow(0), "path header block".into()),
+ (DisplayRow(2), "diagnostic header".into()),
+ (DisplayRow(6), "collapsed context".into()),
+ (DisplayRow(7), "diagnostic header".into()),
]
);
assert_eq!(
@@ -605,10 +605,10 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
assert_eq!(
editor_blocks(&editor, cx),
[
- (0, "path header block".into()),
- (2, "diagnostic header".into()),
- (7, "collapsed context".into()),
- (8, "diagnostic header".into()),
+ (DisplayRow(0), "path header block".into()),
+ (DisplayRow(2), "diagnostic header".into()),
+ (DisplayRow(7), "collapsed context".into()),
+ (DisplayRow(8), "diagnostic header".into()),
]
);
assert_eq!(
@@ -661,10 +661,10 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) {
assert_eq!(
editor_blocks(&editor, cx),
[
- (0, "path header block".into()),
- (2, "diagnostic header".into()),
- (7, "collapsed context".into()),
- (8, "diagnostic header".into()),
+ (DisplayRow(0), "path header block".into()),
+ (DisplayRow(2), "diagnostic header".into()),
+ (DisplayRow(7), "collapsed context".into()),
+ (DisplayRow(8), "diagnostic header".into()),
]
);
assert_eq!(
@@ -958,14 +958,17 @@ fn random_diagnostic(
}
}
-fn editor_blocks(editor: &View<Editor>, cx: &mut VisualTestContext) -> Vec<(u32, SharedString)> {
+fn editor_blocks(
+ editor: &View<Editor>,
+ cx: &mut VisualTestContext,
+) -> Vec<(DisplayRow, SharedString)> {
let mut blocks = Vec::new();
cx.draw(gpui::Point::default(), AvailableSpace::min_size(), |cx| {
editor.update(cx, |editor, cx| {
let snapshot = editor.snapshot(cx);
blocks.extend(
snapshot
- .blocks_in_range(0..snapshot.max_point().row())
+ .blocks_in_range(DisplayRow(0)..snapshot.max_point().row())
.enumerate()
.filter_map(|(ix, (row, block))| {
let name: SharedString = match block {
@@ -54,7 +54,7 @@ pub struct SelectToEndOfLine {
pub struct ToggleCodeActions {
// Display row from which the action was deployed.
#[serde(default)]
- pub deployed_from_indicator: Option<u32>,
+ pub deployed_from_indicator: Option<DisplayRow>,
}
#[derive(PartialEq, Clone, Deserialize, Default)]
@@ -77,12 +77,12 @@ pub struct ToggleComments {
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct FoldAt {
- pub buffer_row: u32,
+ pub buffer_row: MultiBufferRow,
}
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct UnfoldAt {
- pub buffer_row: u32,
+ pub buffer_row: MultiBufferRow,
}
#[derive(PartialEq, Clone, Deserialize, Default)]
@@ -23,8 +23,8 @@ mod inlay_map;
mod tab_map;
mod wrap_map;
-use crate::EditorStyle;
use crate::{hover_links::InlayHighlight, movement::TextLayoutDetails, InlayId};
+use crate::{EditorStyle, RowExt};
pub use block_map::{BlockMap, BlockPoint};
use collections::{HashMap, HashSet};
use fold_map::FoldMap;
@@ -34,7 +34,11 @@ use language::{
language_settings::language_settings, OffsetUtf16, Point, Subscription as BufferSubscription,
};
use lsp::DiagnosticSeverity;
-use multi_buffer::{Anchor, AnchorRangeExt, MultiBuffer, MultiBufferSnapshot, ToOffset, ToPoint};
+use multi_buffer::{
+ Anchor, AnchorRangeExt, MultiBuffer, MultiBufferPoint, MultiBufferRow, MultiBufferSnapshot,
+ ToOffset, ToPoint,
+};
+use serde::Deserialize;
use std::{any::TypeId, borrow::Cow, fmt::Debug, num::NonZeroU32, ops::Range, sync::Arc};
use sum_tree::{Bias, TreeMap};
use tab_map::TabMap;
@@ -42,10 +46,11 @@ use tab_map::TabMap;
use wrap_map::WrapMap;
pub use block_map::{
- BlockBufferRows as DisplayBufferRows, BlockChunks as DisplayChunks, BlockContext,
- BlockDisposition, BlockId, BlockProperties, BlockStyle, RenderBlock, TransformBlock,
+ BlockBufferRows, BlockChunks as DisplayChunks, BlockContext, BlockDisposition, BlockId,
+ BlockProperties, BlockStyle, RenderBlock, TransformBlock,
};
+use self::block_map::BlockRow;
pub use self::fold_map::{Fold, FoldId, FoldPoint};
pub use self::inlay_map::{InlayOffset, InlayPoint};
pub(crate) use inlay_map::Inlay;
@@ -65,6 +70,17 @@ pub trait ToDisplayPoint {
type TextHighlights = TreeMap<Option<TypeId>, Arc<(HighlightStyle, Vec<Range<Anchor>>)>>;
type InlayHighlights = TreeMap<TypeId, TreeMap<InlayId, (HighlightStyle, InlayHighlight)>>;
+#[derive(Clone)]
+pub struct DisplayBufferRows<'a>(BlockBufferRows<'a>);
+
+impl<'a> Iterator for DisplayBufferRows<'a> {
+ type Item = Option<DisplayRow>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next().map(|row| row.map(|r| DisplayRow(r.0)))
+ }
+}
+
/// Decides how text in a [`MultiBuffer`] should be displayed in a buffer, handling inlay hints,
/// folding, hard tabs, soft wrapping, custom blocks (like diagnostics), and highlighting.
///
@@ -382,15 +398,15 @@ impl DisplaySnapshot {
self.buffer_snapshot.len() == 0
}
- pub fn buffer_rows(&self, start_row: u32) -> DisplayBufferRows {
- self.block_snapshot.buffer_rows(start_row)
+ pub fn display_rows(&self, start_row: DisplayRow) -> DisplayBufferRows {
+ DisplayBufferRows(self.block_snapshot.buffer_rows(BlockRow(start_row.0)))
}
- pub fn max_buffer_row(&self) -> u32 {
+ pub fn max_buffer_row(&self) -> MultiBufferRow {
self.buffer_snapshot.max_buffer_row()
}
- pub fn prev_line_boundary(&self, mut point: Point) -> (Point, DisplayPoint) {
+ pub fn prev_line_boundary(&self, mut point: MultiBufferPoint) -> (Point, DisplayPoint) {
loop {
let mut inlay_point = self.inlay_snapshot.to_inlay_point(point);
let mut fold_point = self.fold_snapshot.to_fold_point(inlay_point, Bias::Left);
@@ -408,7 +424,7 @@ impl DisplaySnapshot {
}
}
- pub fn next_line_boundary(&self, mut point: Point) -> (Point, DisplayPoint) {
+ pub fn next_line_boundary(&self, mut point: MultiBufferPoint) -> (Point, DisplayPoint) {
loop {
let mut inlay_point = self.inlay_snapshot.to_inlay_point(point);
let mut fold_point = self.fold_snapshot.to_fold_point(inlay_point, Bias::Right);
@@ -429,13 +445,14 @@ impl DisplaySnapshot {
// used by line_mode selections and tries to match vim behaviour
pub fn expand_to_line(&self, range: Range<Point>) -> Range<Point> {
let new_start = if range.start.row == 0 {
- Point::new(0, 0)
- } else if range.start.row == self.max_buffer_row()
- || (range.end.column > 0 && range.end.row == self.max_buffer_row())
+ MultiBufferPoint::new(0, 0)
+ } else if range.start.row == self.max_buffer_row().0
+ || (range.end.column > 0 && range.end.row == self.max_buffer_row().0)
{
- Point::new(
+ MultiBufferPoint::new(
range.start.row - 1,
- self.buffer_snapshot.line_len(range.start.row - 1),
+ self.buffer_snapshot
+ .line_len(MultiBufferRow(range.start.row - 1)),
)
} else {
self.prev_line_boundary(range.start).0
@@ -443,9 +460,9 @@ impl DisplaySnapshot {
let new_end = if range.end.column == 0 {
range.end
- } else if range.end.row < self.max_buffer_row() {
+ } else if range.end.row < self.max_buffer_row().0 {
self.buffer_snapshot
- .clip_point(Point::new(range.end.row + 1, 0), Bias::Left)
+ .clip_point(MultiBufferPoint::new(range.end.row + 1, 0), Bias::Left)
} else {
self.buffer_snapshot.max_point()
};
@@ -453,7 +470,7 @@ impl DisplaySnapshot {
new_start..new_end
}
- fn point_to_display_point(&self, point: Point, bias: Bias) -> DisplayPoint {
+ fn point_to_display_point(&self, point: MultiBufferPoint, bias: Bias) -> DisplayPoint {
let inlay_point = self.inlay_snapshot.to_inlay_point(point);
let fold_point = self.fold_snapshot.to_fold_point(inlay_point, bias);
let tab_point = self.tab_snapshot.to_tab_point(fold_point);
@@ -509,10 +526,10 @@ impl DisplaySnapshot {
}
/// Returns text chunks starting at the given display row until the end of the file
- pub fn text_chunks(&self, display_row: u32) -> impl Iterator<Item = &str> {
+ pub fn text_chunks(&self, display_row: DisplayRow) -> impl Iterator<Item = &str> {
self.block_snapshot
.chunks(
- display_row..self.max_point().row() + 1,
+ display_row.0..self.max_point().row().next_row().0,
false,
Highlights::default(),
)
@@ -520,8 +537,8 @@ impl DisplaySnapshot {
}
/// Returns text chunks starting at the end of the given display row in reverse until the start of the file
- pub fn reverse_text_chunks(&self, display_row: u32) -> impl Iterator<Item = &str> {
- (0..=display_row).rev().flat_map(|row| {
+ pub fn reverse_text_chunks(&self, display_row: DisplayRow) -> impl Iterator<Item = &str> {
+ (0..=display_row.0).rev().flat_map(|row| {
self.block_snapshot
.chunks(row..row + 1, false, Highlights::default())
.map(|h| h.text)
@@ -533,12 +550,12 @@ impl DisplaySnapshot {
pub fn chunks(
&self,
- display_rows: Range<u32>,
+ display_rows: Range<DisplayRow>,
language_aware: bool,
highlight_styles: HighlightStyles,
) -> DisplayChunks<'_> {
self.block_snapshot.chunks(
- display_rows,
+ display_rows.start.0..display_rows.end.0,
language_aware,
Highlights {
text_highlights: Some(&self.text_highlights),
@@ -550,7 +567,7 @@ impl DisplaySnapshot {
pub fn highlighted_chunks<'a>(
&'a self,
- display_rows: Range<u32>,
+ display_rows: Range<DisplayRow>,
language_aware: bool,
editor_style: &'a EditorStyle,
) -> impl Iterator<Item = HighlightedChunk<'a>> {
@@ -610,7 +627,7 @@ impl DisplaySnapshot {
pub fn layout_row(
&self,
- display_row: u32,
+ display_row: DisplayRow,
TextLayoutDetails {
text_system,
editor_style,
@@ -623,7 +640,7 @@ impl DisplaySnapshot {
let mut runs = Vec::new();
let mut line = String::new();
- let range = display_row..display_row + 1;
+ let range = display_row..display_row.next_row();
for chunk in self.highlighted_chunks(range, false, &editor_style) {
line.push_str(chunk.chunk);
@@ -663,7 +680,7 @@ impl DisplaySnapshot {
pub fn display_column_for_x(
&self,
- display_row: u32,
+ display_row: DisplayRow,
x: Pixels,
details: &TextLayoutDetails,
) -> u32 {
@@ -732,7 +749,7 @@ impl DisplaySnapshot {
pub fn clip_at_line_end(&self, point: DisplayPoint) -> DisplayPoint {
let mut point = point.0;
- if point.column == self.line_len(point.row) {
+ if point.column == self.line_len(DisplayRow(point.row)) {
point.column = point.column.saturating_sub(1);
point = self.block_snapshot.clip_point(point, Bias::Left);
}
@@ -748,36 +765,38 @@ impl DisplaySnapshot {
pub fn blocks_in_range(
&self,
- rows: Range<u32>,
- ) -> impl Iterator<Item = (u32, &TransformBlock)> {
- self.block_snapshot.blocks_in_range(rows)
+ rows: Range<DisplayRow>,
+ ) -> impl Iterator<Item = (DisplayRow, &TransformBlock)> {
+ self.block_snapshot
+ .blocks_in_range(rows.start.0..rows.end.0)
+ .map(|(row, block)| (DisplayRow(row), block))
}
pub fn intersects_fold<T: ToOffset>(&self, offset: T) -> bool {
self.fold_snapshot.intersects_fold(offset)
}
- pub fn is_line_folded(&self, buffer_row: u32) -> bool {
+ pub fn is_line_folded(&self, buffer_row: MultiBufferRow) -> bool {
self.fold_snapshot.is_line_folded(buffer_row)
}
- pub fn is_block_line(&self, display_row: u32) -> bool {
- self.block_snapshot.is_block_line(display_row)
+ pub fn is_block_line(&self, display_row: DisplayRow) -> bool {
+ self.block_snapshot.is_block_line(BlockRow(display_row.0))
}
- pub fn soft_wrap_indent(&self, display_row: u32) -> Option<u32> {
+ pub fn soft_wrap_indent(&self, display_row: DisplayRow) -> Option<u32> {
let wrap_row = self
.block_snapshot
- .to_wrap_point(BlockPoint::new(display_row, 0))
+ .to_wrap_point(BlockPoint::new(display_row.0, 0))
.row();
self.wrap_snapshot.soft_wrap_indent(wrap_row)
}
pub fn text(&self) -> String {
- self.text_chunks(0).collect()
+ self.text_chunks(DisplayRow(0)).collect()
}
- pub fn line(&self, display_row: u32) -> String {
+ pub fn line(&self, display_row: DisplayRow) -> String {
let mut result = String::new();
for chunk in self.text_chunks(display_row) {
if let Some(ix) = chunk.find('\n') {
@@ -790,7 +809,7 @@ impl DisplaySnapshot {
result
}
- pub fn line_indent_for_buffer_row(&self, buffer_row: u32) -> (u32, bool) {
+ pub fn line_indent_for_buffer_row(&self, buffer_row: MultiBufferRow) -> (u32, bool) {
let (buffer, range) = self
.buffer_snapshot
.buffer_line_for_row(buffer_row)
@@ -812,15 +831,15 @@ impl DisplaySnapshot {
(indent_size, is_blank)
}
- pub fn line_len(&self, row: u32) -> u32 {
- self.block_snapshot.line_len(row)
+ pub fn line_len(&self, row: DisplayRow) -> u32 {
+ self.block_snapshot.line_len(BlockRow(row.0))
}
- pub fn longest_row(&self) -> u32 {
- self.block_snapshot.longest_row()
+ pub fn longest_row(&self) -> DisplayRow {
+ DisplayRow(self.block_snapshot.longest_row())
}
- pub fn fold_for_line(&self, buffer_row: u32) -> Option<FoldStatus> {
+ pub fn fold_for_line(&self, buffer_row: MultiBufferRow) -> Option<FoldStatus> {
if self.is_line_folded(buffer_row) {
Some(FoldStatus::Folded)
} else if self.is_foldable(buffer_row) {
@@ -830,7 +849,7 @@ impl DisplaySnapshot {
}
}
- pub fn is_foldable(&self, buffer_row: u32) -> bool {
+ pub fn is_foldable(&self, buffer_row: MultiBufferRow) -> bool {
let max_row = self.buffer_snapshot.max_buffer_row();
if buffer_row >= max_row {
return false;
@@ -841,8 +860,9 @@ impl DisplaySnapshot {
return false;
}
- for next_row in (buffer_row + 1)..=max_row {
- let (next_indent_size, next_line_is_blank) = self.line_indent_for_buffer_row(next_row);
+ for next_row in (buffer_row.0 + 1)..=max_row.0 {
+ let (next_indent_size, next_line_is_blank) =
+ self.line_indent_for_buffer_row(MultiBufferRow(next_row));
if next_indent_size > indent_size {
return true;
} else if !next_line_is_blank {
@@ -853,20 +873,22 @@ impl DisplaySnapshot {
false
}
- pub fn foldable_range(&self, buffer_row: u32) -> Option<Range<Point>> {
- let start = Point::new(buffer_row, self.buffer_snapshot.line_len(buffer_row));
- if self.is_foldable(start.row) && !self.is_line_folded(start.row) {
+ pub fn foldable_range(&self, buffer_row: MultiBufferRow) -> Option<Range<Point>> {
+ let start = MultiBufferPoint::new(buffer_row.0, self.buffer_snapshot.line_len(buffer_row));
+ if self.is_foldable(MultiBufferRow(start.row))
+ && !self.is_line_folded(MultiBufferRow(start.row))
+ {
let (start_indent, _) = self.line_indent_for_buffer_row(buffer_row);
let max_point = self.buffer_snapshot.max_point();
let mut end = None;
- for row in (buffer_row + 1)..=max_point.row {
- let (indent, is_blank) = self.line_indent_for_buffer_row(row);
+ for row in (buffer_row.0 + 1)..=max_point.row {
+ let (indent, is_blank) = self.line_indent_for_buffer_row(MultiBufferRow(row));
if !is_blank && indent <= start_indent {
let prev_row = row - 1;
end = Some(Point::new(
prev_row,
- self.buffer_snapshot.line_len(prev_row),
+ self.buffer_snapshot.line_len(MultiBufferRow(prev_row)),
));
break;
}
@@ -903,27 +925,31 @@ impl Debug for DisplayPoint {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!(
"DisplayPoint({}, {})",
- self.row(),
+ self.row().0,
self.column()
))
}
}
+#[derive(Debug, Copy, Clone, Default, Eq, Ord, PartialOrd, PartialEq, Deserialize, Hash)]
+#[serde(transparent)]
+pub struct DisplayRow(pub u32);
+
impl DisplayPoint {
- pub fn new(row: u32, column: u32) -> Self {
- Self(BlockPoint(Point::new(row, column)))
+ pub fn new(row: DisplayRow, column: u32) -> Self {
+ Self(BlockPoint(Point::new(row.0, column)))
}
pub fn zero() -> Self {
- Self::new(0, 0)
+ Self::new(DisplayRow(0), 0)
}
pub fn is_zero(&self) -> bool {
self.0.is_zero()
}
- pub fn row(self) -> u32 {
- self.0.row
+ pub fn row(self) -> DisplayRow {
+ DisplayRow(self.0.row)
}
pub fn column(self) -> u32 {
@@ -1171,7 +1197,7 @@ pub mod tests {
let buffer = &snapshot.buffer_snapshot;
for _ in 0..5 {
let row = rng.gen_range(0..=buffer.max_point().row);
- let column = rng.gen_range(0..=buffer.line_len(row));
+ let column = rng.gen_range(0..=buffer.line_len(MultiBufferRow(row)));
let point = buffer.clip_point(Point::new(row, column), Left);
let (prev_buffer_bound, prev_display_bound) = snapshot.prev_line_boundary(point);
@@ -1216,12 +1242,12 @@ pub mod tests {
}
// Movement
- let min_point = snapshot.clip_point(DisplayPoint::new(0, 0), Left);
+ let min_point = snapshot.clip_point(DisplayPoint::new(DisplayRow(0), 0), Left);
let max_point = snapshot.clip_point(snapshot.max_point(), Right);
for _ in 0..5 {
- let row = rng.gen_range(0..=snapshot.max_point().row());
- let column = rng.gen_range(0..=snapshot.line_len(row));
- let point = snapshot.clip_point(DisplayPoint::new(row, column), Left);
+ let row = rng.gen_range(0..=snapshot.max_point().row().0);
+ let column = rng.gen_range(0..=snapshot.line_len(DisplayRow(row)));
+ let point = snapshot.clip_point(DisplayPoint::new(DisplayRow(row), column), Left);
log::info!("Moving from point {:?}", point);
@@ -1288,63 +1314,64 @@ pub mod tests {
let snapshot = map.update(cx, |map, cx| map.snapshot(cx));
assert_eq!(
- snapshot.text_chunks(0).collect::<String>(),
+ snapshot.text_chunks(DisplayRow(0)).collect::<String>(),
"one two \nthree four \nfive\nsix seven \neight"
);
assert_eq!(
- snapshot.clip_point(DisplayPoint::new(0, 8), Bias::Left),
- DisplayPoint::new(0, 7)
+ snapshot.clip_point(DisplayPoint::new(DisplayRow(0), 8), Bias::Left),
+ DisplayPoint::new(DisplayRow(0), 7)
);
assert_eq!(
- snapshot.clip_point(DisplayPoint::new(0, 8), Bias::Right),
- DisplayPoint::new(1, 0)
+ snapshot.clip_point(DisplayPoint::new(DisplayRow(0), 8), Bias::Right),
+ DisplayPoint::new(DisplayRow(1), 0)
);
assert_eq!(
- movement::right(&snapshot, DisplayPoint::new(0, 7)),
- DisplayPoint::new(1, 0)
+ movement::right(&snapshot, DisplayPoint::new(DisplayRow(0), 7)),
+ DisplayPoint::new(DisplayRow(1), 0)
);
assert_eq!(
- movement::left(&snapshot, DisplayPoint::new(1, 0)),
- DisplayPoint::new(0, 7)
+ movement::left(&snapshot, DisplayPoint::new(DisplayRow(1), 0)),
+ DisplayPoint::new(DisplayRow(0), 7)
);
- let x = snapshot.x_for_display_point(DisplayPoint::new(1, 10), &text_layout_details);
+ let x = snapshot
+ .x_for_display_point(DisplayPoint::new(DisplayRow(1), 10), &text_layout_details);
assert_eq!(
movement::up(
&snapshot,
- DisplayPoint::new(1, 10),
+ DisplayPoint::new(DisplayRow(1), 10),
SelectionGoal::None,
false,
&text_layout_details,
),
(
- DisplayPoint::new(0, 7),
+ DisplayPoint::new(DisplayRow(0), 7),
SelectionGoal::HorizontalPosition(x.0)
)
);
assert_eq!(
movement::down(
&snapshot,
- DisplayPoint::new(0, 7),
+ DisplayPoint::new(DisplayRow(0), 7),
SelectionGoal::HorizontalPosition(x.0),
false,
&text_layout_details
),
(
- DisplayPoint::new(1, 10),
+ DisplayPoint::new(DisplayRow(1), 10),
SelectionGoal::HorizontalPosition(x.0)
)
);
assert_eq!(
movement::down(
&snapshot,
- DisplayPoint::new(1, 10),
+ DisplayPoint::new(DisplayRow(1), 10),
SelectionGoal::HorizontalPosition(x.0),
false,
&text_layout_details
),
(
- DisplayPoint::new(2, 4),
+ DisplayPoint::new(DisplayRow(2), 4),
SelectionGoal::HorizontalPosition(x.0)
)
);
@@ -1356,7 +1383,7 @@ pub mod tests {
let snapshot = map.update(cx, |map, cx| map.snapshot(cx));
assert_eq!(
- snapshot.text_chunks(1).collect::<String>(),
+ snapshot.text_chunks(DisplayRow(1)).collect::<String>(),
"three four \nfive\nsix and \nseven eight"
);
@@ -1367,7 +1394,7 @@ pub mod tests {
let snapshot = map.update(cx, |map, cx| map.snapshot(cx));
assert_eq!(
- snapshot.text_chunks(1).collect::<String>(),
+ snapshot.text_chunks(DisplayRow(1)).collect::<String>(),
"three \nfour five\nsix and \nseven \neight"
)
});
@@ -1388,9 +1415,18 @@ pub mod tests {
buffer.update(cx, |buffer, cx| {
buffer.edit(
vec![
- (Point::new(1, 0)..Point::new(1, 0), "\t"),
- (Point::new(1, 1)..Point::new(1, 1), "\t"),
- (Point::new(2, 1)..Point::new(2, 1), "\t"),
+ (
+ MultiBufferPoint::new(1, 0)..MultiBufferPoint::new(1, 0),
+ "\t",
+ ),
+ (
+ MultiBufferPoint::new(1, 1)..MultiBufferPoint::new(1, 1),
+ "\t",
+ ),
+ (
+ MultiBufferPoint::new(2, 1)..MultiBufferPoint::new(2, 1),
+ "\t",
+ ),
],
None,
cx,
@@ -1399,7 +1435,7 @@ pub mod tests {
assert_eq!(
map.update(cx, |map, cx| map.snapshot(cx))
- .text_chunks(1)
+ .text_chunks(DisplayRow(1))
.collect::<String>()
.lines()
.next(),
@@ -1407,7 +1443,7 @@ pub mod tests {
);
assert_eq!(
map.update(cx, |map, cx| map.snapshot(cx))
- .text_chunks(2)
+ .text_chunks(DisplayRow(2))
.collect::<String>()
.lines()
.next(),
@@ -1462,7 +1498,7 @@ pub mod tests {
let map = cx
.new_model(|cx| DisplayMap::new(buffer, font("Helvetica"), font_size, None, 1, 1, cx));
assert_eq!(
- cx.update(|cx| syntax_chunks(0..5, &map, &theme, cx)),
+ cx.update(|cx| syntax_chunks(DisplayRow(0)..DisplayRow(5), &map, &theme, cx)),
vec![
("fn ".to_string(), None),
("outer".to_string(), Some(Hsla::blue())),
@@ -1473,7 +1509,7 @@ pub mod tests {
]
);
assert_eq!(
- cx.update(|cx| syntax_chunks(3..5, &map, &theme, cx)),
+ cx.update(|cx| syntax_chunks(DisplayRow(3)..DisplayRow(5), &map, &theme, cx)),
vec![
(" fn ".to_string(), Some(Hsla::red())),
("inner".to_string(), Some(Hsla::blue())),
@@ -1482,10 +1518,13 @@ pub mod tests {
);
map.update(cx, |map, cx| {
- map.fold(vec![Point::new(0, 6)..Point::new(3, 2)], cx)
+ map.fold(
+ vec![MultiBufferPoint::new(0, 6)..MultiBufferPoint::new(3, 2)],
+ cx,
+ )
});
assert_eq!(
- cx.update(|cx| syntax_chunks(0..2, &map, &theme, cx)),
+ cx.update(|cx| syntax_chunks(DisplayRow(0)..DisplayRow(2), &map, &theme, cx)),
vec![
("fn ".to_string(), None),
("out".to_string(), Some(Hsla::blue())),
@@ -1548,7 +1587,7 @@ pub mod tests {
DisplayMap::new(buffer, font("Courier"), font_size, Some(px(40.0)), 1, 1, cx)
});
assert_eq!(
- cx.update(|cx| syntax_chunks(0..5, &map, &theme, cx)),
+ cx.update(|cx| syntax_chunks(DisplayRow(0)..DisplayRow(5), &map, &theme, cx)),
[
("fn \n".to_string(), None),
("oute\nr".to_string(), Some(Hsla::blue())),
@@ -1556,15 +1595,18 @@ pub mod tests {
]
);
assert_eq!(
- cx.update(|cx| syntax_chunks(3..5, &map, &theme, cx)),
+ cx.update(|cx| syntax_chunks(DisplayRow(3)..DisplayRow(5), &map, &theme, cx)),
[("{}\n\n".to_string(), None)]
);
map.update(cx, |map, cx| {
- map.fold(vec![Point::new(0, 6)..Point::new(3, 2)], cx)
+ map.fold(
+ vec![MultiBufferPoint::new(0, 6)..MultiBufferPoint::new(3, 2)],
+ cx,
+ )
});
assert_eq!(
- cx.update(|cx| syntax_chunks(1..4, &map, &theme, cx)),
+ cx.update(|cx| syntax_chunks(DisplayRow(1)..DisplayRow(4), &map, &theme, cx)),
[
("out".to_string(), Some(Hsla::blue())),
("āÆ\n".to_string(), None),
@@ -1636,7 +1678,7 @@ pub mod tests {
});
assert_eq!(
- cx.update(|cx| chunks(0..10, &map, &theme, cx)),
+ cx.update(|cx| chunks(DisplayRow(0)..DisplayRow(10), &map, &theme, cx)),
[
("const ".to_string(), None, None),
("a".to_string(), None, Some(Hsla::blue())),
@@ -1732,45 +1774,57 @@ pub mod tests {
let map = map.update(cx, |map, cx| map.snapshot(cx));
assert_eq!(map.text(), "ā
α\nβ \nšĪ² γ");
assert_eq!(
- map.text_chunks(0).collect::<String>(),
+ map.text_chunks(DisplayRow(0)).collect::<String>(),
"ā
α\nβ \nšĪ² γ"
);
- assert_eq!(map.text_chunks(1).collect::<String>(), "β \nšĪ² γ");
- assert_eq!(map.text_chunks(2).collect::<String>(), "šĪ² γ");
+ assert_eq!(
+ map.text_chunks(DisplayRow(1)).collect::<String>(),
+ "β \nšĪ² γ"
+ );
+ assert_eq!(
+ map.text_chunks(DisplayRow(2)).collect::<String>(),
+ "šĪ² γ"
+ );
- let point = Point::new(0, "ā
\t\t".len() as u32);
- let display_point = DisplayPoint::new(0, "ā
".len() as u32);
+ let point = MultiBufferPoint::new(0, "ā
\t\t".len() as u32);
+ let display_point = DisplayPoint::new(DisplayRow(0), "ā
".len() as u32);
assert_eq!(point.to_display_point(&map), display_point);
assert_eq!(display_point.to_point(&map), point);
- let point = Point::new(1, "β\t".len() as u32);
- let display_point = DisplayPoint::new(1, "β ".len() as u32);
+ let point = MultiBufferPoint::new(1, "β\t".len() as u32);
+ let display_point = DisplayPoint::new(DisplayRow(1), "β ".len() as u32);
assert_eq!(point.to_display_point(&map), display_point);
assert_eq!(display_point.to_point(&map), point,);
- let point = Point::new(2, "šĪ²\t\t".len() as u32);
- let display_point = DisplayPoint::new(2, "šĪ² ".len() as u32);
+ let point = MultiBufferPoint::new(2, "šĪ²\t\t".len() as u32);
+ let display_point = DisplayPoint::new(DisplayRow(2), "šĪ² ".len() as u32);
assert_eq!(point.to_display_point(&map), display_point);
assert_eq!(display_point.to_point(&map), point,);
// Display points inside of expanded tabs
assert_eq!(
- DisplayPoint::new(0, "ā
".len() as u32).to_point(&map),
- Point::new(0, "ā
\t".len() as u32),
+ DisplayPoint::new(DisplayRow(0), "ā
".len() as u32).to_point(&map),
+ MultiBufferPoint::new(0, "ā
\t".len() as u32),
);
assert_eq!(
- DisplayPoint::new(0, "ā
".len() as u32).to_point(&map),
- Point::new(0, "ā
".len() as u32),
+ DisplayPoint::new(DisplayRow(0), "ā
".len() as u32).to_point(&map),
+ MultiBufferPoint::new(0, "ā
".len() as u32),
);
// Clipping display points inside of multi-byte characters
assert_eq!(
- map.clip_point(DisplayPoint::new(0, "ā
".len() as u32 - 1), Left),
- DisplayPoint::new(0, 0)
+ map.clip_point(
+ DisplayPoint::new(DisplayRow(0), "ā
".len() as u32 - 1),
+ Left
+ ),
+ DisplayPoint::new(DisplayRow(0), 0)
);
assert_eq!(
- map.clip_point(DisplayPoint::new(0, "ā
".len() as u32 - 1), Bias::Right),
- DisplayPoint::new(0, "ā
".len() as u32)
+ map.clip_point(
+ DisplayPoint::new(DisplayRow(0), "ā
".len() as u32 - 1),
+ Bias::Right
+ ),
+ DisplayPoint::new(DisplayRow(0), "ā
".len() as u32)
);
}
@@ -1785,12 +1839,12 @@ pub mod tests {
});
assert_eq!(
map.update(cx, |map, cx| map.snapshot(cx)).max_point(),
- DisplayPoint::new(1, 11)
+ DisplayPoint::new(DisplayRow(1), 11)
)
}
fn syntax_chunks(
- rows: Range<u32>,
+ rows: Range<DisplayRow>,
map: &Model<DisplayMap>,
theme: &SyntaxTheme,
cx: &mut AppContext,
@@ -1802,7 +1856,7 @@ pub mod tests {
}
fn chunks(
- rows: Range<u32>,
+ rows: Range<DisplayRow>,
map: &Model<DisplayMap>,
theme: &SyntaxTheme,
cx: &mut AppContext,
@@ -6,7 +6,7 @@ use crate::{EditorStyle, GutterDimensions};
use collections::{Bound, HashMap, HashSet};
use gpui::{AnyElement, Pixels, WindowContext};
use language::{BufferSnapshot, Chunk, Patch, Point};
-use multi_buffer::{Anchor, ExcerptId, ExcerptRange, ToPoint as _};
+use multi_buffer::{Anchor, ExcerptId, ExcerptRange, MultiBufferRow, ToPoint as _};
use parking_lot::Mutex;
use std::{
cell::RefCell,
@@ -50,7 +50,7 @@ pub struct BlockId(usize);
pub struct BlockPoint(pub Point);
#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
-struct BlockRow(u32);
+pub struct BlockRow(pub(super) u32);
#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
struct WrapRow(u32);
@@ -163,7 +163,7 @@ pub struct BlockChunks<'a> {
pub struct BlockBufferRows<'a> {
transforms: sum_tree::Cursor<'a, Transform, (BlockRow, WrapRow)>,
input_buffer_rows: wrap_map::WrapBufferRows<'a>,
- output_row: u32,
+ output_row: BlockRow,
started: bool,
}
@@ -357,7 +357,7 @@ impl BlockMap {
match block.disposition {
BlockDisposition::Above => position.column = 0,
BlockDisposition::Below => {
- position.column = buffer.line_len(position.row)
+ position.column = buffer.line_len(MultiBufferRow(position.row))
}
}
let position = wrap_snapshot.make_wrap_point(position, Bias::Left);
@@ -372,7 +372,7 @@ impl BlockMap {
(
wrap_snapshot
.make_wrap_point(
- Point::new(excerpt_boundary.row, 0),
+ Point::new(excerpt_boundary.row.0, 0),
Bias::Left,
)
.row(),
@@ -633,12 +633,12 @@ impl BlockSnapshot {
}
}
- pub fn buffer_rows(&self, start_row: u32) -> BlockBufferRows {
+ pub(super) fn buffer_rows(&self, start_row: BlockRow) -> BlockBufferRows {
let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>();
- cursor.seek(&BlockRow(start_row), Bias::Right, &());
+ cursor.seek(&start_row, Bias::Right, &());
let (output_start, input_start) = cursor.start();
let overshoot = if cursor.item().map_or(false, |t| t.is_isomorphic()) {
- start_row - output_start.0
+ start_row.0 - output_start.0
} else {
0
};
@@ -676,7 +676,7 @@ impl BlockSnapshot {
pub fn max_point(&self) -> BlockPoint {
let row = self.transforms.summary().output_rows - 1;
- BlockPoint::new(row, self.line_len(row))
+ BlockPoint::new(row, self.line_len(BlockRow(row)))
}
pub fn longest_row(&self) -> u32 {
@@ -684,12 +684,12 @@ impl BlockSnapshot {
self.to_block_point(WrapPoint::new(input_row, 0)).row
}
- pub fn line_len(&self, row: u32) -> u32 {
+ pub(super) fn line_len(&self, row: BlockRow) -> u32 {
let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>();
- cursor.seek(&BlockRow(row), Bias::Right, &());
+ cursor.seek(&BlockRow(row.0), Bias::Right, &());
if let Some(transform) = cursor.item() {
let (output_start, input_start) = cursor.start();
- let overshoot = row - output_start.0;
+ let overshoot = row.0 - output_start.0;
if transform.block.is_some() {
0
} else {
@@ -700,9 +700,9 @@ impl BlockSnapshot {
}
}
- pub fn is_block_line(&self, row: u32) -> bool {
+ pub(super) fn is_block_line(&self, row: BlockRow) -> bool {
let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>();
- cursor.seek(&BlockRow(row), Bias::Right, &());
+ cursor.seek(&row, Bias::Right, &());
cursor.item().map_or(false, |t| t.block.is_some())
}
@@ -881,16 +881,16 @@ impl<'a> Iterator for BlockChunks<'a> {
}
impl<'a> Iterator for BlockBufferRows<'a> {
- type Item = Option<u32>;
+ type Item = Option<BlockRow>;
fn next(&mut self) -> Option<Self::Item> {
if self.started {
- self.output_row += 1;
+ self.output_row.0 += 1;
} else {
self.started = true;
}
- if self.output_row >= self.transforms.end(&()).0 .0 {
+ if self.output_row.0 >= self.transforms.end(&()).0 .0 {
self.transforms.next(&());
}
@@ -898,7 +898,7 @@ impl<'a> Iterator for BlockBufferRows<'a> {
if transform.block.is_some() {
Some(None)
} else {
- Some(self.input_buffer_rows.next().unwrap())
+ Some(self.input_buffer_rows.next().unwrap().map(BlockRow))
}
}
}
@@ -1154,7 +1154,10 @@ mod tests {
);
assert_eq!(
- snapshot.buffer_rows(0).collect::<Vec<_>>(),
+ snapshot
+ .buffer_rows(BlockRow(0))
+ .map(|row| row.map(|r| r.0))
+ .collect::<Vec<_>>(),
&[
Some(0),
None,
@@ -1394,7 +1397,7 @@ mod tests {
position.column = 0;
}
BlockDisposition::Below => {
- position.column = buffer_snapshot.line_len(position.row);
+ position.column = buffer_snapshot.line_len(MultiBufferRow(position.row));
}
};
let row = wraps_snapshot.make_wrap_point(position, Bias::Left).row();
@@ -1410,7 +1413,7 @@ mod tests {
expected_blocks.extend(buffer_snapshot.excerpt_boundaries_in_range(0..).map(
|boundary| {
let position =
- wraps_snapshot.make_wrap_point(Point::new(boundary.row, 0), Bias::Left);
+ wraps_snapshot.make_wrap_point(Point::new(boundary.row.0, 0), Bias::Left);
(
position.row(),
ExpectedBlock::ExcerptHeader {
@@ -1427,7 +1430,9 @@ mod tests {
expected_blocks.sort_unstable();
let mut sorted_blocks_iter = expected_blocks.into_iter().peekable();
- let input_buffer_rows = buffer_snapshot.buffer_rows(0).collect::<Vec<_>>();
+ let input_buffer_rows = buffer_snapshot
+ .buffer_rows(MultiBufferRow(0))
+ .collect::<Vec<_>>();
let mut expected_buffer_rows = Vec::new();
let mut expected_text = String::new();
let mut expected_block_positions = Vec::new();
@@ -1498,7 +1503,8 @@ mod tests {
);
assert_eq!(
blocks_snapshot
- .buffer_rows(start_row as u32)
+ .buffer_rows(BlockRow(start_row as u32))
+ .map(|row| row.map(|r| r.0))
.collect::<Vec<_>>(),
&expected_buffer_rows[start_row..]
);
@@ -1518,7 +1524,7 @@ mod tests {
let row = row as u32;
assert_eq!(
- blocks_snapshot.line_len(row),
+ blocks_snapshot.line_len(BlockRow(row)),
line.len() as u32,
"invalid line len for row {}",
row
@@ -4,7 +4,7 @@ use super::{
};
use gpui::{ElementId, HighlightStyle, Hsla};
use language::{Chunk, Edit, Point, TextSummary};
-use multi_buffer::{Anchor, AnchorRangeExt, MultiBufferSnapshot, ToOffset};
+use multi_buffer::{Anchor, AnchorRangeExt, MultiBufferRow, MultiBufferSnapshot, ToOffset};
use std::{
cmp::{self, Ordering},
iter,
@@ -629,17 +629,17 @@ impl FoldSnapshot {
cursor.item().map_or(false, |t| t.output_text.is_some())
}
- pub fn is_line_folded(&self, buffer_row: u32) -> bool {
+ pub fn is_line_folded(&self, buffer_row: MultiBufferRow) -> bool {
let mut inlay_point = self
.inlay_snapshot
- .to_inlay_point(Point::new(buffer_row, 0));
+ .to_inlay_point(Point::new(buffer_row.0, 0));
let mut cursor = self.transforms.cursor::<InlayPoint>();
cursor.seek(&inlay_point, Bias::Right, &());
loop {
match cursor.item() {
Some(transform) => {
let buffer_point = self.inlay_snapshot.to_buffer_point(inlay_point);
- if buffer_point.row != buffer_row {
+ if buffer_point.row != buffer_row.0 {
return false;
} else if transform.output_text.is_some() {
return true;
@@ -1549,7 +1549,7 @@ mod tests {
.collect::<HashSet<_>>();
for row in 0..=buffer_snapshot.max_point().row {
assert_eq!(
- snapshot.is_line_folded(row),
+ snapshot.is_line_folded(MultiBufferRow(row)),
folded_buffer_rows.contains(&row),
"expected buffer row {}{} to be folded",
row,
@@ -2,7 +2,9 @@ use crate::{HighlightStyles, InlayId};
use collections::{BTreeMap, BTreeSet};
use gpui::HighlightStyle;
use language::{Chunk, Edit, Point, TextSummary};
-use multi_buffer::{Anchor, MultiBufferChunks, MultiBufferRows, MultiBufferSnapshot, ToOffset};
+use multi_buffer::{
+ Anchor, MultiBufferChunks, MultiBufferRow, MultiBufferRows, MultiBufferSnapshot, ToOffset,
+};
use std::{
any::TypeId,
cmp,
@@ -182,7 +184,7 @@ pub struct InlayBufferRows<'a> {
transforms: Cursor<'a, Transform, (InlayPoint, Point)>,
buffer_rows: MultiBufferRows<'a>,
inlay_row: u32,
- max_buffer_row: u32,
+ max_buffer_row: MultiBufferRow,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
@@ -375,7 +377,7 @@ impl<'a> InlayBufferRows<'a> {
self.transforms.seek(&inlay_point, Bias::Left, &());
let mut buffer_point = self.transforms.start().1;
- let buffer_row = if row == 0 {
+ let buffer_row = MultiBufferRow(if row == 0 {
0
} else {
match self.transforms.item() {
@@ -383,9 +385,9 @@ impl<'a> InlayBufferRows<'a> {
buffer_point += inlay_point.0 - self.transforms.start().0 .0;
buffer_point.row
}
- _ => cmp::min(buffer_point.row + 1, self.max_buffer_row),
+ _ => cmp::min(buffer_point.row + 1, self.max_buffer_row.0),
}
- };
+ });
self.inlay_row = inlay_point.row();
self.buffer_rows.seek(buffer_row);
}
@@ -986,17 +988,17 @@ impl InlaySnapshot {
let inlay_point = InlayPoint::new(row, 0);
cursor.seek(&inlay_point, Bias::Left, &());
- let max_buffer_row = self.buffer.max_point().row;
+ let max_buffer_row = MultiBufferRow(self.buffer.max_point().row);
let mut buffer_point = cursor.start().1;
let buffer_row = if row == 0 {
- 0
+ MultiBufferRow(0)
} else {
match cursor.item() {
Some(Transform::Isomorphic(_)) => {
buffer_point += inlay_point.0 - cursor.start().0 .0;
- buffer_point.row
+ MultiBufferRow(buffer_point.row)
}
- _ => cmp::min(buffer_point.row + 1, max_buffer_row),
+ _ => cmp::min(MultiBufferRow(buffer_point.row + 1), max_buffer_row),
}
};
@@ -86,18 +86,18 @@ use language::{
CursorShape, Diagnostic, Documentation, IndentKind, IndentSize, Language, OffsetRangeExt,
Point, Selection, SelectionGoal, TransactionId,
};
-use language::{Runnable, RunnableRange};
+use language::{BufferRow, Runnable, RunnableRange};
use task::{ResolvedTask, TaskTemplate, TaskVariables};
use hover_links::{HoverLink, HoveredLinkState, InlayHighlight};
use lsp::{DiagnosticSeverity, LanguageServerId};
use mouse_context_menu::MouseContextMenu;
use movement::TextLayoutDetails;
-use multi_buffer::ToOffsetUtf16;
pub use multi_buffer::{
Anchor, AnchorRangeExt, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, ToOffset,
ToPoint,
};
+use multi_buffer::{MultiBufferPoint, MultiBufferRow, ToOffsetUtf16};
use ordered_float::OrderedFloat;
use parking_lot::{Mutex, RwLock};
use project::project_settings::{GitGutterSetting, ProjectSettings};
@@ -410,7 +410,7 @@ struct RunnableTasks {
#[derive(Clone)]
struct ResolvedTasks {
templates: SmallVec<[(TaskSourceKind, ResolvedTask); 1]>,
- position: text::Point,
+ position: Anchor,
}
/// Zed's primary text input `View`, allowing users to edit a [`MultiBuffer`]
@@ -505,7 +505,7 @@ pub struct Editor {
>,
last_bounds: Option<Bounds<Pixels>>,
expect_bounds_change: Option<Bounds<Pixels>>,
- tasks: HashMap<(BufferId, u32), (usize, RunnableTasks)>,
+ tasks: HashMap<(BufferId, BufferRow), (usize, RunnableTasks)>,
tasks_update_task: Option<Task<()>>,
}
@@ -804,7 +804,7 @@ impl ContextMenu {
enum ContextMenuOrigin {
EditorPoint(DisplayPoint),
- GutterIndicator(u32),
+ GutterIndicator(DisplayRow),
}
#[derive(Clone)]
@@ -1299,7 +1299,7 @@ struct CodeActionsMenu {
buffer: Model<Buffer>,
selected_item: usize,
scroll_handle: UniformListScrollHandle,
- deployed_from_indicator: Option<u32>,
+ deployed_from_indicator: Option<DisplayRow>,
}
impl CodeActionsMenu {
@@ -2498,7 +2498,8 @@ impl Editor {
let end_column = cmp::max(tail.column(), goal_column);
let reversed = start_column < tail.column();
- let selection_ranges = (start_row..=end_row)
+ let selection_ranges = (start_row.0..=end_row.0)
+ .map(DisplayRow)
.filter_map(|row| {
if start_column <= display_map.line_len(row) && !display_map.is_block_line(row) {
let start = display_map
@@ -2898,7 +2899,8 @@ impl Editor {
.iter()
.map(|selection| {
let start_point = selection.start.to_point(&buffer);
- let mut indent = buffer.indent_size_for_line(start_point.row);
+ let mut indent =
+ buffer.indent_size_for_line(MultiBufferRow(start_point.row));
indent.len = cmp::min(indent.len, start_point.column);
let start = selection.start;
let end = selection.end;
@@ -2951,7 +2953,7 @@ impl Editor {
let max_len_of_delimiter =
delimiters.iter().map(|delimiter| delimiter.len()).max()?;
let (snapshot, range) =
- buffer.buffer_line_for_row(start_point.row)?;
+ buffer.buffer_line_for_row(MultiBufferRow(start_point.row))?;
let mut index_of_first_non_whitespace = 0;
let comment_candidate = snapshot
@@ -3015,7 +3017,7 @@ impl Editor {
let mut cursor = new_selection.end.to_point(&buffer);
if extra_newline_inserted {
cursor.row -= 1;
- cursor.column = buffer.line_len(cursor.row);
+ cursor.column = buffer.line_len(MultiBufferRow(cursor.row));
}
new_selection.map(|_| cursor)
})
@@ -3075,7 +3077,7 @@ impl Editor {
IndentKind::Space => " ".repeat(indent.len as usize),
IndentKind::Tab => "\t".repeat(indent.len as usize),
};
- let point = Point::new(row, 0);
+ let point = Point::new(row.0, 0);
indent_edits.push((point..point, text));
}
}
@@ -3135,7 +3137,7 @@ impl Editor {
IndentKind::Space => " ".repeat(indent.len as usize),
IndentKind::Tab => "\t".repeat(indent.len as usize),
};
- let point = Point::new(row, 0);
+ let point = Point::new(row.0, 0);
indent_edits.push((point..point, text));
}
}
@@ -3852,17 +3854,13 @@ impl Editor {
let spawned_test_task = this.update(&mut cx, |this, cx| {
if this.focus_handle.is_focused(cx) {
- let display_row = action
+ let multibuffer_point = action
.deployed_from_indicator
- .map(|row| {
- DisplayPoint::new(row, 0)
- .to_point(&snapshot.display_snapshot)
- .row
- })
- .unwrap_or_else(|| this.selections.newest::<Point>(cx).head().row);
+ .map(|row| DisplayPoint::new(row, 0).to_point(&snapshot))
+ .unwrap_or_else(|| this.selections.newest::<Point>(cx).head());
let (buffer, buffer_row) = snapshot
.buffer_snapshot
- .buffer_line_for_row(display_row)
+ .buffer_line_for_row(MultiBufferRow(multibuffer_point.row))
.and_then(|(buffer_snapshot, range)| {
this.buffer
.read(cx)
@@ -3934,7 +3932,9 @@ impl Editor {
.map(|task| (kind.clone(), task))
})
.collect(),
- position: Point::new(buffer_row, tasks.1.column),
+ position: snapshot
+ .buffer_snapshot
+ .anchor_before(Point::new(multibuffer_point.row, tasks.1.column)),
})
});
let spawn_straight_away = tasks
@@ -4496,7 +4496,7 @@ impl Editor {
fn render_code_actions_indicator(
&self,
_style: &EditorStyle,
- row: u32,
+ row: DisplayRow,
is_active: bool,
cx: &mut ViewContext<Self>,
) -> Option<IconButton> {
@@ -4525,7 +4525,7 @@ impl Editor {
self.tasks.clear()
}
- fn insert_tasks(&mut self, key: (BufferId, u32), value: (usize, RunnableTasks)) {
+ fn insert_tasks(&mut self, key: (BufferId, BufferRow), value: (usize, RunnableTasks)) {
if let Some(_) = self.tasks.insert(key, value) {
// This case should hopefully be rare, but just in case...
log::error!("multiple different run targets found on a single line, only the last target will be rendered")
@@ -4536,7 +4536,7 @@ impl Editor {
&self,
_style: &EditorStyle,
is_active: bool,
- row: u32,
+ row: DisplayRow,
cx: &mut ViewContext<Self>,
) -> IconButton {
IconButton::new("code_actions_indicator", ui::IconName::Play)
@@ -4556,7 +4556,7 @@ impl Editor {
pub fn render_fold_indicators(
&mut self,
- fold_data: Vec<Option<(FoldStatus, u32, bool)>>,
+ fold_data: Vec<Option<(FoldStatus, MultiBufferRow, bool)>>,
_style: &EditorStyle,
gutter_hovered: bool,
_line_height: Pixels,
@@ -4775,7 +4775,7 @@ impl Editor {
pub fn backspace(&mut self, _: &Backspace, cx: &mut ViewContext<Self>) {
self.transact(cx, |this, cx| {
this.select_autoclose_pair(cx);
- let mut selections = this.selections.all::<Point>(cx);
+ let mut selections = this.selections.all::<MultiBufferPoint>(cx);
if !this.selections.line_mode {
let display_map = this.display_map.update(cx, |map, cx| map.snapshot(cx));
for selection in &mut selections {
@@ -4786,7 +4786,7 @@ impl Editor {
.to_point(&display_map);
if let Some((buffer, line_buffer_range)) = display_map
.buffer_snapshot
- .buffer_line_for_row(old_head.row)
+ .buffer_line_for_row(MultiBufferRow(old_head.row))
{
let indent_size =
buffer.indent_size_for_line(line_buffer_range.start.row);
@@ -4800,7 +4800,7 @@ impl Editor {
let indent_len = indent_len.get();
new_head = cmp::min(
new_head,
- Point::new(
+ MultiBufferPoint::new(
old_head.row,
((old_head.column - 1) / indent_len) * indent_len,
),
@@ -4875,8 +4875,10 @@ impl Editor {
// If the selection is empty and the cursor is in the leading whitespace before the
// suggested indentation, then auto-indent the line.
let cursor = selection.head();
- let current_indent = snapshot.indent_size_for_line(cursor.row);
- if let Some(suggested_indent) = suggested_indents.get(&cursor.row).copied() {
+ let current_indent = snapshot.indent_size_for_line(MultiBufferRow(cursor.row));
+ if let Some(suggested_indent) =
+ suggested_indents.get(&MultiBufferRow(cursor.row)).copied()
+ {
if cursor.column < suggested_indent.len
&& cursor.column <= current_indent.len
&& current_indent.len <= suggested_indent.len
@@ -4996,7 +4998,7 @@ impl Editor {
let mut delta_for_end_row = 0;
let has_multiple_rows = start_row + 1 != end_row;
for row in start_row..end_row {
- let current_indent = snapshot.indent_size_for_line(row);
+ let current_indent = snapshot.indent_size_for_line(MultiBufferRow(row));
let indent_delta = match (current_indent.kind, indent_kind) {
(IndentKind::Space, IndentKind::Space) => {
let columns_to_next_tab_stop = tab_size - (current_indent.len % tab_size);
@@ -5054,11 +5056,11 @@ impl Editor {
// previous selection.
if let Some(last_row) = last_outdent {
if last_row == rows.start {
- rows.start += 1;
+ rows.start = rows.start.next_row();
}
}
let has_multiple_rows = rows.len() > 1;
- for row in rows {
+ for row in rows.iter_rows() {
let indent_size = snapshot.indent_size_for_line(row);
if indent_size.len > 0 {
let deletion_len = match indent_size.kind {
@@ -5080,8 +5082,9 @@ impl Editor {
} else {
selection.start.column - deletion_len
};
- deletion_ranges
- .push(Point::new(row, start)..Point::new(row, start + deletion_len));
+ deletion_ranges.push(
+ Point::new(row.0, start)..Point::new(row.0, start + deletion_len),
+ );
last_outdent = Some(row);
}
}
@@ -5127,23 +5130,23 @@ impl Editor {
}
let buffer = &display_map.buffer_snapshot;
- let mut edit_start = Point::new(rows.start, 0).to_offset(buffer);
+ let mut edit_start = Point::new(rows.start.0, 0).to_offset(buffer);
let edit_end;
let cursor_buffer_row;
- if buffer.max_point().row >= rows.end {
+ if buffer.max_point().row >= rows.end.0 {
// If there's a line after the range, delete the \n from the end of the row range
// and position the cursor on the next line.
- edit_end = Point::new(rows.end, 0).to_offset(buffer);
+ edit_end = Point::new(rows.end.0, 0).to_offset(buffer);
cursor_buffer_row = rows.end;
} else {
// If there isn't a line after the range, delete the \n from the line before the
// start of the row range and position the cursor there.
edit_start = edit_start.saturating_sub(1);
edit_end = buffer.len();
- cursor_buffer_row = rows.start.saturating_sub(1);
+ cursor_buffer_row = rows.start.previous_row();
}
- let mut cursor = Point::new(cursor_buffer_row, 0).to_display_point(&display_map);
+ let mut cursor = Point::new(cursor_buffer_row.0, 0).to_display_point(&display_map);
*cursor.column_mut() =
cmp::min(goal_display_column, display_map.line_len(cursor.row()));
@@ -5190,13 +5193,13 @@ impl Editor {
if self.read_only(cx) {
return;
}
- let mut row_ranges = Vec::<Range<u32>>::new();
+ let mut row_ranges = Vec::<Range<MultiBufferRow>>::new();
for selection in self.selections.all::<Point>(cx) {
- let start = selection.start.row;
+ let start = MultiBufferRow(selection.start.row);
let end = if selection.start.row == selection.end.row {
- selection.start.row + 1
+ MultiBufferRow(selection.start.row + 1)
} else {
- selection.end.row
+ MultiBufferRow(selection.end.row)
};
if let Some(last_row_range) = row_ranges.last_mut() {
@@ -5212,20 +5215,21 @@ impl Editor {
let mut cursor_positions = Vec::new();
for row_range in &row_ranges {
let anchor = snapshot.anchor_before(Point::new(
- row_range.end - 1,
- snapshot.line_len(row_range.end - 1),
+ row_range.end.previous_row().0,
+ snapshot.line_len(row_range.end.previous_row()),
));
cursor_positions.push(anchor..anchor);
}
self.transact(cx, |this, cx| {
for row_range in row_ranges.into_iter().rev() {
- for row in row_range.rev() {
- let end_of_line = Point::new(row, snapshot.line_len(row));
- let indent = snapshot.indent_size_for_line(row + 1);
- let start_of_next_line = Point::new(row + 1, indent.len);
+ for row in row_range.iter_rows().rev() {
+ let end_of_line = Point::new(row.0, snapshot.line_len(row));
+ let next_line_row = row.next_row();
+ let indent = snapshot.indent_size_for_line(next_line_row);
+ let start_of_next_line = Point::new(next_line_row.0, indent.len);
- let replace = if snapshot.line_len(row + 1) > indent.len {
+ let replace = if snapshot.line_len(next_line_row) > indent.len {
" "
} else {
""
@@ -5342,7 +5346,7 @@ impl Editor {
fn prepare_revert_change(
revert_changes: &mut HashMap<BufferId, Vec<(Range<text::Anchor>, Rope)>>,
multi_buffer: &MultiBuffer,
- hunk: &DiffHunk<u32>,
+ hunk: &DiffHunk<MultiBufferRow>,
cx: &mut AppContext,
) -> Option<()> {
let buffer = multi_buffer.buffer(hunk.buffer_id)?;
@@ -5396,8 +5400,11 @@ impl Editor {
&mut selections,
);
- let start_point = Point::new(start_row, 0);
- let end_point = Point::new(end_row - 1, buffer.line_len(end_row - 1));
+ let start_point = Point::new(start_row.0, 0);
+ let end_point = Point::new(
+ end_row.previous_row().0,
+ buffer.line_len(end_row.previous_row()),
+ );
let text = buffer
.text_for_range(start_point..end_point)
.collect::<String>();
@@ -5411,8 +5418,9 @@ impl Editor {
edits.push((start_point..end_point, lines.join("\n")));
// Selections must change based on added and removed line count
- let start_row = start_point.row + added_lines as u32 - removed_lines as u32;
- let end_row = start_row + lines_after.saturating_sub(1) as u32;
+ let start_row =
+ MultiBufferRow(start_point.row + added_lines as u32 - removed_lines as u32);
+ let end_row = MultiBufferRow(start_row.0 + lines_after.saturating_sub(1) as u32);
new_selections.push(Selection {
id: selection.id,
start: start_row,
@@ -5438,8 +5446,8 @@ impl Editor {
let new_selections = new_selections
.iter()
.map(|s| {
- let start_point = Point::new(s.start, 0);
- let end_point = Point::new(s.end, buffer.line_len(s.end));
+ let start_point = Point::new(s.start.0, 0);
+ let end_point = Point::new(s.end.0, buffer.line_len(s.end));
Selection {
id: s.id,
start: buffer.point_to_offset(start_point),
@@ -5602,14 +5610,17 @@ impl Editor {
// Copy the text from the selected row region and splice it either at the start
// or end of the region.
- let start = Point::new(rows.start, 0);
- let end = Point::new(rows.end - 1, buffer.line_len(rows.end - 1));
+ let start = Point::new(rows.start.0, 0);
+ let end = Point::new(
+ rows.end.previous_row().0,
+ buffer.line_len(rows.end.previous_row()),
+ );
let text = buffer
.text_for_range(start..end)
.chain(Some("\n"))
.collect::<String>();
let insert_location = if upwards {
- Point::new(rows.end, 0)
+ Point::new(rows.end.0, 0)
} else {
start
};
@@ -5656,11 +5667,17 @@ impl Editor {
);
// Move the text spanned by the row range to be before the line preceding the row range
- if start_row > 0 {
- let range_to_move = Point::new(start_row - 1, buffer.line_len(start_row - 1))
- ..Point::new(end_row - 1, buffer.line_len(end_row - 1));
+ if start_row.0 > 0 {
+ let range_to_move = Point::new(
+ start_row.previous_row().0,
+ buffer.line_len(start_row.previous_row()),
+ )
+ ..Point::new(
+ end_row.previous_row().0,
+ buffer.line_len(end_row.previous_row()),
+ );
let insertion_point = display_map
- .prev_line_boundary(Point::new(start_row - 1, 0))
+ .prev_line_boundary(Point::new(start_row.previous_row().0, 0))
.0;
// Don't move lines across excerpts
@@ -5754,9 +5771,12 @@ impl Editor {
);
// Move the text spanned by the row range to be after the last line of the row range
- if end_row <= buffer.max_point().row {
- let range_to_move = Point::new(start_row, 0)..Point::new(end_row, 0);
- let insertion_point = display_map.next_line_boundary(Point::new(end_row, 0)).0;
+ if end_row.0 <= buffer.max_point().row {
+ let range_to_move =
+ MultiBufferPoint::new(start_row.0, 0)..MultiBufferPoint::new(end_row.0, 0);
+ let insertion_point = display_map
+ .next_line_boundary(MultiBufferPoint::new(end_row.0, 0))
+ .0;
// Don't move lines across excerpt boundaries
if buffer
@@ -5906,7 +5926,9 @@ impl Editor {
clipboard_selections.push(ClipboardSelection {
len,
is_entire_line,
- first_line_indent: buffer.indent_size_for_line(selection.start.row).len,
+ first_line_indent: buffer
+ .indent_size_for_line(MultiBufferRow(selection.start.row))
+ .len,
});
}
}
@@ -5950,7 +5972,7 @@ impl Editor {
clipboard_selections.push(ClipboardSelection {
len,
is_entire_line,
- first_line_indent: buffer.indent_size_for_line(start.row).len,
+ first_line_indent: buffer.indent_size_for_line(MultiBufferRow(start.row)).len,
});
}
}
@@ -6847,8 +6869,8 @@ impl Editor {
let max_point = display_map.buffer_snapshot.max_point();
for selection in &mut selections {
let rows = selection.spanned_rows(true, &display_map);
- selection.start = Point::new(rows.start, 0);
- selection.end = cmp::min(max_point, Point::new(rows.end, 0));
+ selection.start = Point::new(rows.start.0, 0);
+ selection.end = cmp::min(max_point, Point::new(rows.end.0, 0));
selection.reversed = false;
}
self.change_selections(Some(Autoscroll::fit()), cx, |s| {
@@ -6868,7 +6890,7 @@ impl Editor {
let buffer = self.buffer.read(cx).read(cx);
for selection in selections {
for row in selection.start.row..selection.end.row {
- let cursor = Point::new(row, buffer.line_len(row));
+ let cursor = Point::new(row, buffer.line_len(MultiBufferRow(row)));
new_selection_ranges.push(cursor..cursor);
}
new_selection_ranges.push(selection.end..selection.end);
@@ -6903,10 +6925,10 @@ impl Editor {
selections.clear();
let mut stack = Vec::new();
- for row in range.start.row()..=range.end.row() {
+ for row in range.start.row().0..=range.end.row().0 {
if let Some(selection) = self.selections.build_columnar_selection(
&display_map,
- row,
+ DisplayRow(row),
&positions,
oldest_selection.reversed,
&text_layout_details,
@@ -6927,7 +6949,7 @@ impl Editor {
let mut new_selections = Vec::new();
if above == state.above {
let end_row = if above {
- 0
+ DisplayRow(0)
} else {
display_map.max_point().row()
};
@@ -6950,9 +6972,9 @@ impl Editor {
while row != end_row {
if above {
- row -= 1;
+ row.0 -= 1;
} else {
- row += 1;
+ row.0 += 1;
}
if let Some(new_selection) = self.selections.build_columnar_selection(
@@ -7386,7 +7408,7 @@ impl Editor {
pub fn toggle_comments(&mut self, action: &ToggleComments, cx: &mut ViewContext<Self>) {
let text_layout_details = &self.text_layout_details(cx);
self.transact(cx, |this, cx| {
- let mut selections = this.selections.all::<Point>(cx);
+ let mut selections = this.selections.all::<MultiBufferPoint>(cx);
let mut edits = Vec::new();
let mut selection_edit_ranges = Vec::new();
let mut last_toggled_row = None;
@@ -7396,11 +7418,11 @@ impl Editor {
fn comment_prefix_range(
snapshot: &MultiBufferSnapshot,
- row: u32,
+ row: MultiBufferRow,
comment_prefix: &str,
comment_prefix_whitespace: &str,
) -> Range<Point> {
- let start = Point::new(row, snapshot.indent_size_for_line(row).len);
+ let start = Point::new(row.0, snapshot.indent_size_for_line(row).len);
let mut line_bytes = snapshot
.bytes_in_range(start..snapshot.max_point())
@@ -7431,11 +7453,11 @@ impl Editor {
fn comment_suffix_range(
snapshot: &MultiBufferSnapshot,
- row: u32,
+ row: MultiBufferRow,
comment_suffix: &str,
comment_suffix_has_leading_space: bool,
) -> Range<Point> {
- let end = Point::new(row, snapshot.line_len(row));
+ let end = Point::new(row.0, snapshot.line_len(row));
let suffix_start_column = end.column.saturating_sub(comment_suffix.len() as u32);
let mut line_end_bytes = snapshot
@@ -7464,7 +7486,9 @@ impl Editor {
// TODO: Handle selections that cross excerpts
for selection in &mut selections {
- let start_column = snapshot.indent_size_for_line(selection.start.row).len;
+ let start_column = snapshot
+ .indent_size_for_line(MultiBufferRow(selection.start.row))
+ .len;
let language = if let Some(language) =
snapshot.language_scope_at(Point::new(selection.start.row, start_column))
{
@@ -7477,15 +7501,15 @@ impl Editor {
// If multiple selections contain a given row, avoid processing that
// row more than once.
- let mut start_row = selection.start.row;
+ let mut start_row = MultiBufferRow(selection.start.row);
if last_toggled_row == Some(start_row) {
- start_row += 1;
+ start_row = start_row.next_row();
}
let end_row =
if selection.end.row > selection.start.row && selection.end.column == 0 {
- selection.end.row - 1
+ MultiBufferRow(selection.end.row - 1)
} else {
- selection.end.row
+ MultiBufferRow(selection.end.row)
};
last_toggled_row = Some(end_row);
@@ -7506,7 +7530,8 @@ impl Editor {
let mut all_selection_lines_are_comments = true;
- for row in start_row..=end_row {
+ for row in start_row.0..=end_row.0 {
+ let row = MultiBufferRow(row);
if start_row < end_row && snapshot.is_line_blank(row) {
continue;
}
@@ -7596,7 +7621,7 @@ impl Editor {
let snapshot = this.buffer.read(cx).read(cx);
for selection in &mut selections {
while let Some((row, suffix_len)) = suffixes_inserted.peek().copied() {
- match row.cmp(&selection.end.row) {
+ match row.cmp(&MultiBufferRow(selection.end.row)) {
Ordering::Less => {
suffixes_inserted.next();
continue;
@@ -7782,7 +7807,7 @@ impl Editor {
let row = snapshot
.buffer_snapshot
- .buffer_line_for_row(point.row)?
+ .buffer_line_for_row(MultiBufferRow(point.row))?
.1
.start
.row;
@@ -8060,9 +8085,9 @@ impl Editor {
&snapshot,
selection.head(),
false,
- snapshot
- .buffer_snapshot
- .git_diff_hunks_in_range((selection.head().row + 1)..u32::MAX),
+ snapshot.buffer_snapshot.git_diff_hunks_in_range(
+ MultiBufferRow(selection.head().row + 1)..MultiBufferRow::MAX,
+ ),
cx,
) {
let wrapped_point = Point::zero();
@@ -8070,9 +8095,9 @@ impl Editor {
&snapshot,
wrapped_point,
true,
- snapshot
- .buffer_snapshot
- .git_diff_hunks_in_range((wrapped_point.row + 1)..u32::MAX),
+ snapshot.buffer_snapshot.git_diff_hunks_in_range(
+ MultiBufferRow(wrapped_point.row + 1)..MultiBufferRow::MAX,
+ ),
cx,
);
}
@@ -8088,9 +8113,9 @@ impl Editor {
&snapshot,
selection.head(),
false,
- snapshot
- .buffer_snapshot
- .git_diff_hunks_in_range_rev(0..selection.head().row),
+ snapshot.buffer_snapshot.git_diff_hunks_in_range_rev(
+ MultiBufferRow(0)..MultiBufferRow(selection.head().row),
+ ),
cx,
) {
let wrapped_point = snapshot.buffer_snapshot.max_point();
@@ -8098,9 +8123,9 @@ impl Editor {
&snapshot,
wrapped_point,
true,
- snapshot
- .buffer_snapshot
- .git_diff_hunks_in_range_rev(0..wrapped_point.row),
+ snapshot.buffer_snapshot.git_diff_hunks_in_range_rev(
+ MultiBufferRow(0)..MultiBufferRow(wrapped_point.row),
+ ),
cx,
);
}
@@ -8111,7 +8136,7 @@ impl Editor {
snapshot: &DisplaySnapshot,
initial_point: Point,
is_wrapped: bool,
- hunks: impl Iterator<Item = DiffHunk<u32>>,
+ hunks: impl Iterator<Item = DiffHunk<MultiBufferRow>>,
cx: &mut ViewContext<Editor>,
) -> bool {
let display_point = initial_point.to_display_point(snapshot);
@@ -8972,11 +8997,11 @@ impl Editor {
let mut primary_message = None;
let mut group_end = Point::zero();
let diagnostic_group = buffer
- .diagnostic_group::<Point>(group_id)
+ .diagnostic_group::<MultiBufferPoint>(group_id)
.filter_map(|entry| {
- if snapshot.is_line_folded(entry.range.start.row)
+ if snapshot.is_line_folded(MultiBufferRow(entry.range.start.row))
&& (entry.range.start.row == entry.range.end.row
- || snapshot.is_line_folded(entry.range.end.row))
+ || snapshot.is_line_folded(MultiBufferRow(entry.range.end.row)))
{
return None;
}
@@ -9117,7 +9142,7 @@ impl Editor {
let buffer_start_row = range.start.row;
for row in (0..=range.end.row).rev() {
- let fold_range = display_map.foldable_range(row);
+ let fold_range = display_map.foldable_range(MultiBufferRow(row));
if let Some(fold_range) = fold_range {
if fold_range.end.row >= buffer_start_row {
@@ -9159,7 +9184,7 @@ impl Editor {
let mut start = range.start.to_point(&display_map);
let mut end = range.end.to_point(&display_map);
start.column = 0;
- end.column = buffer.line_len(end.row);
+ end.column = buffer.line_len(MultiBufferRow(end.row));
start..end
})
.collect::<Vec<_>>();
@@ -9170,9 +9195,9 @@ impl Editor {
pub fn unfold_at(&mut self, unfold_at: &UnfoldAt, cx: &mut ViewContext<Self>) {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
- let intersection_range = Point::new(unfold_at.buffer_row, 0)
+ let intersection_range = Point::new(unfold_at.buffer_row.0, 0)
..Point::new(
- unfold_at.buffer_row,
+ unfold_at.buffer_row.0,
display_map.buffer_snapshot.line_len(unfold_at.buffer_row),
);
@@ -9192,7 +9217,12 @@ impl Editor {
let ranges = selections.into_iter().map(|s| {
if line_mode {
let start = Point::new(s.start.row, 0);
- let end = Point::new(s.end.row, display_map.buffer_snapshot.line_len(s.end.row));
+ let end = Point::new(
+ s.end.row,
+ display_map
+ .buffer_snapshot
+ .line_len(MultiBufferRow(s.end.row)),
+ );
start..end
} else {
s.start..s.end
@@ -9330,7 +9360,7 @@ impl Editor {
}
}
- pub fn longest_row(&self, cx: &mut AppContext) -> u32 {
+ pub fn longest_row(&self, cx: &mut AppContext) -> DisplayRow {
self.display_map
.update(cx, |map, cx| map.snapshot(cx))
.longest_row()
@@ -9595,7 +9625,7 @@ impl Editor {
let cursor_anchor = self.selections.newest_anchor().head();
let snapshot = self.buffer.read(cx).snapshot(cx);
- let buffer_row = cursor_anchor.to_point(&snapshot).row;
+ let buffer_row = MultiBufferRow(cursor_anchor.to_point(&snapshot).row);
snapshot.line_len(buffer_row) == 0
}
@@ -9776,7 +9806,7 @@ impl Editor {
&mut self,
exclude_highlights: HashSet<TypeId>,
cx: &mut WindowContext,
- ) -> BTreeMap<u32, Hsla> {
+ ) -> BTreeMap<DisplayRow, Hsla> {
let snapshot = self.snapshot(cx);
let mut used_highlight_orders = HashMap::default();
self.highlighted_rows
@@ -9784,21 +9814,21 @@ impl Editor {
.filter(|(type_id, _)| !exclude_highlights.contains(type_id))
.flat_map(|(_, highlighted_rows)| highlighted_rows.iter())
.fold(
- BTreeMap::<u32, Hsla>::new(),
+ BTreeMap::<DisplayRow, Hsla>::new(),
|mut unique_rows, (highlight_order, anchor_range, hsla)| {
let start_row = anchor_range.start().to_display_point(&snapshot).row();
let end_row = anchor_range.end().to_display_point(&snapshot).row();
- for row in start_row..=end_row {
+ for row in start_row.0..=end_row.0 {
let used_index =
used_highlight_orders.entry(row).or_insert(*highlight_order);
if highlight_order >= used_index {
*used_index = *highlight_order;
match hsla {
Some(hsla) => {
- unique_rows.insert(row, *hsla);
+ unique_rows.insert(DisplayRow(row), *hsla);
}
None => {
- unique_rows.remove(&row);
+ unique_rows.remove(&DisplayRow(row));
}
}
}
@@ -10640,15 +10670,15 @@ impl Editor {
fn hunks_for_selections(
multi_buffer_snapshot: &MultiBufferSnapshot,
selections: &[Selection<Anchor>],
-) -> Vec<DiffHunk<u32>> {
+) -> Vec<DiffHunk<MultiBufferRow>> {
let mut hunks = Vec::with_capacity(selections.len());
let mut processed_buffer_rows: HashMap<BufferId, HashSet<Range<text::Anchor>>> =
HashMap::default();
- let display_rows_for_selections = selections.iter().map(|selection| {
+ let buffer_rows_for_selections = selections.iter().map(|selection| {
let head = selection.head();
let tail = selection.tail();
- let start = tail.to_point(&multi_buffer_snapshot).row;
- let end = head.to_point(&multi_buffer_snapshot).row;
+ let start = MultiBufferRow(tail.to_point(&multi_buffer_snapshot).row);
+ let end = MultiBufferRow(head.to_point(&multi_buffer_snapshot).row);
if start > end {
end..start
} else {
@@ -10656,12 +10686,13 @@ fn hunks_for_selections(
}
});
- for selected_multi_buffer_rows in display_rows_for_selections {
- let query_rows = selected_multi_buffer_rows.start..selected_multi_buffer_rows.end + 1;
+ for selected_multi_buffer_rows in buffer_rows_for_selections {
+ let query_rows =
+ selected_multi_buffer_rows.start..selected_multi_buffer_rows.end.next_row();
for hunk in multi_buffer_snapshot.git_diff_hunks_in_range(query_rows.clone()) {
// Deleted hunk is an empty row range, no caret can be placed there and Zed allows to revert it
// when the caret is just above or just below the deleted hunk.
- let allow_adjacent = hunk.status() == DiffHunkStatus::Removed;
+ let allow_adjacent = hunk_status(&hunk) == DiffHunkStatus::Removed;
let related_to_selection = if allow_adjacent {
hunk.associated_range.overlaps(&query_rows)
|| hunk.associated_range.start == query_rows.end
@@ -10798,13 +10829,13 @@ fn consume_contiguous_rows(
selection: &Selection<Point>,
display_map: &DisplaySnapshot,
selections: &mut std::iter::Peekable<std::slice::Iter<Selection<Point>>>,
-) -> (u32, u32) {
+) -> (MultiBufferRow, MultiBufferRow) {
contiguous_row_selections.push(selection.clone());
- let start_row = selection.start.row;
+ let start_row = MultiBufferRow(selection.start.row);
let mut end_row = ending_row(selection, display_map);
while let Some(next_selection) = selections.peek() {
- if next_selection.start.row <= end_row {
+ if next_selection.start.row <= end_row.0 {
end_row = ending_row(next_selection, display_map);
contiguous_row_selections.push(selections.next().unwrap().clone());
} else {
@@ -10814,11 +10845,11 @@ fn consume_contiguous_rows(
(start_row, end_row)
}
-fn ending_row(next_selection: &Selection<Point>, display_map: &DisplaySnapshot) -> u32 {
+fn ending_row(next_selection: &Selection<Point>, display_map: &DisplaySnapshot) -> MultiBufferRow {
if next_selection.end.column > 0 || next_selection.is_empty() {
- display_map.next_line_boundary(next_selection.end).0.row + 1
+ MultiBufferRow(display_map.next_line_boundary(next_selection.end).0.row + 1)
} else {
- next_selection.end.row
+ MultiBufferRow(next_selection.end.row)
}
}
@@ -11300,7 +11331,7 @@ impl ViewInputHandler for Editor {
let start = OffsetUtf16(range_utf16.start).to_display_point(&snapshot);
let x = snapshot.x_for_display_point(start, &text_layout_details) - scroll_left
+ self.gutter_dimensions.width;
- let y = line_height * (start.row() as f32 - scroll_position.y);
+ let y = line_height * (start.row().as_f32() - scroll_position.y);
Some(Bounds {
origin: element_bounds.origin + point(x, y),
@@ -11311,8 +11342,11 @@ impl ViewInputHandler for Editor {
trait SelectionExt {
fn display_range(&self, map: &DisplaySnapshot) -> Range<DisplayPoint>;
- fn spanned_rows(&self, include_end_if_at_line_start: bool, map: &DisplaySnapshot)
- -> Range<u32>;
+ fn spanned_rows(
+ &self,
+ include_end_if_at_line_start: bool,
+ map: &DisplaySnapshot,
+ ) -> Range<MultiBufferRow>;
}
impl<T: ToPoint + ToOffset> SelectionExt for Selection<T> {
@@ -11336,7 +11370,7 @@ impl<T: ToPoint + ToOffset> SelectionExt for Selection<T> {
&self,
include_end_if_at_line_start: bool,
map: &DisplaySnapshot,
- ) -> Range<u32> {
+ ) -> Range<MultiBufferRow> {
let start = self.start.to_point(&map.buffer_snapshot);
let mut end = self.end.to_point(&map.buffer_snapshot);
if !include_end_if_at_line_start && start.row != end.row && end.column == 0 {
@@ -11345,7 +11379,7 @@ impl<T: ToPoint + ToOffset> SelectionExt for Selection<T> {
let buffer_start = map.prev_line_boundary(start).0;
let buffer_end = map.next_line_boundary(end).0;
- buffer_start.row..buffer_end.row + 1
+ MultiBufferRow(buffer_start.row)..MultiBufferRow(buffer_end.row + 1)
}
}
@@ -11609,3 +11643,91 @@ impl<T: ToOffset> RangeToAnchorExt for Range<T> {
}
}
}
+
+pub trait RowExt {
+ fn as_f32(&self) -> f32;
+
+ fn next_row(&self) -> Self;
+
+ fn previous_row(&self) -> Self;
+
+ fn minus(&self, other: Self) -> u32;
+}
+
+impl RowExt for DisplayRow {
+ fn as_f32(&self) -> f32 {
+ self.0 as f32
+ }
+
+ fn next_row(&self) -> Self {
+ Self(self.0 + 1)
+ }
+
+ fn previous_row(&self) -> Self {
+ Self(self.0.saturating_sub(1))
+ }
+
+ fn minus(&self, other: Self) -> u32 {
+ self.0 - other.0
+ }
+}
+
+impl RowExt for MultiBufferRow {
+ fn as_f32(&self) -> f32 {
+ self.0 as f32
+ }
+
+ fn next_row(&self) -> Self {
+ Self(self.0 + 1)
+ }
+
+ fn previous_row(&self) -> Self {
+ Self(self.0.saturating_sub(1))
+ }
+
+ fn minus(&self, other: Self) -> u32 {
+ self.0 - other.0
+ }
+}
+
+trait RowRangeExt {
+ type Row;
+
+ fn len(&self) -> usize;
+
+ fn iter_rows(&self) -> impl DoubleEndedIterator<Item = Self::Row>;
+}
+
+impl RowRangeExt for Range<MultiBufferRow> {
+ type Row = MultiBufferRow;
+
+ fn len(&self) -> usize {
+ (self.end.0 - self.start.0) as usize
+ }
+
+ fn iter_rows(&self) -> impl DoubleEndedIterator<Item = MultiBufferRow> {
+ (self.start.0..self.end.0).map(MultiBufferRow)
+ }
+}
+
+impl RowRangeExt for Range<DisplayRow> {
+ type Row = DisplayRow;
+
+ fn len(&self) -> usize {
+ (self.end.0 - self.start.0) as usize
+ }
+
+ fn iter_rows(&self) -> impl DoubleEndedIterator<Item = DisplayRow> {
+ (self.start.0..self.end.0).map(DisplayRow)
+ }
+}
+
+fn hunk_status(hunk: &DiffHunk<MultiBufferRow>) -> DiffHunkStatus {
+ if hunk.diff_base_byte_range.is_empty() {
+ DiffHunkStatus::Added
+ } else if hunk.associated_range.is_empty() {
+ DiffHunkStatus::Removed
+ } else {
+ DiffHunkStatus::Modified
+ }
+}
@@ -333,18 +333,18 @@ fn test_selection_with_mouse(cx: &mut TestAppContext) {
});
_ = editor.update(cx, |view, cx| {
- view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx);
+ view.begin_selection(DisplayPoint::new(DisplayRow(2), 2), false, 1, cx);
});
assert_eq!(
editor
.update(cx, |view, cx| view.selections.display_ranges(cx))
.unwrap(),
- [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)]
+ [DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(2), 2)]
);
_ = editor.update(cx, |view, cx| {
view.update_selection(
- DisplayPoint::new(3, 3),
+ DisplayPoint::new(DisplayRow(3), 3),
0,
gpui::Point::<f32>::default(),
cx,
@@ -355,12 +355,12 @@ fn test_selection_with_mouse(cx: &mut TestAppContext) {
editor
.update(cx, |view, cx| view.selections.display_ranges(cx))
.unwrap(),
- [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)]
+ [DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(3), 3)]
);
_ = editor.update(cx, |view, cx| {
view.update_selection(
- DisplayPoint::new(1, 1),
+ DisplayPoint::new(DisplayRow(1), 1),
0,
gpui::Point::<f32>::default(),
cx,
@@ -371,13 +371,13 @@ fn test_selection_with_mouse(cx: &mut TestAppContext) {
editor
.update(cx, |view, cx| view.selections.display_ranges(cx))
.unwrap(),
- [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)]
+ [DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(1), 1)]
);
_ = editor.update(cx, |view, cx| {
view.end_selection(cx);
view.update_selection(
- DisplayPoint::new(3, 3),
+ DisplayPoint::new(DisplayRow(3), 3),
0,
gpui::Point::<f32>::default(),
cx,
@@ -388,13 +388,13 @@ fn test_selection_with_mouse(cx: &mut TestAppContext) {
editor
.update(cx, |view, cx| view.selections.display_ranges(cx))
.unwrap(),
- [DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1)]
+ [DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(1), 1)]
);
_ = editor.update(cx, |view, cx| {
- view.begin_selection(DisplayPoint::new(3, 3), true, 1, cx);
+ view.begin_selection(DisplayPoint::new(DisplayRow(3), 3), true, 1, cx);
view.update_selection(
- DisplayPoint::new(0, 0),
+ DisplayPoint::new(DisplayRow(0), 0),
0,
gpui::Point::<f32>::default(),
cx,
@@ -406,8 +406,8 @@ fn test_selection_with_mouse(cx: &mut TestAppContext) {
.update(cx, |view, cx| view.selections.display_ranges(cx))
.unwrap(),
[
- DisplayPoint::new(2, 2)..DisplayPoint::new(1, 1),
- DisplayPoint::new(3, 3)..DisplayPoint::new(0, 0)
+ DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(1), 1),
+ DisplayPoint::new(DisplayRow(3), 3)..DisplayPoint::new(DisplayRow(0), 0)
]
);
@@ -419,7 +419,7 @@ fn test_selection_with_mouse(cx: &mut TestAppContext) {
editor
.update(cx, |view, cx| view.selections.display_ranges(cx))
.unwrap(),
- [DisplayPoint::new(3, 3)..DisplayPoint::new(0, 0)]
+ [DisplayPoint::new(DisplayRow(3), 3)..DisplayPoint::new(DisplayRow(0), 0)]
);
}
@@ -433,37 +433,37 @@ fn test_canceling_pending_selection(cx: &mut TestAppContext) {
});
_ = view.update(cx, |view, cx| {
- view.begin_selection(DisplayPoint::new(2, 2), false, 1, cx);
+ view.begin_selection(DisplayPoint::new(DisplayRow(2), 2), false, 1, cx);
assert_eq!(
view.selections.display_ranges(cx),
- [DisplayPoint::new(2, 2)..DisplayPoint::new(2, 2)]
+ [DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(2), 2)]
);
});
_ = view.update(cx, |view, cx| {
view.update_selection(
- DisplayPoint::new(3, 3),
+ DisplayPoint::new(DisplayRow(3), 3),
0,
gpui::Point::<f32>::default(),
cx,
);
assert_eq!(
view.selections.display_ranges(cx),
- [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)]
+ [DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(3), 3)]
);
});
_ = view.update(cx, |view, cx| {
view.cancel(&Cancel, cx);
view.update_selection(
- DisplayPoint::new(1, 1),
+ DisplayPoint::new(DisplayRow(1), 1),
0,
gpui::Point::<f32>::default(),
cx,
);
assert_eq!(
view.selections.display_ranges(cx),
- [DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3)]
+ [DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(3), 3)]
);
});
}
@@ -566,51 +566,57 @@ async fn test_navigation_history(cx: &mut TestAppContext) {
// Move the cursor a small distance.
// Nothing is added to the navigation history.
editor.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)])
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0)
+ ])
});
editor.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0)])
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(3), 0)..DisplayPoint::new(DisplayRow(3), 0)
+ ])
});
assert!(pop_history(&mut editor, cx).is_none());
// Move the cursor a large distance.
// The history can jump back to the previous position.
editor.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(13, 0)..DisplayPoint::new(13, 3)])
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(13), 0)..DisplayPoint::new(DisplayRow(13), 3)
+ ])
});
let nav_entry = pop_history(&mut editor, cx).unwrap();
editor.navigate(nav_entry.data.unwrap(), cx);
assert_eq!(nav_entry.item.id(), cx.entity_id());
assert_eq!(
editor.selections.display_ranges(cx),
- &[DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0)]
+ &[DisplayPoint::new(DisplayRow(3), 0)..DisplayPoint::new(DisplayRow(3), 0)]
);
assert!(pop_history(&mut editor, cx).is_none());
// Move the cursor a small distance via the mouse.
// Nothing is added to the navigation history.
- editor.begin_selection(DisplayPoint::new(5, 0), false, 1, cx);
+ editor.begin_selection(DisplayPoint::new(DisplayRow(5), 0), false, 1, cx);
editor.end_selection(cx);
assert_eq!(
editor.selections.display_ranges(cx),
- &[DisplayPoint::new(5, 0)..DisplayPoint::new(5, 0)]
+ &[DisplayPoint::new(DisplayRow(5), 0)..DisplayPoint::new(DisplayRow(5), 0)]
);
assert!(pop_history(&mut editor, cx).is_none());
// Move the cursor a large distance via the mouse.
// The history can jump back to the previous position.
- editor.begin_selection(DisplayPoint::new(15, 0), false, 1, cx);
+ editor.begin_selection(DisplayPoint::new(DisplayRow(15), 0), false, 1, cx);
editor.end_selection(cx);
assert_eq!(
editor.selections.display_ranges(cx),
- &[DisplayPoint::new(15, 0)..DisplayPoint::new(15, 0)]
+ &[DisplayPoint::new(DisplayRow(15), 0)..DisplayPoint::new(DisplayRow(15), 0)]
);
let nav_entry = pop_history(&mut editor, cx).unwrap();
editor.navigate(nav_entry.data.unwrap(), cx);
assert_eq!(nav_entry.item.id(), cx.entity_id());
assert_eq!(
editor.selections.display_ranges(cx),
- &[DisplayPoint::new(5, 0)..DisplayPoint::new(5, 0)]
+ &[DisplayPoint::new(DisplayRow(5), 0)..DisplayPoint::new(DisplayRow(5), 0)]
);
assert!(pop_history(&mut editor, cx).is_none());
@@ -649,7 +655,7 @@ async fn test_navigation_history(cx: &mut TestAppContext) {
);
assert_eq!(
editor.scroll_position(cx),
- gpui::Point::new(0., editor.max_point(cx).row() as f32)
+ gpui::Point::new(0., editor.max_point(cx).row().as_f32())
);
editor
@@ -667,18 +673,18 @@ fn test_cancel(cx: &mut TestAppContext) {
});
_ = view.update(cx, |view, cx| {
- view.begin_selection(DisplayPoint::new(3, 4), false, 1, cx);
+ view.begin_selection(DisplayPoint::new(DisplayRow(3), 4), false, 1, cx);
view.update_selection(
- DisplayPoint::new(1, 1),
+ DisplayPoint::new(DisplayRow(1), 1),
0,
gpui::Point::<f32>::default(),
cx,
);
view.end_selection(cx);
- view.begin_selection(DisplayPoint::new(0, 1), true, 1, cx);
+ view.begin_selection(DisplayPoint::new(DisplayRow(0), 1), true, 1, cx);
view.update_selection(
- DisplayPoint::new(0, 3),
+ DisplayPoint::new(DisplayRow(0), 3),
0,
gpui::Point::<f32>::default(),
cx,
@@ -687,8 +693,8 @@ fn test_cancel(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
[
- DisplayPoint::new(0, 1)..DisplayPoint::new(0, 3),
- DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1),
+ DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(0), 3),
+ DisplayPoint::new(DisplayRow(3), 4)..DisplayPoint::new(DisplayRow(1), 1),
]
);
});
@@ -697,7 +703,7 @@ fn test_cancel(cx: &mut TestAppContext) {
view.cancel(&Cancel, cx);
assert_eq!(
view.selections.display_ranges(cx),
- [DisplayPoint::new(3, 4)..DisplayPoint::new(1, 1)]
+ [DisplayPoint::new(DisplayRow(3), 4)..DisplayPoint::new(DisplayRow(1), 1)]
);
});
@@ -705,7 +711,7 @@ fn test_cancel(cx: &mut TestAppContext) {
view.cancel(&Cancel, cx);
assert_eq!(
view.selections.display_ranges(cx),
- [DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1)]
+ [DisplayPoint::new(DisplayRow(1), 1)..DisplayPoint::new(DisplayRow(1), 1)]
);
});
}
@@ -741,7 +747,9 @@ fn test_fold_action(cx: &mut TestAppContext) {
_ = view.update(cx, |view, cx| {
view.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(8, 0)..DisplayPoint::new(12, 0)]);
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(8), 0)..DisplayPoint::new(DisplayRow(12), 0)
+ ]);
});
view.fold(&Fold, cx);
assert_eq!(
@@ -820,58 +828,60 @@ fn test_move_cursor(cx: &mut TestAppContext) {
_ = view.update(cx, |view, cx| {
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)]
+ &[DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0)]
);
view.move_down(&MoveDown, cx);
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]
+ &[DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0)]
);
view.move_right(&MoveRight, cx);
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4)]
+ &[DisplayPoint::new(DisplayRow(1), 4)..DisplayPoint::new(DisplayRow(1), 4)]
);
view.move_left(&MoveLeft, cx);
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]
+ &[DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0)]
);
view.move_up(&MoveUp, cx);
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)]
+ &[DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0)]
);
view.move_to_end(&MoveToEnd, cx);
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(5, 6)..DisplayPoint::new(5, 6)]
+ &[DisplayPoint::new(DisplayRow(5), 6)..DisplayPoint::new(DisplayRow(5), 6)]
);
view.move_to_beginning(&MoveToBeginning, cx);
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)]
+ &[DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0)]
);
view.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(0, 1)..DisplayPoint::new(0, 2)]);
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(0), 2)
+ ]);
});
view.select_to_beginning(&SelectToBeginning, cx);
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(0, 1)..DisplayPoint::new(0, 0)]
+ &[DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(0), 0)]
);
view.select_to_end(&SelectToEnd, cx);
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(0, 1)..DisplayPoint::new(5, 6)]
+ &[DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(5), 6)]
);
});
}
@@ -1060,8 +1070,8 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) {
_ = view.update(cx, |view, cx| {
view.change_selections(None, cx, |s| {
s.select_display_ranges([
- DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
- DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4),
+ DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(0), 1),
+ DisplayPoint::new(DisplayRow(1), 4)..DisplayPoint::new(DisplayRow(1), 4),
]);
});
});
@@ -1071,8 +1081,8 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
&[
- DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
- DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2),
+ DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0),
+ DisplayPoint::new(DisplayRow(1), 2)..DisplayPoint::new(DisplayRow(1), 2),
]
);
});
@@ -1082,8 +1092,8 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
&[
- DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
- DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
+ DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0),
+ DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0),
]
);
});
@@ -1093,8 +1103,8 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
&[
- DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
- DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2),
+ DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0),
+ DisplayPoint::new(DisplayRow(1), 2)..DisplayPoint::new(DisplayRow(1), 2),
]
);
});
@@ -1104,8 +1114,8 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
&[
- DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
- DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5),
+ DisplayPoint::new(DisplayRow(0), 3)..DisplayPoint::new(DisplayRow(0), 3),
+ DisplayPoint::new(DisplayRow(1), 5)..DisplayPoint::new(DisplayRow(1), 5),
]
);
});
@@ -1116,8 +1126,8 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
&[
- DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
- DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5),
+ DisplayPoint::new(DisplayRow(0), 3)..DisplayPoint::new(DisplayRow(0), 3),
+ DisplayPoint::new(DisplayRow(1), 5)..DisplayPoint::new(DisplayRow(1), 5),
]
);
});
@@ -1133,8 +1143,8 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
&[
- DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0),
- DisplayPoint::new(1, 4)..DisplayPoint::new(1, 2),
+ DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 0),
+ DisplayPoint::new(DisplayRow(1), 4)..DisplayPoint::new(DisplayRow(1), 2),
]
);
});
@@ -1149,8 +1159,8 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
&[
- DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0),
- DisplayPoint::new(1, 4)..DisplayPoint::new(1, 0),
+ DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 0),
+ DisplayPoint::new(DisplayRow(1), 4)..DisplayPoint::new(DisplayRow(1), 0),
]
);
});
@@ -1165,8 +1175,8 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
&[
- DisplayPoint::new(0, 2)..DisplayPoint::new(0, 0),
- DisplayPoint::new(1, 4)..DisplayPoint::new(1, 2),
+ DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 0),
+ DisplayPoint::new(DisplayRow(1), 4)..DisplayPoint::new(DisplayRow(1), 2),
]
);
});
@@ -1181,8 +1191,8 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
&[
- DisplayPoint::new(0, 2)..DisplayPoint::new(0, 3),
- DisplayPoint::new(1, 4)..DisplayPoint::new(1, 5),
+ DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 3),
+ DisplayPoint::new(DisplayRow(1), 4)..DisplayPoint::new(DisplayRow(1), 5),
]
);
});
@@ -1193,8 +1203,8 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
&[
- DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
- DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4),
+ DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 2),
+ DisplayPoint::new(DisplayRow(1), 4)..DisplayPoint::new(DisplayRow(1), 4),
]
);
});
@@ -1205,8 +1215,8 @@ fn test_beginning_end_of_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
&[
- DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
- DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
+ DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0),
+ DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0),
]
);
});
@@ -1246,41 +1256,45 @@ fn test_beginning_end_of_line_ignore_soft_wrap(cx: &mut TestAppContext) {
// First, let's assert behavior on the first line, that was not soft-wrapped.
// Start the cursor at the `k` on the first line
view.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(0, 7)..DisplayPoint::new(0, 7)]);
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(0), 7)..DisplayPoint::new(DisplayRow(0), 7)
+ ]);
});
// Moving to the beginning of the line should put us at the beginning of the line.
view.move_to_beginning_of_line(&move_to_beg, cx);
assert_eq!(
- vec![DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),],
+ vec![DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0),],
view.selections.display_ranges(cx)
);
// Moving to the end of the line should put us at the end of the line.
view.move_to_end_of_line(&move_to_end, cx);
assert_eq!(
- vec![DisplayPoint::new(0, 16)..DisplayPoint::new(0, 16),],
+ vec![DisplayPoint::new(DisplayRow(0), 16)..DisplayPoint::new(DisplayRow(0), 16),],
view.selections.display_ranges(cx)
);
// Now, let's assert behavior on the second line, that ended up being soft-wrapped.
// Start the cursor at the last line (`y` that was wrapped to a new line)
view.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(2, 0)..DisplayPoint::new(2, 0)]);
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(2), 0)..DisplayPoint::new(DisplayRow(2), 0)
+ ]);
});
// Moving to the beginning of the line should put us at the start of the second line of
// display text, i.e., the `j`.
view.move_to_beginning_of_line(&move_to_beg, cx);
assert_eq!(
- vec![DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),],
+ vec![DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0),],
view.selections.display_ranges(cx)
);
// Moving to the beginning of the line again should be a no-op.
view.move_to_beginning_of_line(&move_to_beg, cx);
assert_eq!(
- vec![DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),],
+ vec![DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0),],
view.selections.display_ranges(cx)
);
@@ -1288,14 +1302,14 @@ fn test_beginning_end_of_line_ignore_soft_wrap(cx: &mut TestAppContext) {
// next display line.
view.move_to_end_of_line(&move_to_end, cx);
assert_eq!(
- vec![DisplayPoint::new(2, 5)..DisplayPoint::new(2, 5),],
+ vec![DisplayPoint::new(DisplayRow(2), 5)..DisplayPoint::new(DisplayRow(2), 5),],
view.selections.display_ranges(cx)
);
// Moving to the end of the line again should be a no-op.
view.move_to_end_of_line(&move_to_end, cx);
assert_eq!(
- vec![DisplayPoint::new(2, 5)..DisplayPoint::new(2, 5),],
+ vec![DisplayPoint::new(DisplayRow(2), 5)..DisplayPoint::new(DisplayRow(2), 5),],
view.selections.display_ranges(cx)
);
});
@@ -1312,8 +1326,8 @@ fn test_prev_next_word_boundary(cx: &mut TestAppContext) {
_ = view.update(cx, |view, cx| {
view.change_selections(None, cx, |s| {
s.select_display_ranges([
- DisplayPoint::new(0, 11)..DisplayPoint::new(0, 11),
- DisplayPoint::new(2, 4)..DisplayPoint::new(2, 4),
+ DisplayPoint::new(DisplayRow(0), 11)..DisplayPoint::new(DisplayRow(0), 11),
+ DisplayPoint::new(DisplayRow(2), 4)..DisplayPoint::new(DisplayRow(2), 4),
])
});
@@ -1370,43 +1384,45 @@ fn test_prev_next_word_bounds_with_soft_wrap(cx: &mut TestAppContext) {
);
view.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(1, 7)..DisplayPoint::new(1, 7)]);
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(1), 7)..DisplayPoint::new(DisplayRow(1), 7)
+ ]);
});
view.move_to_next_word_end(&MoveToNextWordEnd, cx);
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(1, 9)..DisplayPoint::new(1, 9)]
+ &[DisplayPoint::new(DisplayRow(1), 9)..DisplayPoint::new(DisplayRow(1), 9)]
);
view.move_to_next_word_end(&MoveToNextWordEnd, cx);
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(1, 14)..DisplayPoint::new(1, 14)]
+ &[DisplayPoint::new(DisplayRow(1), 14)..DisplayPoint::new(DisplayRow(1), 14)]
);
view.move_to_next_word_end(&MoveToNextWordEnd, cx);
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(2, 4)..DisplayPoint::new(2, 4)]
+ &[DisplayPoint::new(DisplayRow(2), 4)..DisplayPoint::new(DisplayRow(2), 4)]
);
view.move_to_next_word_end(&MoveToNextWordEnd, cx);
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(2, 8)..DisplayPoint::new(2, 8)]
+ &[DisplayPoint::new(DisplayRow(2), 8)..DisplayPoint::new(DisplayRow(2), 8)]
);
view.move_to_previous_word_start(&MoveToPreviousWordStart, cx);
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(2, 4)..DisplayPoint::new(2, 4)]
+ &[DisplayPoint::new(DisplayRow(2), 4)..DisplayPoint::new(DisplayRow(2), 4)]
);
view.move_to_previous_word_start(&MoveToPreviousWordStart, cx);
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(1, 14)..DisplayPoint::new(1, 14)]
+ &[DisplayPoint::new(DisplayRow(1), 14)..DisplayPoint::new(DisplayRow(1), 14)]
);
});
}
@@ -1806,9 +1822,9 @@ fn test_delete_to_word_boundary(cx: &mut TestAppContext) {
view.change_selections(None, cx, |s| {
s.select_display_ranges([
// an empty selection - the preceding word fragment is deleted
- DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
+ DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 2),
// characters selected - they are deleted
- DisplayPoint::new(0, 9)..DisplayPoint::new(0, 12),
+ DisplayPoint::new(DisplayRow(0), 9)..DisplayPoint::new(DisplayRow(0), 12),
])
});
view.delete_to_previous_word_start(&DeleteToPreviousWordStart, cx);
@@ -1819,9 +1835,9 @@ fn test_delete_to_word_boundary(cx: &mut TestAppContext) {
view.change_selections(None, cx, |s| {
s.select_display_ranges([
// an empty selection - the following word fragment is deleted
- DisplayPoint::new(0, 3)..DisplayPoint::new(0, 3),
+ DisplayPoint::new(DisplayRow(0), 3)..DisplayPoint::new(DisplayRow(0), 3),
// characters selected - they are deleted
- DisplayPoint::new(0, 9)..DisplayPoint::new(0, 10),
+ DisplayPoint::new(DisplayRow(0), 9)..DisplayPoint::new(DisplayRow(0), 10),
])
});
view.delete_to_next_word_end(&DeleteToNextWordEnd, cx);
@@ -1841,9 +1857,9 @@ fn test_newline(cx: &mut TestAppContext) {
_ = view.update(cx, |view, cx| {
view.change_selections(None, cx, |s| {
s.select_display_ranges([
- DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
- DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2),
- DisplayPoint::new(1, 6)..DisplayPoint::new(1, 6),
+ DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 2),
+ DisplayPoint::new(DisplayRow(1), 2)..DisplayPoint::new(DisplayRow(1), 2),
+ DisplayPoint::new(DisplayRow(1), 6)..DisplayPoint::new(DisplayRow(1), 6),
])
});
@@ -2603,9 +2619,9 @@ fn test_delete_line(cx: &mut TestAppContext) {
_ = view.update(cx, |view, cx| {
view.change_selections(None, cx, |s| {
s.select_display_ranges([
- DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
- DisplayPoint::new(1, 0)..DisplayPoint::new(1, 1),
- DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0),
+ DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(0), 1),
+ DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 1),
+ DisplayPoint::new(DisplayRow(3), 0)..DisplayPoint::new(DisplayRow(3), 0),
])
});
view.delete_line(&DeleteLine, cx);
@@ -2613,8 +2629,8 @@ fn test_delete_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
vec![
- DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0),
- DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)
+ DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0),
+ DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(0), 1)
]
);
});
@@ -2625,13 +2641,15 @@ fn test_delete_line(cx: &mut TestAppContext) {
});
_ = view.update(cx, |view, cx| {
view.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(2, 0)..DisplayPoint::new(0, 1)])
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(2), 0)..DisplayPoint::new(DisplayRow(0), 1)
+ ])
});
view.delete_line(&DeleteLine, cx);
assert_eq!(view.display_text(cx), "ghi\n");
assert_eq!(
view.selections.display_ranges(cx),
- vec![DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1)]
+ vec![DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(0), 1)]
);
});
}
@@ -2843,7 +2861,7 @@ async fn test_custom_newlines_cause_no_false_positive_diffs(
.buffer()
.read(cx)
.snapshot(cx)
- .git_diff_hunks_in_range(0..u32::MAX)
+ .git_diff_hunks_in_range(MultiBufferRow::MIN..MultiBufferRow::MAX)
.collect::<Vec<_>>(),
Vec::new(),
"Should not have any diffs for files with custom newlines"
@@ -3284,10 +3302,10 @@ fn test_duplicate_line(cx: &mut TestAppContext) {
_ = view.update(cx, |view, cx| {
view.change_selections(None, cx, |s| {
s.select_display_ranges([
- DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1),
- DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
- DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
- DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0),
+ DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 1),
+ DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 2),
+ DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0),
+ DisplayPoint::new(DisplayRow(3), 0)..DisplayPoint::new(DisplayRow(3), 0),
])
});
view.duplicate_line_down(&DuplicateLineDown, cx);
@@ -3295,10 +3313,10 @@ fn test_duplicate_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
vec![
- DisplayPoint::new(1, 0)..DisplayPoint::new(1, 1),
- DisplayPoint::new(1, 2)..DisplayPoint::new(1, 2),
- DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0),
- DisplayPoint::new(6, 0)..DisplayPoint::new(6, 0),
+ DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 1),
+ DisplayPoint::new(DisplayRow(1), 2)..DisplayPoint::new(DisplayRow(1), 2),
+ DisplayPoint::new(DisplayRow(3), 0)..DisplayPoint::new(DisplayRow(3), 0),
+ DisplayPoint::new(DisplayRow(6), 0)..DisplayPoint::new(DisplayRow(6), 0),
]
);
});
@@ -3310,8 +3328,8 @@ fn test_duplicate_line(cx: &mut TestAppContext) {
_ = view.update(cx, |view, cx| {
view.change_selections(None, cx, |s| {
s.select_display_ranges([
- DisplayPoint::new(0, 1)..DisplayPoint::new(1, 1),
- DisplayPoint::new(1, 2)..DisplayPoint::new(2, 1),
+ DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(1), 1),
+ DisplayPoint::new(DisplayRow(1), 2)..DisplayPoint::new(DisplayRow(2), 1),
])
});
view.duplicate_line_down(&DuplicateLineDown, cx);
@@ -3319,8 +3337,8 @@ fn test_duplicate_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
vec![
- DisplayPoint::new(3, 1)..DisplayPoint::new(4, 1),
- DisplayPoint::new(4, 2)..DisplayPoint::new(5, 1),
+ DisplayPoint::new(DisplayRow(3), 1)..DisplayPoint::new(DisplayRow(4), 1),
+ DisplayPoint::new(DisplayRow(4), 2)..DisplayPoint::new(DisplayRow(5), 1),
]
);
});
@@ -3334,10 +3352,10 @@ fn test_duplicate_line(cx: &mut TestAppContext) {
_ = view.update(cx, |view, cx| {
view.change_selections(None, cx, |s| {
s.select_display_ranges([
- DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1),
- DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
- DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
- DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0),
+ DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 1),
+ DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 2),
+ DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0),
+ DisplayPoint::new(DisplayRow(3), 0)..DisplayPoint::new(DisplayRow(3), 0),
])
});
view.duplicate_line_up(&DuplicateLineUp, cx);
@@ -3345,10 +3363,10 @@ fn test_duplicate_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
vec![
- DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1),
- DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
- DisplayPoint::new(2, 0)..DisplayPoint::new(2, 0),
- DisplayPoint::new(6, 0)..DisplayPoint::new(6, 0),
+ DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 1),
+ DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 2),
+ DisplayPoint::new(DisplayRow(2), 0)..DisplayPoint::new(DisplayRow(2), 0),
+ DisplayPoint::new(DisplayRow(6), 0)..DisplayPoint::new(DisplayRow(6), 0),
]
);
});
@@ -3360,8 +3378,8 @@ fn test_duplicate_line(cx: &mut TestAppContext) {
_ = view.update(cx, |view, cx| {
view.change_selections(None, cx, |s| {
s.select_display_ranges([
- DisplayPoint::new(0, 1)..DisplayPoint::new(1, 1),
- DisplayPoint::new(1, 2)..DisplayPoint::new(2, 1),
+ DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(1), 1),
+ DisplayPoint::new(DisplayRow(1), 2)..DisplayPoint::new(DisplayRow(2), 1),
])
});
view.duplicate_line_up(&DuplicateLineUp, cx);
@@ -3369,8 +3387,8 @@ fn test_duplicate_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
vec![
- DisplayPoint::new(0, 1)..DisplayPoint::new(1, 1),
- DisplayPoint::new(1, 2)..DisplayPoint::new(2, 1),
+ DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(1), 1),
+ DisplayPoint::new(DisplayRow(1), 2)..DisplayPoint::new(DisplayRow(2), 1),
]
);
});
@@ -3396,10 +3414,10 @@ fn test_move_line_up_down(cx: &mut TestAppContext) {
);
view.change_selections(None, cx, |s| {
s.select_display_ranges([
- DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
- DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1),
- DisplayPoint::new(3, 2)..DisplayPoint::new(4, 3),
- DisplayPoint::new(5, 0)..DisplayPoint::new(5, 2),
+ DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(0), 1),
+ DisplayPoint::new(DisplayRow(3), 1)..DisplayPoint::new(DisplayRow(3), 1),
+ DisplayPoint::new(DisplayRow(3), 2)..DisplayPoint::new(DisplayRow(4), 3),
+ DisplayPoint::new(DisplayRow(5), 0)..DisplayPoint::new(DisplayRow(5), 2),
])
});
assert_eq!(
@@ -3415,10 +3433,10 @@ fn test_move_line_up_down(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
vec![
- DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
- DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
- DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3),
- DisplayPoint::new(4, 0)..DisplayPoint::new(4, 2)
+ DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(0), 1),
+ DisplayPoint::new(DisplayRow(2), 1)..DisplayPoint::new(DisplayRow(2), 1),
+ DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(3), 3),
+ DisplayPoint::new(DisplayRow(4), 0)..DisplayPoint::new(DisplayRow(4), 2)
]
);
});
@@ -3432,10 +3450,10 @@ fn test_move_line_up_down(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
vec![
- DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
- DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1),
- DisplayPoint::new(3, 2)..DisplayPoint::new(4, 3),
- DisplayPoint::new(5, 0)..DisplayPoint::new(5, 2)
+ DisplayPoint::new(DisplayRow(1), 1)..DisplayPoint::new(DisplayRow(1), 1),
+ DisplayPoint::new(DisplayRow(3), 1)..DisplayPoint::new(DisplayRow(3), 1),
+ DisplayPoint::new(DisplayRow(3), 2)..DisplayPoint::new(DisplayRow(4), 3),
+ DisplayPoint::new(DisplayRow(5), 0)..DisplayPoint::new(DisplayRow(5), 2)
]
);
});
@@ -3449,10 +3467,10 @@ fn test_move_line_up_down(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
vec![
- DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
- DisplayPoint::new(3, 1)..DisplayPoint::new(3, 1),
- DisplayPoint::new(3, 2)..DisplayPoint::new(4, 3),
- DisplayPoint::new(5, 0)..DisplayPoint::new(5, 2)
+ DisplayPoint::new(DisplayRow(2), 1)..DisplayPoint::new(DisplayRow(2), 1),
+ DisplayPoint::new(DisplayRow(3), 1)..DisplayPoint::new(DisplayRow(3), 1),
+ DisplayPoint::new(DisplayRow(3), 2)..DisplayPoint::new(DisplayRow(4), 3),
+ DisplayPoint::new(DisplayRow(5), 0)..DisplayPoint::new(DisplayRow(5), 2)
]
);
});
@@ -3466,10 +3484,10 @@ fn test_move_line_up_down(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
vec![
- DisplayPoint::new(1, 1)..DisplayPoint::new(1, 1),
- DisplayPoint::new(2, 1)..DisplayPoint::new(2, 1),
- DisplayPoint::new(2, 2)..DisplayPoint::new(3, 3),
- DisplayPoint::new(4, 0)..DisplayPoint::new(4, 2)
+ DisplayPoint::new(DisplayRow(1), 1)..DisplayPoint::new(DisplayRow(1), 1),
+ DisplayPoint::new(DisplayRow(2), 1)..DisplayPoint::new(DisplayRow(2), 1),
+ DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(3), 3),
+ DisplayPoint::new(DisplayRow(4), 0)..DisplayPoint::new(DisplayRow(4), 2)
]
);
});
@@ -3808,7 +3826,7 @@ fn test_select_all(cx: &mut TestAppContext) {
view.select_all(&SelectAll, cx);
assert_eq!(
view.selections.display_ranges(cx),
- &[DisplayPoint::new(0, 0)..DisplayPoint::new(2, 3)]
+ &[DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(2), 3)]
);
});
}
@@ -3824,18 +3842,18 @@ fn test_select_line(cx: &mut TestAppContext) {
_ = view.update(cx, |view, cx| {
view.change_selections(None, cx, |s| {
s.select_display_ranges([
- DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1),
- DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
- DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
- DisplayPoint::new(4, 2)..DisplayPoint::new(4, 2),
+ DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 1),
+ DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 2),
+ DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0),
+ DisplayPoint::new(DisplayRow(4), 2)..DisplayPoint::new(DisplayRow(4), 2),
])
});
view.select_line(&SelectLine, cx);
assert_eq!(
view.selections.display_ranges(cx),
vec![
- DisplayPoint::new(0, 0)..DisplayPoint::new(2, 0),
- DisplayPoint::new(4, 0)..DisplayPoint::new(5, 0),
+ DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(2), 0),
+ DisplayPoint::new(DisplayRow(4), 0)..DisplayPoint::new(DisplayRow(5), 0),
]
);
});
@@ -3845,8 +3863,8 @@ fn test_select_line(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
vec![
- DisplayPoint::new(0, 0)..DisplayPoint::new(3, 0),
- DisplayPoint::new(4, 0)..DisplayPoint::new(5, 5),
+ DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(3), 0),
+ DisplayPoint::new(DisplayRow(4), 0)..DisplayPoint::new(DisplayRow(5), 5),
]
);
});
@@ -3855,7 +3873,7 @@ fn test_select_line(cx: &mut TestAppContext) {
view.select_line(&SelectLine, cx);
assert_eq!(
view.selections.display_ranges(cx),
- vec![DisplayPoint::new(0, 0)..DisplayPoint::new(5, 5)]
+ vec![DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(5), 5)]
);
});
}
@@ -3880,10 +3898,10 @@ fn test_split_selection_into_lines(cx: &mut TestAppContext) {
);
view.change_selections(None, cx, |s| {
s.select_display_ranges([
- DisplayPoint::new(0, 0)..DisplayPoint::new(0, 1),
- DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
- DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0),
- DisplayPoint::new(4, 4)..DisplayPoint::new(4, 4),
+ DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 1),
+ DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 2),
+ DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0),
+ DisplayPoint::new(DisplayRow(4), 4)..DisplayPoint::new(DisplayRow(4), 4),
])
});
assert_eq!(view.display_text(cx), "aaāÆbbb\ncccāÆeeee\nfffff\nggggg\nāÆi");
@@ -3898,17 +3916,19 @@ fn test_split_selection_into_lines(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
[
- DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1),
- DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2),
- DisplayPoint::new(2, 0)..DisplayPoint::new(2, 0),
- DisplayPoint::new(5, 4)..DisplayPoint::new(5, 4)
+ DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(0), 1),
+ DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 2),
+ DisplayPoint::new(DisplayRow(2), 0)..DisplayPoint::new(DisplayRow(2), 0),
+ DisplayPoint::new(DisplayRow(5), 4)..DisplayPoint::new(DisplayRow(5), 4)
]
);
});
_ = view.update(cx, |view, cx| {
view.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(5, 0)..DisplayPoint::new(0, 1)])
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(5), 0)..DisplayPoint::new(DisplayRow(0), 1)
+ ])
});
view.split_selection_into_lines(&SplitSelectionIntoLines, cx);
assert_eq!(
@@ -3918,14 +3938,14 @@ fn test_split_selection_into_lines(cx: &mut TestAppContext) {
assert_eq!(
view.selections.display_ranges(cx),
[
- DisplayPoint::new(0, 5)..DisplayPoint::new(0, 5),
- DisplayPoint::new(1, 5)..DisplayPoint::new(1, 5),
- DisplayPoint::new(2, 5)..DisplayPoint::new(2, 5),
- DisplayPoint::new(3, 5)..DisplayPoint::new(3, 5),
- DisplayPoint::new(4, 5)..DisplayPoint::new(4, 5),
- DisplayPoint::new(5, 5)..DisplayPoint::new(5, 5),
- DisplayPoint::new(6, 5)..DisplayPoint::new(6, 5),
- DisplayPoint::new(7, 0)..DisplayPoint::new(7, 0)
+ DisplayPoint::new(DisplayRow(0), 5)..DisplayPoint::new(DisplayRow(0), 5),
+ DisplayPoint::new(DisplayRow(1), 5)..DisplayPoint::new(DisplayRow(1), 5),
+ DisplayPoint::new(DisplayRow(2), 5)..DisplayPoint::new(DisplayRow(2), 5),
+ DisplayPoint::new(DisplayRow(3), 5)..DisplayPoint::new(DisplayRow(3), 5),
+ DisplayPoint::new(DisplayRow(4), 5)..DisplayPoint::new(DisplayRow(4), 5),
+ DisplayPoint::new(DisplayRow(5), 5)..DisplayPoint::new(DisplayRow(5), 5),
+ DisplayPoint::new(DisplayRow(6), 5)..DisplayPoint::new(DisplayRow(6), 5),
+ DisplayPoint::new(DisplayRow(7), 0)..DisplayPoint::new(DisplayRow(7), 0)
]
);
});
@@ -4429,9 +4449,9 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) {
_ = view.update(cx, |view, cx| {
view.change_selections(None, cx, |s| {
s.select_display_ranges([
- DisplayPoint::new(0, 25)..DisplayPoint::new(0, 25),
- DisplayPoint::new(2, 24)..DisplayPoint::new(2, 12),
- DisplayPoint::new(3, 18)..DisplayPoint::new(3, 18),
+ DisplayPoint::new(DisplayRow(0), 25)..DisplayPoint::new(DisplayRow(0), 25),
+ DisplayPoint::new(DisplayRow(2), 24)..DisplayPoint::new(DisplayRow(2), 12),
+ DisplayPoint::new(DisplayRow(3), 18)..DisplayPoint::new(DisplayRow(3), 18),
]);
});
view.select_larger_syntax_node(&SelectLargerSyntaxNode, cx);
@@ -9,14 +9,15 @@ use crate::{
hover_popover::{
self, hover_at, HOVER_POPOVER_GAP, MIN_POPOVER_CHARACTER_WIDTH, MIN_POPOVER_LINE_HEIGHT,
},
+ hunk_status,
items::BufferSearchHighlights,
mouse_context_menu::{self, MouseContextMenu},
scroll::scroll_amount::ScrollAmount,
- CodeActionsMenu, CursorShape, DisplayPoint, DocumentHighlightRead, DocumentHighlightWrite,
- Editor, EditorMode, EditorSettings, EditorSnapshot, EditorStyle, ExpandExcerpts,
- GutterDimensions, HalfPageDown, HalfPageUp, HoveredCursor, HunkToExpand, LineDown, LineUp,
- OpenExcerpts, PageDown, PageUp, Point, SelectPhase, Selection, SoftWrap, ToPoint,
- CURSORS_VISIBLE_FOR, MAX_LINE_LEN,
+ CodeActionsMenu, CursorShape, DisplayPoint, DisplayRow, DocumentHighlightRead,
+ DocumentHighlightWrite, Editor, EditorMode, EditorSettings, EditorSnapshot, EditorStyle,
+ ExpandExcerpts, GutterDimensions, HalfPageDown, HalfPageUp, HoveredCursor, HunkToExpand,
+ LineDown, LineUp, OpenExcerpts, PageDown, PageUp, Point, RowExt, RowRangeExt, SelectPhase,
+ Selection, SoftWrap, ToPoint, CURSORS_VISIBLE_FOR, MAX_LINE_LEN,
};
use anyhow::Result;
use client::ParticipantIndex;
@@ -35,7 +36,7 @@ use gpui::{
use itertools::Itertools;
use language::language_settings::ShowWhitespaceSetting;
use lsp::DiagnosticSeverity;
-use multi_buffer::Anchor;
+use multi_buffer::{Anchor, MultiBufferPoint, MultiBufferRow};
use project::{
project_settings::{GitGutterSetting, ProjectSettings},
ProjectPath,
@@ -64,7 +65,7 @@ struct SelectionLayout {
is_newest: bool,
is_local: bool,
range: Range<DisplayPoint>,
- active_rows: Range<u32>,
+ active_rows: Range<DisplayRow>,
user_name: Option<SharedString>,
}
@@ -98,16 +99,19 @@ impl SelectionLayout {
{
if head.column() > 0 {
head = map.clip_point(DisplayPoint::new(head.row(), head.column() - 1), Bias::Left)
- } else if head.row() > 0 && head != map.max_point() {
+ } else if head.row().0 > 0 && head != map.max_point() {
head = map.clip_point(
- DisplayPoint::new(head.row() - 1, map.line_len(head.row() - 1)),
+ DisplayPoint::new(
+ head.row().previous_row(),
+ map.line_len(head.row().previous_row()),
+ ),
Bias::Left,
);
// updating range.end is a no-op unless you're cursor is
// on the newline containing a multi-buffer divider
// in which case the clip_point may have moved the head up
// an additional row.
- range.end = DisplayPoint::new(head.row() + 1, 0);
+ range.end = DisplayPoint::new(head.row().next_row(), 0);
active_rows.end = head.row();
}
}
@@ -129,6 +133,8 @@ pub struct EditorElement {
style: EditorStyle,
}
+type DisplayRowDelta = u32;
+
impl EditorElement {
pub fn new(editor: &View<Editor>, style: EditorStyle) -> Self {
Self {
@@ -706,12 +712,12 @@ impl EditorElement {
start_anchor: Anchor,
end_anchor: Anchor,
snapshot: &EditorSnapshot,
- start_row: u32,
- end_row: u32,
+ start_row: DisplayRow,
+ end_row: DisplayRow,
cx: &mut WindowContext,
) -> (
Vec<(PlayerColor, Vec<SelectionLayout>)>,
- BTreeMap<u32, bool>,
+ BTreeMap<DisplayRow, bool>,
Option<DisplayPoint>,
) {
let mut selections: Vec<(PlayerColor, Vec<SelectionLayout>)> = Vec::new();
@@ -743,10 +749,11 @@ impl EditorElement {
newest_selection_head = Some(layout.head);
}
- for row in cmp::max(layout.active_rows.start, start_row)
- ..=cmp::min(layout.active_rows.end, end_row)
+ for row in cmp::max(layout.active_rows.start.0, start_row.0)
+ ..=cmp::min(layout.active_rows.end.0, end_row.0)
{
- let contains_non_empty_selection = active_rows.entry(row).or_insert(!is_empty);
+ let contains_non_empty_selection =
+ active_rows.entry(DisplayRow(row)).or_insert(!is_empty);
*contains_non_empty_selection |= !is_empty;
}
layouts.push(layout);
@@ -826,7 +833,7 @@ impl EditorElement {
snapshot: &EditorSnapshot,
content_origin: gpui::Point<Pixels>,
visible_anchor_range: Range<Anchor>,
- visible_display_row_range: Range<u32>,
+ visible_display_row_range: Range<DisplayRow>,
scroll_pixel_position: gpui::Point<Pixels>,
line_height: Pixels,
line_layouts: &[LineWithInvisibles],
@@ -842,13 +849,14 @@ impl EditorElement {
let row = display_range.start.row();
debug_assert!(row < visible_display_row_range.end);
let line_layout = line_layouts
- .get((row - visible_display_row_range.start) as usize)
+ .get(row.minus(visible_display_row_range.start) as usize)
.map(|l| &l.line)?;
let start_x = content_origin.x
+ line_layout.x_for_index(display_range.start.column() as usize)
- scroll_pixel_position.x;
- let start_y = content_origin.y + row as f32 * line_height - scroll_pixel_position.y;
+ let start_y =
+ content_origin.y + row.as_f32() * line_height - scroll_pixel_position.y;
let end_x = content_origin.x
+ line_layout.x_for_index(display_range.end.column() as usize)
- scroll_pixel_position.x;
@@ -927,7 +935,7 @@ impl EditorElement {
&self,
snapshot: &EditorSnapshot,
selections: &[(PlayerColor, Vec<SelectionLayout>)],
- visible_display_row_range: Range<u32>,
+ visible_display_row_range: Range<DisplayRow>,
line_layouts: &[LineWithInvisibles],
text_hitbox: &Hitbox,
content_origin: gpui::Point<Pixels>,
@@ -951,7 +959,7 @@ impl EditorElement {
}
let cursor_row_layout = &line_layouts
- [(cursor_position.row() - visible_display_row_range.start) as usize]
+ [cursor_position.row().minus(visible_display_row_range.start) as usize]
.line;
let cursor_column = cursor_position.column() as usize;
@@ -999,7 +1007,8 @@ impl EditorElement {
};
let x = cursor_character_x - scroll_pixel_position.x;
- let y = (cursor_position.row() as f32 - scroll_pixel_position.y / line_height)
+ let y = (cursor_position.row().as_f32()
+ - scroll_pixel_position.y / line_height)
* line_height;
if selection.is_newest {
editor.pixel_position_of_newest_cursor = Some(point(
@@ -1009,7 +1018,7 @@ impl EditorElement {
if autoscroll_containing_element {
let top = text_hitbox.origin.y
- + (cursor_position.row() as f32 - scroll_position.y - 3.).max(0.)
+ + (cursor_position.row().as_f32() - scroll_position.y - 3.).max(0.)
* line_height;
let left = text_hitbox.origin.x
+ (cursor_position.column() as f32 - scroll_position.x - 3.)
@@ -1017,7 +1026,7 @@ impl EditorElement {
* em_width;
let bottom = text_hitbox.origin.y
- + (cursor_position.row() as f32 - scroll_position.y + 4.)
+ + (cursor_position.row().as_f32() - scroll_position.y + 4.)
* line_height;
let right = text_hitbox.origin.x
+ (cursor_position.column() as f32 - scroll_position.x + 4.)
@@ -1040,7 +1049,7 @@ impl EditorElement {
let cursor_name = selection.user_name.clone().map(|name| CursorName {
string: name,
color: self.style.background,
- is_top_row: cursor_position.row() == 0,
+ is_top_row: cursor_position.row().0 == 0,
});
cursor.layout(content_origin, cursor_name, cx);
cursors.push(cursor);
@@ -1112,10 +1121,10 @@ impl EditorElement {
);
let height = bounds.size.height;
- let total_rows = snapshot.max_point().row() as f32 + rows_per_page;
+ let total_rows = snapshot.max_point().row().as_f32() + rows_per_page;
let px_per_row = height / total_rows;
let thumb_height = (rows_per_page * px_per_row).max(ScrollbarLayout::MIN_THUMB_HEIGHT);
- let row_height = (height - thumb_height) / snapshot.max_point().row() as f32;
+ let row_height = (height - thumb_height) / snapshot.max_point().row().as_f32();
Some(ScrollbarLayout {
hitbox: cx.insert_hitbox(track_bounds, false),
@@ -1129,7 +1138,7 @@ impl EditorElement {
#[allow(clippy::too_many_arguments)]
fn layout_gutter_fold_indicators(
&self,
- fold_statuses: Vec<Option<(FoldStatus, u32, bool)>>,
+ fold_statuses: Vec<Option<(FoldStatus, MultiBufferRow, bool)>>,
line_height: Pixels,
gutter_dimensions: &GutterDimensions,
gutter_settings: crate::editor_settings::Gutter,
@@ -1181,18 +1190,22 @@ impl EditorElement {
&self,
line_height: Pixels,
gutter_hitbox: &Hitbox,
- display_rows: Range<u32>,
+ display_rows: Range<DisplayRow>,
snapshot: &EditorSnapshot,
cx: &mut WindowContext,
) -> Vec<(DisplayDiffHunk, Option<Hitbox>)> {
let buffer_snapshot = &snapshot.buffer_snapshot;
- let buffer_start_row = DisplayPoint::new(display_rows.start, 0)
- .to_point(snapshot)
- .row;
- let buffer_end_row = DisplayPoint::new(display_rows.end, 0)
- .to_point(snapshot)
- .row;
+ let buffer_start_row = MultiBufferRow(
+ DisplayPoint::new(display_rows.start, 0)
+ .to_point(snapshot)
+ .row,
+ );
+ let buffer_end_row = MultiBufferRow(
+ DisplayPoint::new(display_rows.end, 0)
+ .to_point(snapshot)
+ .row,
+ );
let expanded_hunk_display_rows = self.editor.update(cx, |editor, _| {
editor
@@ -1249,7 +1262,7 @@ impl EditorElement {
#[allow(clippy::too_many_arguments)]
fn layout_inline_blame(
&self,
- display_row: u32,
+ display_row: DisplayRow,
display_snapshot: &DisplaySnapshot,
line_layout: &LineWithInvisibles,
em_width: Pixels,
@@ -1273,7 +1286,7 @@ impl EditorElement {
.map(|(w, _)| w.clone());
let display_point = DisplayPoint::new(display_row, 0);
- let buffer_row = display_point.to_point(display_snapshot).row;
+ let buffer_row = MultiBufferRow(display_point.to_point(display_snapshot).row);
let blame = self.editor.read(cx).blame.clone()?;
let blame_entry = blame
@@ -1286,7 +1299,7 @@ impl EditorElement {
render_inline_blame_entry(&blame, blame_entry, &self.style, workspace, cx);
let start_y = content_origin.y
- + line_height * (display_row as f32 - scroll_pixel_position.y / line_height);
+ + line_height * (display_row.as_f32() - scroll_pixel_position.y / line_height);
let start_x = {
const INLINE_BLAME_PADDING_EM_WIDTHS: f32 = 6.;
@@ -1315,7 +1328,7 @@ impl EditorElement {
#[allow(clippy::too_many_arguments)]
fn layout_blame_entries(
&self,
- buffer_rows: impl Iterator<Item = Option<u32>>,
+ buffer_rows: impl Iterator<Item = Option<MultiBufferRow>>,
em_width: Pixels,
scroll_position: gpui::Point<f32>,
line_height: Pixels,
@@ -1399,7 +1412,7 @@ impl EditorElement {
actions
.tasks
.as_ref()
- .map(|tasks| tasks.position.row)
+ .map(|tasks| tasks.position.to_display_point(snapshot).row())
.or_else(|| *deployed_from_indicator)
} else {
None
@@ -1407,19 +1420,16 @@ impl EditorElement {
editor
.tasks
.iter()
- .filter_map(|((_, row), (multibuffer_offset, _))| {
- if snapshot.is_line_folded(*row) {
+ .filter_map(|(_, (multibuffer_offset, _))| {
+ let multibuffer_point = multibuffer_offset.to_point(&snapshot.buffer_snapshot);
+ let multibuffer_row = MultiBufferRow(multibuffer_point.row);
+ if snapshot.is_line_folded(multibuffer_row) {
return None;
}
- let display_row = snapshot
- .buffer_snapshot
- .offset_to_point(*multibuffer_offset)
- .to_display_point(&snapshot.display_snapshot)
- .row();
-
+ let display_row = multibuffer_point.to_display_point(snapshot).row();
let button = editor.render_run_indicator(
&self.style,
- Some(*row) == active_task_indicator_row,
+ Some(display_row) == active_task_indicator_row,
display_row,
cx,
);
@@ -1489,10 +1499,10 @@ impl EditorElement {
fn calculate_relative_line_numbers(
&self,
snapshot: &EditorSnapshot,
- rows: &Range<u32>,
- relative_to: Option<u32>,
- ) -> HashMap<u32, u32> {
- let mut relative_rows: HashMap<u32, u32> = Default::default();
+ rows: &Range<DisplayRow>,
+ relative_to: Option<DisplayRow>,
+ ) -> HashMap<DisplayRow, DisplayRowDelta> {
+ let mut relative_rows: HashMap<DisplayRow, DisplayRowDelta> = Default::default();
let Some(relative_to) = relative_to else {
return relative_rows;
};
@@ -1501,17 +1511,17 @@ impl EditorElement {
let end = rows.end.max(relative_to);
let buffer_rows = snapshot
- .buffer_rows(start)
- .take(1 + (end - start) as usize)
+ .display_rows(start)
+ .take(1 + end.minus(start) as usize)
.collect::<Vec<_>>();
- let head_idx = relative_to - start;
+ let head_idx = relative_to.minus(start);
let mut delta = 1;
let mut i = head_idx + 1;
while i < buffer_rows.len() as u32 {
if buffer_rows[i as usize].is_some() {
- if rows.contains(&(i + start)) {
- relative_rows.insert(i + start, delta);
+ if rows.contains(&DisplayRow(i + start.0)) {
+ relative_rows.insert(DisplayRow(i + start.0), delta);
}
delta += 1;
}
@@ -1526,8 +1536,8 @@ impl EditorElement {
while i > 0 {
i -= 1;
if buffer_rows[i as usize].is_some() {
- if rows.contains(&(i + start)) {
- relative_rows.insert(i + start, delta);
+ if rows.contains(&DisplayRow(i + start.0)) {
+ relative_rows.insert(DisplayRow(i + start.0), delta);
}
delta += 1;
}
@@ -1538,15 +1548,15 @@ impl EditorElement {
fn layout_line_numbers(
&self,
- rows: Range<u32>,
- buffer_rows: impl Iterator<Item = Option<u32>>,
- active_rows: &BTreeMap<u32, bool>,
+ rows: Range<DisplayRow>,
+ buffer_rows: impl Iterator<Item = Option<DisplayRow>>,
+ active_rows: &BTreeMap<DisplayRow, bool>,
newest_selection_head: Option<DisplayPoint>,
snapshot: &EditorSnapshot,
cx: &WindowContext,
) -> (
Vec<Option<ShapedLine>>,
- Vec<Option<(FoldStatus, BufferRow, bool)>>,
+ Vec<Option<(FoldStatus, MultiBufferRow, bool)>>,
) {
let editor = self.editor.read(cx);
let is_singleton = editor.is_singleton(cx);
@@ -1581,20 +1591,20 @@ impl EditorElement {
let relative_rows = self.calculate_relative_line_numbers(snapshot, &rows, relative_to);
for (ix, row) in buffer_rows.into_iter().enumerate() {
- let display_row = rows.start + ix as u32;
+ let display_row = DisplayRow(rows.start.0 + ix as u32);
let (active, color) = if active_rows.contains_key(&display_row) {
(true, cx.theme().colors().editor_active_line_number)
} else {
(false, cx.theme().colors().editor_line_number)
};
- if let Some(buffer_row) = row {
+ if let Some(display_row) = row {
if include_line_numbers {
line_number.clear();
- let default_number = buffer_row + 1;
+ let default_number = display_row.0 + 1;
let number = relative_rows
- .get(&(ix as u32 + rows.start))
+ .get(&DisplayRow(ix as u32 + rows.start.0))
.unwrap_or(&default_number);
- write!(&mut line_number, "{}", number).unwrap();
+ write!(&mut line_number, "{number}").unwrap();
let run = TextRun {
len: line_number.len(),
font: self.style.text.font(),
@@ -1613,9 +1623,12 @@ impl EditorElement {
fold_statuses.push(
is_singleton
.then(|| {
+ let multibuffer_point =
+ DisplayPoint::new(display_row, 0).to_point(snapshot);
+ let multibuffer_row = MultiBufferRow(multibuffer_point.row);
snapshot
- .fold_for_line(buffer_row)
- .map(|fold_status| (fold_status, buffer_row, active))
+ .fold_for_line(multibuffer_row)
+ .map(|fold_status| (fold_status, multibuffer_row, active))
})
.flatten(),
)
@@ -1631,7 +1644,7 @@ impl EditorElement {
fn layout_lines(
&self,
- rows: Range<u32>,
+ rows: Range<DisplayRow>,
line_number_layouts: &[Option<ShapedLine>],
snapshot: &EditorSnapshot,
cx: &WindowContext,
@@ -1650,7 +1663,7 @@ impl EditorElement {
.as_ref()
.map_or("", AsRef::as_ref)
.split('\n')
- .skip(rows.start as usize)
+ .skip(rows.start.0 as usize)
.chain(iter::repeat(""))
.take(rows.len());
placeholder_lines
@@ -1689,7 +1702,7 @@ impl EditorElement {
#[allow(clippy::too_many_arguments)]
fn build_blocks(
&self,
- rows: Range<u32>,
+ rows: Range<DisplayRow>,
snapshot: &EditorSnapshot,
hitbox: &Hitbox,
text_hitbox: &Hitbox,
@@ -1712,7 +1725,7 @@ impl EditorElement {
let render_block = |block: &TransformBlock,
available_space: Size<AvailableSpace>,
block_id: usize,
- block_row_start: u32,
+ block_row_start: DisplayRow,
cx: &mut WindowContext| {
let mut element = match block {
TransformBlock::Custom(block) => {
@@ -1722,7 +1735,7 @@ impl EditorElement {
.to_display_point(snapshot);
let anchor_x = text_x
+ if rows.contains(&align_to.row()) {
- line_layouts[(align_to.row() - rows.start) as usize]
+ line_layouts[align_to.row().minus(rows.start) as usize]
.line
.x_for_index(align_to.column() as usize)
} else {
@@ -1788,7 +1801,7 @@ impl EditorElement {
};
let line_offset_from_top =
- block_row_start + *height as u32 + offset_from_excerpt_start
+ block_row_start.0 + *height as u32 + offset_from_excerpt_start
- snapshot
.scroll_anchor
.scroll_position(&snapshot.display_snapshot)
@@ -2040,7 +2053,7 @@ impl EditorElement {
let mut origin = hitbox.origin
+ point(
Pixels::ZERO,
- block.row as f32 * line_height - scroll_pixel_position.y,
+ block.row.as_f32() * line_height - scroll_pixel_position.y,
);
if !matches!(block.style, BlockStyle::Sticky) {
origin += point(-scroll_pixel_position.x, Pixels::ZERO);
@@ -2058,7 +2071,7 @@ impl EditorElement {
hitbox: &Hitbox,
text_hitbox: &Hitbox,
content_origin: gpui::Point<Pixels>,
- start_row: u32,
+ start_row: DisplayRow,
scroll_pixel_position: gpui::Point<Pixels>,
line_layouts: &[LineWithInvisibles],
newest_selection_head: DisplayPoint,
@@ -2084,21 +2097,17 @@ impl EditorElement {
let (x, y) = match position {
crate::ContextMenuOrigin::EditorPoint(point) => {
- let cursor_row_layout = &line_layouts[(point.row() - start_row) as usize].line;
+ let cursor_row_layout = &line_layouts[point.row().minus(start_row) as usize].line;
let x = cursor_row_layout.x_for_index(point.column() as usize)
- scroll_pixel_position.x;
- let y = (point.row() + 1) as f32 * line_height - scroll_pixel_position.y;
+ let y = point.row().next_row().as_f32() * line_height - scroll_pixel_position.y;
(x, y)
}
crate::ContextMenuOrigin::GutterIndicator(row) => {
// Context menu was spawned via a click on a gutter. Ensure it's a bit closer to the indicator than just a plain first column of the
// text field.
- let snapshot = self.editor.update(cx, |this, cx| this.snapshot(cx));
- let row = Point::new(row, 0)
- .to_display_point(&snapshot.display_snapshot)
- .row();
let x = -gutter_overshoot;
- let y = (row + 1) as f32 * line_height - scroll_pixel_position.y;
+ let y = row.next_row().as_f32() * line_height - scroll_pixel_position.y;
(x, y)
}
};
@@ -2143,7 +2152,7 @@ impl EditorElement {
snapshot: &EditorSnapshot,
hitbox: &Hitbox,
text_hitbox: &Hitbox,
- visible_display_row_range: Range<u32>,
+ visible_display_row_range: Range<DisplayRow>,
content_origin: gpui::Point<Pixels>,
scroll_pixel_position: gpui::Point<Pixels>,
line_layouts: &[LineWithInvisibles],
@@ -2184,12 +2193,12 @@ impl EditorElement {
// This is safe because we check on layout whether the required row is available
let hovered_row_layout =
- &line_layouts[(position.row() - visible_display_row_range.start) as usize].line;
+ &line_layouts[position.row().minus(visible_display_row_range.start) as usize].line;
// Compute Hovered Point
let x =
hovered_row_layout.x_for_index(position.column() as usize) - scroll_pixel_position.x;
- let y = position.row() as f32 * line_height - scroll_pixel_position.y;
+ let y = position.row().as_f32() * line_height - scroll_pixel_position.y;
let hovered_point = content_origin + point(x, y);
let mut overall_height = Pixels::ZERO;
@@ -2265,10 +2274,14 @@ impl EditorElement {
if let EditorMode::Full = layout.mode {
let mut active_rows = layout.active_rows.iter().peekable();
while let Some((start_row, contains_non_empty_selection)) = active_rows.next() {
- let mut end_row = *start_row;
- while active_rows.peek().map_or(false, |r| {
- *r.0 == end_row + 1 && r.1 == contains_non_empty_selection
- }) {
+ let mut end_row = start_row.0;
+ while active_rows
+ .peek()
+ .map_or(false, |(active_row, has_selection)| {
+ active_row.0 == end_row + 1
+ && *has_selection == contains_non_empty_selection
+ })
+ {
active_rows.next().unwrap();
end_row += 1;
}
@@ -2277,12 +2290,12 @@ impl EditorElement {
let origin = point(
layout.hitbox.origin.x,
layout.hitbox.origin.y
- + (*start_row as f32 - scroll_top)
+ + (start_row.as_f32() - scroll_top)
* layout.position_map.line_height,
);
let size = size(
layout.hitbox.size.width,
- layout.position_map.line_height * (end_row - start_row + 1) as f32,
+ layout.position_map.line_height * (end_row - start_row.0 + 1) as f32,
);
let active_line_bg = cx.theme().colors().editor_active_line_background;
cx.paint_quad(fill(Bounds { origin, size }, active_line_bg));
@@ -2290,28 +2303,28 @@ impl EditorElement {
}
let mut paint_highlight =
- |highlight_row_start: u32, highlight_row_end: u32, color| {
+ |highlight_row_start: DisplayRow, highlight_row_end: DisplayRow, color| {
let origin = point(
layout.hitbox.origin.x,
layout.hitbox.origin.y
- + (highlight_row_start as f32 - scroll_top)
+ + (highlight_row_start.as_f32() - scroll_top)
* layout.position_map.line_height,
);
let size = size(
layout.hitbox.size.width,
layout.position_map.line_height
- * (highlight_row_end + 1 - highlight_row_start) as f32,
+ * highlight_row_end.next_row().minus(highlight_row_start) as f32,
);
cx.paint_quad(fill(Bounds { origin, size }, color));
};
- let mut current_paint: Option<(Hsla, Range<u32>)> = None;
+ let mut current_paint: Option<(Hsla, Range<DisplayRow>)> = None;
for (&new_row, &new_color) in &layout.highlighted_rows {
match &mut current_paint {
Some((current_color, current_range)) => {
let current_color = *current_color;
- let new_range_started =
- current_color != new_color || current_range.end + 1 != new_row;
+ let new_range_started = current_color != new_color
+ || current_range.end.next_row() != new_row;
if new_range_started {
paint_highlight(
current_range.start,
@@ -2321,7 +2334,7 @@ impl EditorElement {
current_paint = Some((new_color, new_row..new_row));
continue;
} else {
- current_range.end += 1;
+ current_range.end = current_range.end.next_row();
}
}
None => current_paint = Some((new_color, new_row..new_row)),
@@ -2494,7 +2507,7 @@ impl EditorElement {
match hunk {
DisplayDiffHunk::Folded { display_row, .. } => {
- let start_y = *display_row as f32 * line_height - scroll_top;
+ let start_y = display_row.as_f32() * line_height - scroll_top;
let end_y = start_y + line_height;
let width = 0.275 * line_height;
@@ -2527,8 +2540,8 @@ impl EditorElement {
})
.unwrap_or(end_row);
- let start_y = start_row as f32 * line_height - scroll_top;
- let end_y = end_row_in_current_excerpt as f32 * line_height - scroll_top;
+ let start_y = start_row.as_f32() * line_height - scroll_top;
+ let end_y = end_row_in_current_excerpt.as_f32() * line_height - scroll_top;
let width = 0.275 * line_height;
let highlight_origin = bounds.origin + point(-width, start_y);
@@ -2539,7 +2552,7 @@ impl EditorElement {
let row = display_row_range.start;
let offset = line_height / 2.;
- let start_y = row as f32 * line_height - offset - scroll_top;
+ let start_y = row.as_f32() * line_height - offset - scroll_top;
let end_y = start_y + line_height;
let width = 0.35 * line_height;
@@ -2648,7 +2661,7 @@ impl EditorElement {
.show_whitespaces;
for (ix, line_with_invisibles) in layout.position_map.line_layouts.iter().enumerate() {
- let row = layout.visible_display_row_range.start + ix as u32;
+ let row = DisplayRow(layout.visible_display_row_range.start.0 + ix as u32);
line_with_invisibles.draw(
layout,
row,
@@ -2879,20 +2892,22 @@ impl EditorElement {
if scrollbar_settings.git_diff {
let marker_row_ranges = snapshot
.buffer_snapshot
- .git_diff_hunks_in_range(0..max_point.row)
+ .git_diff_hunks_in_range(
+ MultiBufferRow::MIN..MultiBufferRow::MAX,
+ )
.map(|hunk| {
let start_display_row =
- Point::new(hunk.associated_range.start, 0)
+ MultiBufferPoint::new(hunk.associated_range.start.0, 0)
.to_display_point(&snapshot.display_snapshot)
.row();
let mut end_display_row =
- Point::new(hunk.associated_range.end, 0)
+ MultiBufferPoint::new(hunk.associated_range.end.0, 0)
.to_display_point(&snapshot.display_snapshot)
.row();
if end_display_row != start_display_row {
- end_display_row -= 1;
+ end_display_row.0 -= 1;
}
- let color = match hunk.status() {
+ let color = match hunk_status(&hunk) {
DiffHunkStatus::Added => theme.status().created,
DiffHunkStatus::Modified => theme.status().modified,
DiffHunkStatus::Removed => theme.status().deleted,
@@ -3018,7 +3033,8 @@ impl EditorElement {
let row_range = if range.end.column() == 0 {
cmp::max(range.start.row(), start_row)..cmp::min(range.end.row(), end_row)
} else {
- cmp::max(range.start.row(), start_row)..cmp::min(range.end.row() + 1, end_row)
+ cmp::max(range.start.row(), start_row)
+ ..cmp::min(range.end.row().next_row(), end_row)
};
let highlighted_range = HighlightedRange {
@@ -3026,13 +3042,13 @@ impl EditorElement {
line_height: layout.position_map.line_height,
corner_radius,
start_y: layout.content_origin.y
- + row_range.start as f32 * layout.position_map.line_height
+ + row_range.start.as_f32() * layout.position_map.line_height
- layout.position_map.scroll_pixel_position.y,
lines: row_range
- .into_iter()
+ .iter_rows()
.map(|row| {
let line_layout =
- &layout.position_map.line_layouts[(row - start_row) as usize].line;
+ &layout.position_map.line_layouts[row.minus(start_row) as usize].line;
HighlightedRangeLine {
start_x: if row == range.start.row() {
layout.content_origin.x
@@ -3281,14 +3297,20 @@ impl EditorElement {
}
fn max_line_number_width(&self, snapshot: &EditorSnapshot, cx: &WindowContext) -> Pixels {
- let digit_count = (snapshot.max_buffer_row() as f32 + 1.).log10().floor() as usize + 1;
+ let digit_count = snapshot
+ .max_buffer_row()
+ .next_row()
+ .as_f32()
+ .log10()
+ .floor() as usize
+ + 1;
self.column_pixels(digit_count, cx)
}
}
fn prepaint_gutter_button(
button: IconButton,
- row: u32,
+ row: DisplayRow,
line_height: Pixels,
gutter_dimensions: &GutterDimensions,
scroll_pixel_position: gpui::Point<Pixels>,
@@ -3312,7 +3334,7 @@ fn prepaint_gutter_button(
- blame_width;
x += available_width / 2.;
- let mut y = row as f32 * line_height - scroll_pixel_position.y;
+ let mut y = row.as_f32() * line_height - scroll_pixel_position.y;
y += (line_height - indicator_size.height) / 2.;
button.prepaint_as_root(gutter_hitbox.origin + point(x, y), available_space, cx);
@@ -3563,15 +3585,15 @@ impl LineWithInvisibles {
fn draw(
&self,
layout: &EditorLayout,
- row: u32,
+ row: DisplayRow,
content_origin: gpui::Point<Pixels>,
whitespace_setting: ShowWhitespaceSetting,
selection_ranges: &[Range<DisplayPoint>],
cx: &mut WindowContext,
) {
let line_height = layout.position_map.line_height;
- let line_y =
- line_height * (row as f32 - layout.position_map.scroll_pixel_position.y / line_height);
+ let line_y = line_height
+ * (row.as_f32() - layout.position_map.scroll_pixel_position.y / line_height);
let line_origin =
content_origin + gpui::point(-layout.position_map.scroll_pixel_position.x, line_y);
@@ -3596,7 +3618,7 @@ impl LineWithInvisibles {
layout: &EditorLayout,
content_origin: gpui::Point<Pixels>,
line_y: Pixels,
- row: u32,
+ row: DisplayRow,
line_height: Pixels,
whitespace_setting: ShowWhitespaceSetting,
cx: &mut WindowContext,
@@ -3806,19 +3828,20 @@ impl Element for EditorElement {
let mut scroll_position = snapshot.scroll_position();
// The scroll position is a fractional point, the whole number of which represents
// the top of the window in terms of display rows.
- let start_row = scroll_position.y as u32;
+ let start_row = DisplayRow(scroll_position.y as u32);
let height_in_lines = bounds.size.height / line_height;
let max_row = snapshot.max_point().row();
let end_row = cmp::min(
(scroll_position.y + height_in_lines).ceil() as u32,
- max_row + 1,
+ max_row.next_row().0,
);
+ let end_row = DisplayRow(end_row);
let buffer_rows = snapshot
- .buffer_rows(start_row)
+ .display_rows(start_row)
.take((start_row..end_row).len());
- let start_anchor = if start_row == 0 {
+ let start_anchor = if start_row == Default::default() {
Anchor::min()
} else {
snapshot.buffer_snapshot.anchor_before(
@@ -3914,7 +3937,7 @@ impl Element for EditorElement {
if let Some(newest_selection_head) = newest_selection_head {
let display_row = newest_selection_head.row();
if (start_row..end_row).contains(&display_row) {
- let line_layout = &line_layouts[(display_row - start_row) as usize];
+ let line_layout = &line_layouts[display_row.minus(start_row) as usize];
inline_blame = self.layout_inline_blame(
display_row,
&snapshot.display_snapshot,
@@ -3929,7 +3952,11 @@ impl Element for EditorElement {
}
let blamed_display_rows = self.layout_blame_entries(
- buffer_rows,
+ buffer_rows.map(|display_row| {
+ display_row.map(|row| {
+ MultiBufferRow(DisplayPoint::new(row, 0).to_point(&snapshot).row)
+ })
+ }),
em_width,
scroll_position,
line_height,
@@ -3940,7 +3967,7 @@ impl Element for EditorElement {
let scroll_max = point(
((scroll_width - text_hitbox.size.width) / em_width).max(0.0),
- max_row as f32,
+ max_row.as_f32(),
);
self.editor.update(cx, |editor, cx| {
@@ -4041,7 +4068,7 @@ impl Element for EditorElement {
newest_selection_head.to_point(&snapshot.display_snapshot);
let buffer = snapshot
.buffer_snapshot
- .buffer_line_for_row(newest_selection_point.row);
+ .buffer_line_for_row(MultiBufferRow(newest_selection_point.row));
if let Some((buffer, range)) = buffer {
let buffer_id = buffer.remote_id();
let row = range.start.row;
@@ -4263,8 +4290,6 @@ impl IntoElement for EditorElement {
}
}
-type BufferRow = u32;
-
pub struct EditorLayout {
position_map: Arc<PositionMap>,
hitbox: Hitbox,
@@ -4275,9 +4300,9 @@ pub struct EditorLayout {
scrollbar_layout: Option<ScrollbarLayout>,
mode: EditorMode,
wrap_guides: SmallVec<[(Pixels, bool); 2]>,
- visible_display_row_range: Range<u32>,
- active_rows: BTreeMap<u32, bool>,
- highlighted_rows: BTreeMap<u32, Hsla>,
+ visible_display_row_range: Range<DisplayRow>,
+ active_rows: BTreeMap<DisplayRow, bool>,
+ highlighted_rows: BTreeMap<DisplayRow, Hsla>,
line_numbers: Vec<Option<ShapedLine>>,
display_hunks: Vec<(DisplayDiffHunk, Option<Hitbox>)>,
blamed_display_rows: Option<Vec<AnyElement>>,
@@ -4339,7 +4364,7 @@ impl ScrollbarLayout {
fn marker_quads_for_ranges(
&self,
- row_ranges: impl IntoIterator<Item = ColoredRange<u32>>,
+ row_ranges: impl IntoIterator<Item = ColoredRange<DisplayRow>>,
column: Option<usize>,
) -> Vec<PaintQuad> {
struct MinMax {
@@ -4370,7 +4395,7 @@ impl ScrollbarLayout {
)
};
- let row_to_y = |row: u32| row as f32 * self.row_height;
+ let row_to_y = |row: DisplayRow| row.as_f32() * self.row_height;
let mut pixel_ranges = row_ranges
.into_iter()
.map(|range| {
@@ -4475,7 +4500,7 @@ impl PositionMap {
(0, x)
};
- let mut exact_unclipped = DisplayPoint::new(row, column);
+ let mut exact_unclipped = DisplayPoint::new(DisplayRow(row), column);
let previous_valid = self.snapshot.clip_point(exact_unclipped, Bias::Left);
let next_valid = self.snapshot.clip_point(exact_unclipped, Bias::Right);
@@ -4491,14 +4516,14 @@ impl PositionMap {
}
struct BlockLayout {
- row: u32,
+ row: DisplayRow,
element: AnyElement,
available_space: Size<AvailableSpace>,
style: BlockStyle,
}
fn layout_line(
- row: u32,
+ row: DisplayRow,
snapshot: &EditorSnapshot,
style: &EditorStyle,
cx: &WindowContext,
@@ -4835,10 +4860,10 @@ mod tests {
.update_window(*window, |_, cx| {
element
.layout_line_numbers(
- 0..6,
- (0..6).map(Some),
+ DisplayRow(0)..DisplayRow(6),
+ (0..6).map(DisplayRow).map(Some),
&Default::default(),
- Some(DisplayPoint::new(0, 0)),
+ Some(DisplayPoint::new(DisplayRow(0), 0)),
&snapshot,
cx,
)
@@ -4850,39 +4875,51 @@ mod tests {
let relative_rows = window
.update(cx, |editor, cx| {
let snapshot = editor.snapshot(cx);
- element.calculate_relative_line_numbers(&snapshot, &(0..6), Some(3))
+ element.calculate_relative_line_numbers(
+ &snapshot,
+ &(DisplayRow(0)..DisplayRow(6)),
+ Some(DisplayRow(3)),
+ )
})
.unwrap();
- assert_eq!(relative_rows[&0], 3);
- assert_eq!(relative_rows[&1], 2);
- assert_eq!(relative_rows[&2], 1);
+ assert_eq!(relative_rows[&DisplayRow(0)], 3);
+ assert_eq!(relative_rows[&DisplayRow(1)], 2);
+ assert_eq!(relative_rows[&DisplayRow(2)], 1);
// current line has no relative number
- assert_eq!(relative_rows[&4], 1);
- assert_eq!(relative_rows[&5], 2);
+ assert_eq!(relative_rows[&DisplayRow(4)], 1);
+ assert_eq!(relative_rows[&DisplayRow(5)], 2);
// works if cursor is before screen
let relative_rows = window
.update(cx, |editor, cx| {
let snapshot = editor.snapshot(cx);
- element.calculate_relative_line_numbers(&snapshot, &(3..6), Some(1))
+ element.calculate_relative_line_numbers(
+ &snapshot,
+ &(DisplayRow(3)..DisplayRow(6)),
+ Some(DisplayRow(1)),
+ )
})
.unwrap();
assert_eq!(relative_rows.len(), 3);
- assert_eq!(relative_rows[&3], 2);
- assert_eq!(relative_rows[&4], 3);
- assert_eq!(relative_rows[&5], 4);
+ assert_eq!(relative_rows[&DisplayRow(3)], 2);
+ assert_eq!(relative_rows[&DisplayRow(4)], 3);
+ assert_eq!(relative_rows[&DisplayRow(5)], 4);
// works if cursor is after screen
let relative_rows = window
.update(cx, |editor, cx| {
let snapshot = editor.snapshot(cx);
- element.calculate_relative_line_numbers(&snapshot, &(0..3), Some(6))
+ element.calculate_relative_line_numbers(
+ &snapshot,
+ &(DisplayRow(0)..DisplayRow(3)),
+ Some(DisplayRow(6)),
+ )
})
.unwrap();
assert_eq!(relative_rows.len(), 3);
- assert_eq!(relative_rows[&0], 5);
- assert_eq!(relative_rows[&1], 4);
- assert_eq!(relative_rows[&2], 3);
+ assert_eq!(relative_rows[&DisplayRow(0)], 5);
+ assert_eq!(relative_rows[&DisplayRow(1)], 4);
+ assert_eq!(relative_rows[&DisplayRow(2)], 3);
}
#[gpui::test]
@@ -4918,30 +4955,39 @@ mod tests {
let local_selections = &state.selections[0].1;
assert_eq!(local_selections.len(), 3);
// moves cursor back one line
- assert_eq!(local_selections[0].head, DisplayPoint::new(0, 6));
+ assert_eq!(
+ local_selections[0].head,
+ DisplayPoint::new(DisplayRow(0), 6)
+ );
assert_eq!(
local_selections[0].range,
- DisplayPoint::new(0, 0)..DisplayPoint::new(1, 0)
+ DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(1), 0)
);
// moves cursor back one column
assert_eq!(
local_selections[1].range,
- DisplayPoint::new(3, 2)..DisplayPoint::new(3, 3)
+ DisplayPoint::new(DisplayRow(3), 2)..DisplayPoint::new(DisplayRow(3), 3)
+ );
+ assert_eq!(
+ local_selections[1].head,
+ DisplayPoint::new(DisplayRow(3), 2)
);
- assert_eq!(local_selections[1].head, DisplayPoint::new(3, 2));
// leaves cursor on the max point
assert_eq!(
local_selections[2].range,
- DisplayPoint::new(5, 6)..DisplayPoint::new(6, 0)
+ DisplayPoint::new(DisplayRow(5), 6)..DisplayPoint::new(DisplayRow(6), 0)
+ );
+ assert_eq!(
+ local_selections[2].head,
+ DisplayPoint::new(DisplayRow(6), 0)
);
- assert_eq!(local_selections[2].head, DisplayPoint::new(6, 0));
// active lines does not include 1 (even though the range of the selection does)
assert_eq!(
- state.active_rows.keys().cloned().collect::<Vec<u32>>(),
- vec![0, 3, 5, 6]
+ state.active_rows.keys().cloned().collect::<Vec<_>>(),
+ vec![DisplayRow(0), DisplayRow(3), DisplayRow(5), DisplayRow(6)]
);
// multi-buffer support
@@ -4,29 +4,29 @@ use std::ops::Range;
use git::diff::{DiffHunk, DiffHunkStatus};
use language::Point;
-use multi_buffer::Anchor;
+use multi_buffer::{Anchor, MultiBufferRow};
use crate::{
display_map::{DisplaySnapshot, ToDisplayPoint},
- AnchorRangeExt,
+ hunk_status, AnchorRangeExt, DisplayRow,
};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DisplayDiffHunk {
Folded {
- display_row: u32,
+ display_row: DisplayRow,
},
Unfolded {
diff_base_byte_range: Range<usize>,
- display_row_range: Range<u32>,
+ display_row_range: Range<DisplayRow>,
multi_buffer_range: Range<Anchor>,
status: DiffHunkStatus,
},
}
impl DisplayDiffHunk {
- pub fn start_display_row(&self) -> u32 {
+ pub fn start_display_row(&self) -> DisplayRow {
match self {
&DisplayDiffHunk::Folded { display_row } => display_row,
DisplayDiffHunk::Unfolded {
@@ -35,7 +35,7 @@ impl DisplayDiffHunk {
}
}
- pub fn contains_display_row(&self, display_row: u32) -> bool {
+ pub fn contains_display_row(&self, display_row: DisplayRow) -> bool {
let range = match self {
&DisplayDiffHunk::Folded { display_row } => display_row..=display_row,
@@ -48,21 +48,26 @@ impl DisplayDiffHunk {
}
}
-pub fn diff_hunk_to_display(hunk: &DiffHunk<u32>, snapshot: &DisplaySnapshot) -> DisplayDiffHunk {
- let hunk_start_point = Point::new(hunk.associated_range.start, 0);
- let hunk_start_point_sub = Point::new(hunk.associated_range.start.saturating_sub(1), 0);
+pub fn diff_hunk_to_display(
+ hunk: &DiffHunk<MultiBufferRow>,
+ snapshot: &DisplaySnapshot,
+) -> DisplayDiffHunk {
+ let hunk_start_point = Point::new(hunk.associated_range.start.0, 0);
+ let hunk_start_point_sub = Point::new(hunk.associated_range.start.0.saturating_sub(1), 0);
let hunk_end_point_sub = Point::new(
hunk.associated_range
.end
+ .0
.saturating_sub(1)
- .max(hunk.associated_range.start),
+ .max(hunk.associated_range.start.0),
0,
);
- let is_removal = hunk.status() == DiffHunkStatus::Removed;
+ let status = hunk_status(hunk);
+ let is_removal = status == DiffHunkStatus::Removed;
- let folds_start = Point::new(hunk.associated_range.start.saturating_sub(2), 0);
- let folds_end = Point::new(hunk.associated_range.end + 2, 0);
+ let folds_start = Point::new(hunk.associated_range.start.0.saturating_sub(2), 0);
+ let folds_end = Point::new(hunk.associated_range.end.0 + 2, 0);
let folds_range = folds_start..folds_end;
let containing_fold = snapshot.folds_in_range(folds_range).find(|fold| {
@@ -83,7 +88,7 @@ pub fn diff_hunk_to_display(hunk: &DiffHunk<u32>, snapshot: &DisplaySnapshot) ->
let start = hunk_start_point.to_display_point(snapshot).row();
let hunk_end_row = hunk.associated_range.end.max(hunk.associated_range.start);
- let hunk_end_point = Point::new(hunk_end_row, 0);
+ let hunk_end_point = Point::new(hunk_end_row.0, 0);
let multi_buffer_start = snapshot.buffer_snapshot.anchor_after(hunk_start_point);
let multi_buffer_end = snapshot.buffer_snapshot.anchor_before(hunk_end_point);
@@ -92,7 +97,7 @@ pub fn diff_hunk_to_display(hunk: &DiffHunk<u32>, snapshot: &DisplaySnapshot) ->
DisplayDiffHunk::Unfolded {
display_row_range: start..end,
multi_buffer_range: multi_buffer_start..multi_buffer_end,
- status: hunk.status(),
+ status,
diff_base_byte_range: hunk.diff_base_byte_range.clone(),
}
}
@@ -100,11 +105,11 @@ pub fn diff_hunk_to_display(hunk: &DiffHunk<u32>, snapshot: &DisplaySnapshot) ->
#[cfg(test)]
mod tests {
- use crate::editor_tests::init_test;
use crate::Point;
+ use crate::{editor_tests::init_test, hunk_status};
use gpui::{Context, TestAppContext};
use language::Capability::ReadWrite;
- use multi_buffer::{ExcerptRange, MultiBuffer};
+ use multi_buffer::{ExcerptRange, MultiBuffer, MultiBufferRow};
use project::{FakeFs, Project};
use unindent::Unindent;
#[gpui::test]
@@ -257,26 +262,41 @@ mod tests {
);
let expected = [
- (DiffHunkStatus::Modified, 1..2),
- (DiffHunkStatus::Modified, 2..3),
+ (
+ DiffHunkStatus::Modified,
+ MultiBufferRow(1)..MultiBufferRow(2),
+ ),
+ (
+ DiffHunkStatus::Modified,
+ MultiBufferRow(2)..MultiBufferRow(3),
+ ),
//TODO: Define better when and where removed hunks show up at range extremities
- (DiffHunkStatus::Removed, 6..6),
- (DiffHunkStatus::Removed, 8..8),
- (DiffHunkStatus::Added, 10..11),
+ (
+ DiffHunkStatus::Removed,
+ MultiBufferRow(6)..MultiBufferRow(6),
+ ),
+ (
+ DiffHunkStatus::Removed,
+ MultiBufferRow(8)..MultiBufferRow(8),
+ ),
+ (
+ DiffHunkStatus::Added,
+ MultiBufferRow(10)..MultiBufferRow(11),
+ ),
];
assert_eq!(
snapshot
- .git_diff_hunks_in_range(0..12)
- .map(|hunk| (hunk.status(), hunk.associated_range))
+ .git_diff_hunks_in_range(MultiBufferRow(0)..MultiBufferRow(12))
+ .map(|hunk| (hunk_status(&hunk), hunk.associated_range))
.collect::<Vec<_>>(),
&expected,
);
assert_eq!(
snapshot
- .git_diff_hunks_in_range_rev(0..12)
- .map(|hunk| (hunk.status(), hunk.associated_range))
+ .git_diff_hunks_in_range_rev(MultiBufferRow(0)..MultiBufferRow(12))
+ .map(|hunk| (hunk_status(&hunk), hunk.associated_range))
.collect::<Vec<_>>(),
expected
.iter()
@@ -8,6 +8,7 @@ use git::{
};
use gpui::{Model, ModelContext, Subscription, Task};
use language::{markdown, Bias, Buffer, BufferSnapshot, Edit, LanguageRegistry, ParsedMarkdown};
+use multi_buffer::MultiBufferRow;
use project::{Item, Project};
use smallvec::SmallVec;
use sum_tree::SumTree;
@@ -185,7 +186,7 @@ impl GitBlame {
pub fn blame_for_rows<'a>(
&'a mut self,
- rows: impl 'a + IntoIterator<Item = Option<u32>>,
+ rows: impl 'a + IntoIterator<Item = Option<MultiBufferRow>>,
cx: &mut ModelContext<Self>,
) -> impl 'a + Iterator<Item = Option<BlameEntry>> {
self.sync(cx);
@@ -193,7 +194,7 @@ impl GitBlame {
let mut cursor = self.entries.cursor::<u32>();
rows.into_iter().map(move |row| {
let row = row?;
- cursor.seek_forward(&row, Bias::Right, &());
+ cursor.seek_forward(&row.0, Bias::Right, &());
cursor.item()?.blame.clone()
})
}
@@ -532,7 +533,7 @@ mod tests {
($blame:expr, $rows:expr, $expected:expr, $cx:expr) => {
assert_eq!(
$blame
- .blame_for_rows($rows.map(Some), $cx)
+ .blame_for_rows($rows.map(MultiBufferRow).map(Some), $cx)
.collect::<Vec<_>>(),
$expected
);
@@ -597,7 +598,7 @@ mod tests {
blame.update(cx, |blame, cx| {
assert_eq!(
blame
- .blame_for_rows((0..1).map(Some), cx)
+ .blame_for_rows((0..1).map(MultiBufferRow).map(Some), cx)
.collect::<Vec<_>>(),
vec![None]
);
@@ -661,7 +662,7 @@ mod tests {
// All lines
assert_eq!(
blame
- .blame_for_rows((0..8).map(Some), cx)
+ .blame_for_rows((0..8).map(MultiBufferRow).map(Some), cx)
.collect::<Vec<_>>(),
vec![
Some(blame_entry("1b1b1b", 0..1)),
@@ -677,7 +678,7 @@ mod tests {
// Subset of lines
assert_eq!(
blame
- .blame_for_rows((1..4).map(Some), cx)
+ .blame_for_rows((1..4).map(MultiBufferRow).map(Some), cx)
.collect::<Vec<_>>(),
vec![
Some(blame_entry("0d0d0d", 1..2)),
@@ -688,7 +689,7 @@ mod tests {
// Subset of lines, with some not displayed
assert_eq!(
blame
- .blame_for_rows(vec![Some(1), None, None], cx)
+ .blame_for_rows(vec![Some(MultiBufferRow(1)), None, None], cx)
.collect::<Vec<_>>(),
vec![Some(blame_entry("0d0d0d", 1..2)), None, None]
);
@@ -1,8 +1,8 @@
use crate::{
display_map::{InlayOffset, ToDisplayPoint},
hover_links::{InlayHighlight, RangeInEditor},
- Anchor, AnchorRangeExt, DisplayPoint, Editor, EditorSettings, EditorSnapshot, EditorStyle,
- ExcerptId, Hover, RangeToAnchorExt,
+ Anchor, AnchorRangeExt, DisplayPoint, DisplayRow, Editor, EditorSettings, EditorSnapshot,
+ EditorStyle, ExcerptId, Hover, RangeToAnchorExt,
};
use futures::{stream::FuturesUnordered, FutureExt};
use gpui::{
@@ -440,7 +440,7 @@ impl HoverState {
&mut self,
snapshot: &EditorSnapshot,
style: &EditorStyle,
- visible_rows: Range<u32>,
+ visible_rows: Range<DisplayRow>,
max_size: Size<Pixels>,
workspace: Option<WeakView<Workspace>>,
cx: &mut ViewContext<Editor>,
@@ -7,7 +7,9 @@ use collections::{hash_map, HashMap, HashSet};
use git::diff::{DiffHunk, DiffHunkStatus};
use gpui::{AppContext, Hsla, Model, Task, View};
use language::Buffer;
-use multi_buffer::{Anchor, ExcerptRange, MultiBuffer, MultiBufferSnapshot, ToPoint};
+use multi_buffer::{
+ Anchor, ExcerptRange, MultiBuffer, MultiBufferRow, MultiBufferSnapshot, ToPoint,
+};
use text::{BufferId, Point};
use ui::{
div, ActiveTheme, Context as _, IntoElement, ParentElement, Styled, ViewContext, VisualContext,
@@ -16,9 +18,9 @@ use util::{debug_panic, RangeExt};
use crate::{
git::{diff_hunk_to_display, DisplayDiffHunk},
- hunks_for_selections, BlockDisposition, BlockId, BlockProperties, BlockStyle, DiffRowHighlight,
- Editor, EditorSnapshot, ExpandAllHunkDiffs, RangeToAnchorExt, RevertSelectedHunks,
- ToDisplayPoint, ToggleHunkDiff,
+ hunk_status, hunks_for_selections, BlockDisposition, BlockId, BlockProperties, BlockStyle,
+ DiffRowHighlight, Editor, EditorSnapshot, ExpandAllHunkDiffs, RangeToAnchorExt,
+ RevertSelectedHunks, ToDisplayPoint, ToggleHunkDiff,
};
#[derive(Debug, Clone)]
@@ -90,11 +92,11 @@ impl Editor {
let hunks = snapshot
.display_snapshot
.buffer_snapshot
- .git_diff_hunks_in_range(0..u32::MAX)
+ .git_diff_hunks_in_range(MultiBufferRow::MIN..MultiBufferRow::MAX)
.filter(|hunk| {
- let hunk_display_row_range = Point::new(hunk.associated_range.start, 0)
+ let hunk_display_row_range = Point::new(hunk.associated_range.start.0, 0)
.to_display_point(&snapshot.display_snapshot)
- ..Point::new(hunk.associated_range.end, 0)
+ ..Point::new(hunk.associated_range.end.0, 0)
.to_display_point(&snapshot.display_snapshot);
let row_range_end =
display_rows_with_expanded_hunks.get(&hunk_display_row_range.start.row());
@@ -105,7 +107,7 @@ impl Editor {
fn toggle_hunks_expanded(
&mut self,
- hunks_to_toggle: Vec<DiffHunk<u32>>,
+ hunks_to_toggle: Vec<DiffHunk<MultiBufferRow>>,
cx: &mut ViewContext<Self>,
) {
let previous_toggle_task = self.expanded_hunks.hunk_update_tasks.remove(&None);
@@ -176,10 +178,10 @@ impl Editor {
});
for remaining_hunk in hunks_to_toggle {
let remaining_hunk_point_range =
- Point::new(remaining_hunk.associated_range.start, 0)
- ..Point::new(remaining_hunk.associated_range.end, 0);
+ Point::new(remaining_hunk.associated_range.start.0, 0)
+ ..Point::new(remaining_hunk.associated_range.end.0, 0);
hunks_to_expand.push(HunkToExpand {
- status: remaining_hunk.status(),
+ status: hunk_status(&remaining_hunk),
multi_buffer_range: remaining_hunk_point_range
.to_anchors(&snapshot.buffer_snapshot),
diff_base_byte_range: remaining_hunk.diff_base_byte_range.clone(),
@@ -374,9 +376,10 @@ impl Editor {
}
let snapshot = editor.snapshot(cx);
- let buffer_snapshot = buffer.read(cx).snapshot();
- let mut recalculated_hunks = buffer_snapshot
- .git_diff_hunks_in_row_range(0..u32::MAX)
+ let mut recalculated_hunks = snapshot
+ .buffer_snapshot
+ .git_diff_hunks_in_range(MultiBufferRow::MIN..MultiBufferRow::MAX)
+ .filter(|hunk| hunk.buffer_id == buffer_id)
.fuse()
.peekable();
let mut highlights_to_remove =
@@ -402,7 +405,7 @@ impl Editor {
.to_display_point(&snapshot)
.row();
while let Some(buffer_hunk) = recalculated_hunks.peek() {
- match diff_hunk_to_display(buffer_hunk, &snapshot) {
+ match diff_hunk_to_display(&buffer_hunk, &snapshot) {
DisplayDiffHunk::Folded { display_row } => {
recalculated_hunks.next();
if !expanded_hunk.folded
@@ -441,7 +444,7 @@ impl Editor {
} else {
if !expanded_hunk.folded
&& expanded_hunk_display_range == hunk_display_range
- && expanded_hunk.status == buffer_hunk.status()
+ && expanded_hunk.status == hunk_status(buffer_hunk)
&& expanded_hunk.diff_base_byte_range
== buffer_hunk.diff_base_byte_range
{
@@ -614,15 +617,17 @@ fn editor_with_deleted_text(
editor
});
- let editor_height = editor.update(cx, |editor, cx| editor.max_point(cx).row() as u8);
+ let editor_height = editor.update(cx, |editor, cx| editor.max_point(cx).row().0 as u8);
(editor_height, editor)
}
fn buffer_diff_hunk(
buffer_snapshot: &MultiBufferSnapshot,
row_range: Range<Point>,
-) -> Option<DiffHunk<u32>> {
- let mut hunks = buffer_snapshot.git_diff_hunks_in_range(row_range.start.row..row_range.end.row);
+) -> Option<DiffHunk<MultiBufferRow>> {
+ let mut hunks = buffer_snapshot.git_diff_hunks_in_range(
+ MultiBufferRow(row_range.start.row)..MultiBufferRow(row_range.end.row),
+ );
let hunk = hunks.next()?;
let second_hunk = hunks.next();
if second_hunk.is_none() {
@@ -2,10 +2,12 @@
//! in editor given a given motion (e.g. it handles converting a "move left" command into coordinates in editor). It is exposed mostly for use by vim crate.
use super::{Bias, DisplayPoint, DisplaySnapshot, SelectionGoal, ToDisplayPoint};
-use crate::{char_kind, scroll::ScrollAnchor, CharKind, EditorStyle, ToOffset, ToPoint};
+use crate::{
+ char_kind, scroll::ScrollAnchor, CharKind, DisplayRow, EditorStyle, RowExt, ToOffset, ToPoint,
+};
use gpui::{px, Pixels, WindowTextSystem};
use language::Point;
-use multi_buffer::MultiBufferSnapshot;
+use multi_buffer::{MultiBufferRow, MultiBufferSnapshot};
use serde::Deserialize;
use std::{ops::Range, sync::Arc};
@@ -35,7 +37,7 @@ pub struct TextLayoutDetails {
pub fn left(map: &DisplaySnapshot, mut point: DisplayPoint) -> DisplayPoint {
if point.column() > 0 {
*point.column_mut() -= 1;
- } else if point.row() > 0 {
+ } else if point.row().0 > 0 {
*point.row_mut() -= 1;
*point.column_mut() = map.line_len(point.row());
}
@@ -127,7 +129,7 @@ pub(crate) fn up_by_rows(
_ => map.x_for_display_point(start, text_layout_details),
};
- let prev_row = start.row().saturating_sub(row_count);
+ let prev_row = DisplayRow(start.row().0.saturating_sub(row_count));
let mut point = map.clip_point(
DisplayPoint::new(prev_row, map.line_len(prev_row)),
Bias::Left,
@@ -137,7 +139,7 @@ pub(crate) fn up_by_rows(
} else if preserve_column_at_start {
return (start, goal);
} else {
- point = DisplayPoint::new(0, 0);
+ point = DisplayPoint::new(DisplayRow(0), 0);
goal_x = px(0.);
}
@@ -166,7 +168,7 @@ pub(crate) fn down_by_rows(
_ => map.x_for_display_point(start, text_layout_details),
};
- let new_row = start.row() + row_count;
+ let new_row = DisplayRow(start.row().0 + row_count);
let mut point = map.clip_point(DisplayPoint::new(new_row, 0), Bias::Right);
if point.row() > start.row() {
*point.column_mut() = map.display_column_for_x(point.row(), goal_x, text_layout_details)
@@ -220,7 +222,9 @@ pub fn indented_line_beginning(
let soft_line_start = map.clip_point(DisplayPoint::new(display_point.row(), 0), Bias::Right);
let indent_start = Point::new(
point.row,
- map.buffer_snapshot.indent_size_for_line(point.row).len,
+ map.buffer_snapshot
+ .indent_size_for_line(MultiBufferRow(point.row))
+ .len,
)
.to_display_point(map);
let line_start = map.prev_line_boundary(point).1;
@@ -326,7 +330,7 @@ pub fn start_of_paragraph(
let mut found_non_blank_line = false;
for row in (0..point.row + 1).rev() {
- let blank = map.buffer_snapshot.is_line_blank(row);
+ let blank = map.buffer_snapshot.is_line_blank(MultiBufferRow(row));
if found_non_blank_line && blank {
if count <= 1 {
return Point::new(row, 0).to_display_point(map);
@@ -349,13 +353,13 @@ pub fn end_of_paragraph(
mut count: usize,
) -> DisplayPoint {
let point = display_point.to_point(map);
- if point.row == map.max_buffer_row() {
+ if point.row == map.max_buffer_row().0 {
return map.max_point();
}
let mut found_non_blank_line = false;
- for row in point.row..map.max_buffer_row() + 1 {
- let blank = map.buffer_snapshot.is_line_blank(row);
+ for row in point.row..map.max_buffer_row().next_row().0 {
+ let blank = map.buffer_snapshot.is_line_blank(MultiBufferRow(row));
if found_non_blank_line && blank {
if count <= 1 {
return Point::new(row, 0).to_display_point(map);
@@ -549,13 +553,16 @@ pub fn split_display_range_by_lines(
let mut start = range.start;
// Loop over all the covered rows until the one containing the range end
- for row in range.start.row()..range.end.row() {
- let row_end_column = map.line_len(row);
- let end = map.clip_point(DisplayPoint::new(row, row_end_column), Bias::Left);
+ for row in range.start.row().0..range.end.row().0 {
+ let row_end_column = map.line_len(DisplayRow(row));
+ let end = map.clip_point(
+ DisplayPoint::new(DisplayRow(row), row_end_column),
+ Bias::Left,
+ );
if start != end {
result.push(start..end);
}
- start = map.clip_point(DisplayPoint::new(row + 1, 0), Bias::Left);
+ start = map.clip_point(DisplayPoint::new(DisplayRow(row + 1), 0), Bias::Left);
}
// Add the final range from the start of the last end to the original range end.
@@ -570,7 +577,7 @@ mod tests {
use crate::{
display_map::Inlay,
test::{editor_test_context::EditorTestContext, marked_display_snapshot},
- Buffer, DisplayMap, ExcerptRange, InlayId, MultiBuffer,
+ Buffer, DisplayMap, DisplayRow, ExcerptRange, InlayId, MultiBuffer,
};
use gpui::{font, Context as _};
use language::Capability;
@@ -900,126 +907,126 @@ mod tests {
assert_eq!(snapshot.text(), "\n\nabc\ndefg\n\n\nhijkl\nmn");
- let col_2_x =
- snapshot.x_for_display_point(DisplayPoint::new(2, 2), &text_layout_details);
+ let col_2_x = snapshot
+ .x_for_display_point(DisplayPoint::new(DisplayRow(2), 2), &text_layout_details);
// Can't move up into the first excerpt's header
assert_eq!(
up(
&snapshot,
- DisplayPoint::new(2, 2),
+ DisplayPoint::new(DisplayRow(2), 2),
SelectionGoal::HorizontalPosition(col_2_x.0),
false,
&text_layout_details
),
(
- DisplayPoint::new(2, 0),
+ DisplayPoint::new(DisplayRow(2), 0),
SelectionGoal::HorizontalPosition(0.0)
),
);
assert_eq!(
up(
&snapshot,
- DisplayPoint::new(2, 0),
+ DisplayPoint::new(DisplayRow(2), 0),
SelectionGoal::None,
false,
&text_layout_details
),
(
- DisplayPoint::new(2, 0),
+ DisplayPoint::new(DisplayRow(2), 0),
SelectionGoal::HorizontalPosition(0.0)
),
);
- let col_4_x =
- snapshot.x_for_display_point(DisplayPoint::new(3, 4), &text_layout_details);
+ let col_4_x = snapshot
+ .x_for_display_point(DisplayPoint::new(DisplayRow(3), 4), &text_layout_details);
// Move up and down within first excerpt
assert_eq!(
up(
&snapshot,
- DisplayPoint::new(3, 4),
+ DisplayPoint::new(DisplayRow(3), 4),
SelectionGoal::HorizontalPosition(col_4_x.0),
false,
&text_layout_details
),
(
- DisplayPoint::new(2, 3),
+ DisplayPoint::new(DisplayRow(2), 3),
SelectionGoal::HorizontalPosition(col_4_x.0)
),
);
assert_eq!(
down(
&snapshot,
- DisplayPoint::new(2, 3),
+ DisplayPoint::new(DisplayRow(2), 3),
SelectionGoal::HorizontalPosition(col_4_x.0),
false,
&text_layout_details
),
(
- DisplayPoint::new(3, 4),
+ DisplayPoint::new(DisplayRow(3), 4),
SelectionGoal::HorizontalPosition(col_4_x.0)
),
);
- let col_5_x =
- snapshot.x_for_display_point(DisplayPoint::new(6, 5), &text_layout_details);
+ let col_5_x = snapshot
+ .x_for_display_point(DisplayPoint::new(DisplayRow(6), 5), &text_layout_details);
// Move up and down across second excerpt's header
assert_eq!(
up(
&snapshot,
- DisplayPoint::new(6, 5),
+ DisplayPoint::new(DisplayRow(6), 5),
SelectionGoal::HorizontalPosition(col_5_x.0),
false,
&text_layout_details
),
(
- DisplayPoint::new(3, 4),
+ DisplayPoint::new(DisplayRow(3), 4),
SelectionGoal::HorizontalPosition(col_5_x.0)
),
);
assert_eq!(
down(
&snapshot,
- DisplayPoint::new(3, 4),
+ DisplayPoint::new(DisplayRow(3), 4),
SelectionGoal::HorizontalPosition(col_5_x.0),
false,
&text_layout_details
),
(
- DisplayPoint::new(6, 5),
+ DisplayPoint::new(DisplayRow(6), 5),
SelectionGoal::HorizontalPosition(col_5_x.0)
),
);
- let max_point_x =
- snapshot.x_for_display_point(DisplayPoint::new(7, 2), &text_layout_details);
+ let max_point_x = snapshot
+ .x_for_display_point(DisplayPoint::new(DisplayRow(7), 2), &text_layout_details);
// Can't move down off the end
assert_eq!(
down(
&snapshot,
- DisplayPoint::new(7, 0),
+ DisplayPoint::new(DisplayRow(7), 0),
SelectionGoal::HorizontalPosition(0.0),
false,
&text_layout_details
),
(
- DisplayPoint::new(7, 2),
+ DisplayPoint::new(DisplayRow(7), 2),
SelectionGoal::HorizontalPosition(max_point_x.0)
),
);
assert_eq!(
down(
&snapshot,
- DisplayPoint::new(7, 2),
+ DisplayPoint::new(DisplayRow(7), 2),
SelectionGoal::HorizontalPosition(max_point_x.0),
false,
&text_layout_details
),
(
- DisplayPoint::new(7, 2),
+ DisplayPoint::new(DisplayRow(7), 2),
SelectionGoal::HorizontalPosition(max_point_x.0)
),
);
@@ -6,8 +6,8 @@ use crate::{
display_map::{DisplaySnapshot, ToDisplayPoint},
hover_popover::hide_hover,
persistence::DB,
- Anchor, DisplayPoint, Editor, EditorEvent, EditorMode, EditorSettings, InlayHintRefreshReason,
- MultiBufferSnapshot, ToPoint,
+ Anchor, DisplayPoint, DisplayRow, Editor, EditorEvent, EditorMode, EditorSettings,
+ InlayHintRefreshReason, MultiBufferSnapshot, RowExt, ToPoint,
};
pub use autoscroll::{Autoscroll, AutoscrollStrategy};
use gpui::{point, px, AppContext, Entity, Global, Pixels, Task, ViewContext, WindowContext};
@@ -48,7 +48,7 @@ impl ScrollAnchor {
if self.anchor == Anchor::min() {
scroll_position.y = 0.;
} else {
- let scroll_top = self.anchor.to_display_point(snapshot).row() as f32;
+ let scroll_top = self.anchor.to_display_point(snapshot).row().as_f32();
scroll_position.y = scroll_top + scroll_position.y;
}
scroll_position
@@ -200,7 +200,7 @@ impl ScrollManager {
)
} else {
let scroll_top_buffer_point =
- DisplayPoint::new(scroll_position.y as u32, 0).to_point(&map);
+ DisplayPoint::new(DisplayRow(scroll_position.y as u32), 0).to_point(&map);
let top_anchor = map
.buffer_snapshot
.anchor_at(scroll_top_buffer_point, Bias::Right);
@@ -210,7 +210,7 @@ impl ScrollManager {
anchor: top_anchor,
offset: point(
scroll_position.x.max(0.),
- scroll_position.y - top_anchor.to_display_point(&map).row() as f32,
+ scroll_position.y - top_anchor.to_display_point(&map).row().as_f32(),
),
},
scroll_top_buffer_point.row,
@@ -472,7 +472,7 @@ impl Editor {
}
if let Some(visible_lines) = self.visible_line_count() {
- if newest_head.row() < screen_top.row() + visible_lines as u32 {
+ if newest_head.row() < DisplayRow(screen_top.row().0 + visible_lines as u32) {
return Ordering::Equal;
}
}
@@ -37,7 +37,7 @@ impl Editor {
let scroll_margin_rows = self.vertical_scroll_margin() as u32;
let mut new_screen_top = self.selections.newest_display(cx).head();
- *new_screen_top.row_mut() = new_screen_top.row().saturating_sub(scroll_margin_rows);
+ *new_screen_top.row_mut() = new_screen_top.row().0.saturating_sub(scroll_margin_rows);
*new_screen_top.column_mut() = 0;
let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
@@ -60,7 +60,7 @@ impl Editor {
};
let mut new_screen_top = self.selections.newest_display(cx).head();
- *new_screen_top.row_mut() = new_screen_top.row().saturating_sub(visible_rows / 2);
+ *new_screen_top.row_mut() = new_screen_top.row().0.saturating_sub(visible_rows / 2);
*new_screen_top.column_mut() = 0;
let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
@@ -86,6 +86,7 @@ impl Editor {
let mut new_screen_top = self.selections.newest_display(cx).head();
*new_screen_top.row_mut() = new_screen_top
.row()
+ .0
.saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
*new_screen_top.column_mut() = 0;
let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
@@ -5,7 +5,8 @@ use gpui::{px, Bounds, Pixels, ViewContext};
use language::Point;
use crate::{
- display_map::ToDisplayPoint, DiffRowHighlight, Editor, EditorMode, LineWithInvisibles,
+ display_map::ToDisplayPoint, DiffRowHighlight, DisplayRow, Editor, EditorMode,
+ LineWithInvisibles, RowExt,
};
#[derive(PartialEq, Eq, Clone, Copy)]
@@ -88,9 +89,9 @@ impl Editor {
}
}
let max_scroll_top = if matches!(self.mode, EditorMode::AutoHeight { .. }) {
- (display_map.max_point().row() as f32 - visible_lines + 1.).max(0.)
+ (display_map.max_point().row().as_f32() - visible_lines + 1.).max(0.)
} else {
- display_map.max_point().row() as f32
+ display_map.max_point().row().as_f32()
};
if scroll_position.y > max_scroll_top {
scroll_position.y = max_scroll_top;
@@ -113,7 +114,7 @@ impl Editor {
)
.first_entry()
{
- target_top = *first_highlighted_row.key() as f32;
+ target_top = first_highlighted_row.key().as_f32();
target_bottom = target_top + 1.;
} else {
let selections = self.selections.all::<Point>(cx);
@@ -122,14 +123,16 @@ impl Editor {
.unwrap()
.head()
.to_display_point(&display_map)
- .row() as f32;
+ .row()
+ .as_f32();
target_bottom = selections
.last()
.unwrap()
.head()
.to_display_point(&display_map)
- .row() as f32
- + 1.0;
+ .row()
+ .next_row()
+ .as_f32();
// If the selections can't all fit on screen, scroll to the newest.
if autoscroll == Autoscroll::newest()
@@ -141,7 +144,8 @@ impl Editor {
.unwrap()
.head()
.to_display_point(&display_map)
- .row() as f32;
+ .row()
+ .as_f32();
target_top = newest_selection_top;
target_bottom = newest_selection_top + 1.;
}
@@ -227,7 +231,7 @@ impl Editor {
pub(crate) fn autoscroll_horizontally(
&mut self,
- start_row: u32,
+ start_row: DisplayRow,
viewport_width: Pixels,
scroll_width: Pixels,
max_glyph_width: Pixels,
@@ -245,16 +249,18 @@ impl Editor {
target_right = px(0.);
for selection in selections {
let head = selection.head().to_display_point(&display_map);
- if head.row() >= start_row && head.row() < start_row + layouts.len() as u32 {
+ if head.row() >= start_row
+ && head.row() < DisplayRow(start_row.0 + layouts.len() as u32)
+ {
let start_column = head.column().saturating_sub(3);
let end_column = cmp::min(display_map.line_len(head.row()), head.column() + 3);
target_left = target_left.min(
- layouts[(head.row() - start_row) as usize]
+ layouts[head.row().minus(start_row) as usize]
.line
.x_for_index(start_column as usize),
);
target_right = target_right.max(
- layouts[(head.row() - start_row) as usize]
+ layouts[head.row().minus(start_row) as usize]
.line
.x_for_index(end_column as usize)
+ max_glyph_width,
@@ -14,7 +14,8 @@ use util::post_inc;
use crate::{
display_map::{DisplayMap, DisplaySnapshot, ToDisplayPoint},
movement::TextLayoutDetails,
- Anchor, DisplayPoint, ExcerptId, MultiBuffer, MultiBufferSnapshot, SelectMode, ToOffset,
+ Anchor, DisplayPoint, DisplayRow, ExcerptId, MultiBuffer, MultiBufferSnapshot, SelectMode,
+ ToOffset,
};
#[derive(Debug, Clone)]
@@ -308,7 +309,7 @@ impl SelectionsCollection {
pub fn build_columnar_selection(
&mut self,
display_map: &DisplaySnapshot,
- row: u32,
+ row: DisplayRow,
positions: &Range<Pixels>,
reversed: bool,
text_layout_details: &TextLayoutDetails,
@@ -81,23 +81,30 @@ pub fn editor_hunks(
editor: &Editor,
snapshot: &DisplaySnapshot,
cx: &mut ViewContext<'_, Editor>,
-) -> Vec<(String, git::diff::DiffHunkStatus, core::ops::Range<u32>)> {
+) -> Vec<(
+ String,
+ git::diff::DiffHunkStatus,
+ std::ops::Range<crate::DisplayRow>,
+)> {
+ use multi_buffer::MultiBufferRow;
use text::Point;
+ use crate::hunk_status;
+
snapshot
.buffer_snapshot
- .git_diff_hunks_in_range(0..u32::MAX)
+ .git_diff_hunks_in_range(MultiBufferRow::MIN..MultiBufferRow::MAX)
.map(|hunk| {
- let display_range = Point::new(hunk.associated_range.start, 0)
+ let display_range = Point::new(hunk.associated_range.start.0, 0)
.to_display_point(snapshot)
.row()
- ..Point::new(hunk.associated_range.end, 0)
+ ..Point::new(hunk.associated_range.end.0, 0)
.to_display_point(snapshot)
.row();
let (_, buffer, _) = editor
.buffer()
.read(cx)
- .excerpt_containing(Point::new(hunk.associated_range.start, 0), cx)
+ .excerpt_containing(Point::new(hunk.associated_range.start.0, 0), cx)
.expect("no excerpt for expanded buffer's hunk start");
let diff_base = buffer
.read(cx)
@@ -105,7 +112,7 @@ pub fn editor_hunks(
.expect("should have a diff base for expanded hunk")
.slice(hunk.diff_base_byte_range.clone())
.to_string();
- (diff_base, hunk.status(), display_range)
+ (diff_base, hunk_status(&hunk), display_range)
})
.collect()
}
@@ -115,7 +122,11 @@ pub fn expanded_hunks(
editor: &Editor,
snapshot: &DisplaySnapshot,
cx: &mut ViewContext<'_, Editor>,
-) -> Vec<(String, git::diff::DiffHunkStatus, core::ops::Range<u32>)> {
+) -> Vec<(
+ String,
+ git::diff::DiffHunkStatus,
+ std::ops::Range<crate::DisplayRow>,
+)> {
editor
.expanded_hunks
.hunks(false)
@@ -150,7 +161,9 @@ pub fn expanded_hunks(
pub fn expanded_hunks_background_highlights(
editor: &mut Editor,
cx: &mut gpui::WindowContext,
-) -> Vec<std::ops::RangeInclusive<u32>> {
+) -> Vec<std::ops::RangeInclusive<crate::DisplayRow>> {
+ use crate::DisplayRow;
+
let mut highlights = Vec::new();
let mut range_start = 0;
@@ -159,19 +172,19 @@ pub fn expanded_hunks_background_highlights(
{
match previous_highlighted_row {
Some(previous_row) => {
- if previous_row + 1 != highlighted_row {
- highlights.push(range_start..=previous_row);
- range_start = highlighted_row;
+ if previous_row + 1 != highlighted_row.0 {
+ highlights.push(DisplayRow(range_start)..=DisplayRow(previous_row));
+ range_start = highlighted_row.0;
}
}
None => {
- range_start = highlighted_row;
+ range_start = highlighted_row.0;
}
}
- previous_highlighted_row = Some(highlighted_row);
+ previous_highlighted_row = Some(highlighted_row.0);
}
if let Some(previous_row) = previous_highlighted_row {
- highlights.push(range_start..=previous_row);
+ highlights.push(DisplayRow(range_start)..=DisplayRow(previous_row));
}
highlights
@@ -1,5 +1,6 @@
use crate::{
display_map::ToDisplayPoint, AnchorRangeExt, Autoscroll, DisplayPoint, Editor, MultiBuffer,
+ RowExt,
};
use collections::BTreeMap;
use futures::Future;
@@ -256,7 +257,7 @@ impl EditorTestContext {
let details = editor.text_layout_details(cx);
let y = pixel_position.y
- + line_height * (display_point.row() as f32 - newest_point.row() as f32);
+ + line_height * (display_point.row().as_f32() - newest_point.row().as_f32());
let x = pixel_position.x + snapshot.x_for_display_point(display_point, &details)
- snapshot.x_for_display_point(newest_point, &details);
Point::new(x, y)
@@ -30,18 +30,6 @@ pub struct DiffHunk<T> {
pub diff_base_byte_range: Range<usize>,
}
-impl DiffHunk<u32> {
- pub fn status(&self) -> DiffHunkStatus {
- if self.diff_base_byte_range.is_empty() {
- DiffHunkStatus::Added
- } else if self.associated_range.is_empty() {
- DiffHunkStatus::Removed
- } else {
- DiffHunkStatus::Modified
- }
- }
-}
-
impl sum_tree::Item for DiffHunk<Anchor> {
type Summary = DiffHunkSummary;
@@ -352,6 +352,7 @@ mod tests {
editor
.highlighted_display_rows(HashSet::default(), cx)
.into_keys()
+ .map(|r| r.0)
.collect()
})
}
@@ -75,6 +75,8 @@ pub enum Capability {
ReadOnly,
}
+pub type BufferRow = u32;
+
/// An in-memory representation of a source code file, including its text,
/// syntax trees, git status, and diagnostics.
pub struct Buffer {
@@ -3104,7 +3106,7 @@ impl BufferSnapshot {
/// row range.
pub fn git_diff_hunks_in_row_range(
&self,
- range: Range<u32>,
+ range: Range<BufferRow>,
) -> impl '_ + Iterator<Item = git::diff::DiffHunk<u32>> {
self.git_diff.hunks_in_row_range(range, self)
}
@@ -35,6 +35,7 @@ log.workspace = true
parking_lot.workspace = true
rand.workspace = true
settings.workspace = true
+serde.workspace = true
smallvec.workspace = true
sum_tree.workspace = true
text.workspace = true
@@ -11,9 +11,9 @@ use itertools::Itertools;
use language::{
char_kind,
language_settings::{language_settings, LanguageSettings},
- AutoindentMode, Buffer, BufferChunks, BufferSnapshot, Capability, CharKind, Chunk, CursorShape,
- DiagnosticEntry, File, IndentSize, Language, LanguageScope, OffsetRangeExt, OffsetUtf16,
- Outline, OutlineItem, Point, PointUtf16, Selection, TextDimension, ToOffset as _,
+ AutoindentMode, Buffer, BufferChunks, BufferRow, BufferSnapshot, Capability, CharKind, Chunk,
+ CursorShape, DiagnosticEntry, File, IndentSize, Language, LanguageScope, OffsetRangeExt,
+ OffsetUtf16, Outline, OutlineItem, Point, PointUtf16, Selection, TextDimension, ToOffset as _,
ToOffsetUtf16 as _, ToPoint as _, ToPointUtf16 as _, TransactionId, Unclipped,
};
use smallvec::SmallVec;
@@ -100,6 +100,16 @@ pub enum Event {
DiagnosticsUpdated,
}
+pub type MultiBufferPoint = Point;
+
+#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq, serde::Deserialize)]
+#[serde(transparent)]
+pub struct MultiBufferRow(pub u32);
+
+impl MultiBufferRow {
+ pub const MIN: Self = Self(0);
+ pub const MAX: Self = Self(u32::MAX);
+}
#[derive(Clone)]
struct History {
next_transaction_id: TransactionId,
@@ -165,8 +175,7 @@ pub struct MultiBufferSnapshot {
/// A boundary between [`Excerpt`]s in a [`MultiBuffer`]
pub struct ExcerptBoundary {
pub id: ExcerptId,
- /// The row in the `MultiBuffer` where the boundary is located
- pub row: u32,
+ pub row: MultiBufferRow,
pub buffer: BufferSnapshot,
pub range: ExcerptRange<text::Anchor>,
/// It's possible to have multiple excerpts in the same buffer,
@@ -190,7 +199,7 @@ struct Excerpt {
/// The range of the buffer to be shown in the excerpt
range: ExcerptRange<text::Anchor>,
/// The last row in the excerpted slice of the buffer
- max_buffer_row: u32,
+ max_buffer_row: BufferRow,
/// A summary of the text in the excerpt
text_summary: TextSummary,
has_trailing_newline: bool,
@@ -229,7 +238,7 @@ struct ExcerptSummary {
/// The location of the last [`Excerpt`] being summarized
excerpt_locator: Locator,
/// The maximum row of the [`Excerpt`]s being summarized
- max_buffer_row: u32,
+ max_buffer_row: MultiBufferRow,
text: TextSummary,
}
@@ -2111,8 +2120,8 @@ impl MultiBufferSnapshot {
self.chunks(range, false).map(|chunk| chunk.text)
}
- pub fn is_line_blank(&self, row: u32) -> bool {
- self.text_for_range(Point::new(row, 0)..Point::new(row, self.line_len(row)))
+ pub fn is_line_blank(&self, row: MultiBufferRow) -> bool {
+ self.text_for_range(Point::new(row.0, 0)..Point::new(row.0, self.line_len(row)))
.all(|chunk| chunk.matches(|c: char| !c.is_whitespace()).next().is_none())
}
@@ -2181,7 +2190,7 @@ impl MultiBufferSnapshot {
self.excerpts.summary().text.len == 0
}
- pub fn max_buffer_row(&self) -> u32 {
+ pub fn max_buffer_row(&self) -> MultiBufferRow {
self.excerpts.summary().max_buffer_row
}
@@ -2312,7 +2321,7 @@ impl MultiBufferSnapshot {
}
}
- pub fn buffer_rows(&self, start_row: u32) -> MultiBufferRows {
+ pub fn buffer_rows(&self, start_row: MultiBufferRow) -> MultiBufferRows {
let mut result = MultiBufferRows {
buffer_row_range: 0..0,
excerpts: self.excerpts.cursor(),
@@ -2509,7 +2518,7 @@ impl MultiBufferSnapshot {
&self,
rows: impl IntoIterator<Item = u32>,
cx: &AppContext,
- ) -> BTreeMap<u32, IndentSize> {
+ ) -> BTreeMap<MultiBufferRow, IndentSize> {
let mut result = BTreeMap::new();
let mut rows_for_excerpt = Vec::new();
@@ -2555,16 +2564,19 @@ impl MultiBufferSnapshot {
let buffer_indents = excerpt
.buffer
.suggested_indents(buffer_rows, single_indent_size);
- let multibuffer_indents = buffer_indents
- .into_iter()
- .map(|(row, indent)| (start_multibuffer_row + row - start_buffer_row, indent));
+ let multibuffer_indents = buffer_indents.into_iter().map(|(row, indent)| {
+ (
+ MultiBufferRow(start_multibuffer_row + row - start_buffer_row),
+ indent,
+ )
+ });
result.extend(multibuffer_indents);
}
result
}
- pub fn indent_size_for_line(&self, row: u32) -> IndentSize {
+ pub fn indent_size_for_line(&self, row: MultiBufferRow) -> IndentSize {
if let Some((buffer, range)) = self.buffer_line_for_row(row) {
let mut size = buffer.indent_size_for_line(range.start.row);
size.len = size
@@ -2577,9 +2589,9 @@ impl MultiBufferSnapshot {
}
}
- pub fn prev_non_blank_row(&self, mut row: u32) -> Option<u32> {
- while row > 0 {
- row -= 1;
+ pub fn prev_non_blank_row(&self, mut row: MultiBufferRow) -> Option<MultiBufferRow> {
+ while row.0 > 0 {
+ row.0 -= 1;
if !self.is_line_blank(row) {
return Some(row);
}
@@ -2587,7 +2599,7 @@ impl MultiBufferSnapshot {
None
}
- pub fn line_len(&self, row: u32) -> u32 {
+ pub fn line_len(&self, row: MultiBufferRow) -> u32 {
if let Some((_, range)) = self.buffer_line_for_row(row) {
range.end.column - range.start.column
} else {
@@ -2595,15 +2607,18 @@ impl MultiBufferSnapshot {
}
}
- pub fn buffer_line_for_row(&self, row: u32) -> Option<(&BufferSnapshot, Range<Point>)> {
+ pub fn buffer_line_for_row(
+ &self,
+ row: MultiBufferRow,
+ ) -> Option<(&BufferSnapshot, Range<Point>)> {
let mut cursor = self.excerpts.cursor::<Point>();
- let point = Point::new(row, 0);
+ let point = Point::new(row.0, 0);
cursor.seek(&point, Bias::Right, &());
if cursor.item().is_none() && *cursor.start() == point {
cursor.prev(&());
}
if let Some(excerpt) = cursor.item() {
- let overshoot = row - cursor.start().row;
+ let overshoot = row.0 - cursor.start().row;
let excerpt_start = excerpt.range.context.start.to_point(&excerpt.buffer);
let excerpt_end = excerpt.range.context.end.to_point(&excerpt.buffer);
let buffer_row = excerpt_start.row + overshoot;
@@ -3028,7 +3043,7 @@ impl MultiBufferSnapshot {
let starts_new_buffer = Some(excerpt.buffer_id) != prev_buffer_id;
let boundary = ExcerptBoundary {
id: excerpt.id,
- row: cursor.start().1.row,
+ row: MultiBufferRow(cursor.start().1.row),
buffer: excerpt.buffer.clone(),
range: excerpt.range.clone(),
starts_new_buffer,
@@ -3312,11 +3327,11 @@ impl MultiBufferSnapshot {
pub fn git_diff_hunks_in_range_rev(
&self,
- row_range: Range<u32>,
- ) -> impl Iterator<Item = DiffHunk<u32>> + '_ {
+ row_range: Range<MultiBufferRow>,
+ ) -> impl Iterator<Item = DiffHunk<MultiBufferRow>> + '_ {
let mut cursor = self.excerpts.cursor::<Point>();
- cursor.seek(&Point::new(row_range.end, 0), Bias::Left, &());
+ cursor.seek(&Point::new(row_range.end.0, 0), Bias::Left, &());
if cursor.item().is_none() {
cursor.prev(&());
}
@@ -3325,7 +3340,7 @@ impl MultiBufferSnapshot {
let excerpt = cursor.item()?;
let multibuffer_start = *cursor.start();
let multibuffer_end = multibuffer_start + excerpt.text_summary.lines;
- if multibuffer_start.row >= row_range.end {
+ if multibuffer_start.row >= row_range.end.0 {
return None;
}
@@ -3334,15 +3349,15 @@ impl MultiBufferSnapshot {
let excerpt_start_point = buffer_start.to_point(&excerpt.buffer);
let excerpt_end_point = excerpt_start_point + excerpt.text_summary.lines;
- if row_range.start > multibuffer_start.row {
+ if row_range.start.0 > multibuffer_start.row {
let buffer_start_point =
- excerpt_start_point + Point::new(row_range.start - multibuffer_start.row, 0);
+ excerpt_start_point + Point::new(row_range.start.0 - multibuffer_start.row, 0);
buffer_start = excerpt.buffer.anchor_before(buffer_start_point);
}
- if row_range.end < multibuffer_end.row {
+ if row_range.end.0 < multibuffer_end.row {
let buffer_end_point =
- excerpt_start_point + Point::new(row_range.end - multibuffer_start.row, 0);
+ excerpt_start_point + Point::new(row_range.end.0 - multibuffer_start.row, 0);
buffer_end = excerpt.buffer.anchor_before(buffer_end_point);
}
@@ -3363,7 +3378,7 @@ impl MultiBufferSnapshot {
.saturating_sub(excerpt_start_point.row);
DiffHunk {
- associated_range: start..end,
+ associated_range: MultiBufferRow(start)..MultiBufferRow(end),
diff_base_byte_range: hunk.diff_base_byte_range.clone(),
buffer_range: hunk.buffer_range.clone(),
buffer_id: hunk.buffer_id,
@@ -3379,11 +3394,11 @@ impl MultiBufferSnapshot {
pub fn git_diff_hunks_in_range(
&self,
- row_range: Range<u32>,
- ) -> impl Iterator<Item = DiffHunk<u32>> + '_ {
+ row_range: Range<MultiBufferRow>,
+ ) -> impl Iterator<Item = DiffHunk<MultiBufferRow>> + '_ {
let mut cursor = self.excerpts.cursor::<Point>();
- cursor.seek(&Point::new(row_range.start, 0), Bias::Left, &());
+ cursor.seek(&Point::new(row_range.start.0, 0), Bias::Left, &());
std::iter::from_fn(move || {
let excerpt = cursor.item()?;
@@ -3392,25 +3407,25 @@ impl MultiBufferSnapshot {
let mut buffer_start = excerpt.range.context.start;
let mut buffer_end = excerpt.range.context.end;
- let excerpt_rows = match multibuffer_start.row.cmp(&row_range.end) {
+ let excerpt_rows = match multibuffer_start.row.cmp(&row_range.end.0) {
cmp::Ordering::Less => {
let excerpt_start_point = buffer_start.to_point(&excerpt.buffer);
let excerpt_end_point = excerpt_start_point + excerpt.text_summary.lines;
- if row_range.start > multibuffer_start.row {
+ if row_range.start.0 > multibuffer_start.row {
let buffer_start_point = excerpt_start_point
- + Point::new(row_range.start - multibuffer_start.row, 0);
+ + Point::new(row_range.start.0 - multibuffer_start.row, 0);
buffer_start = excerpt.buffer.anchor_before(buffer_start_point);
}
- if row_range.end < multibuffer_end.row {
+ if row_range.end.0 < multibuffer_end.row {
let buffer_end_point = excerpt_start_point
- + Point::new(row_range.end - multibuffer_start.row, 0);
+ + Point::new(row_range.end.0 - multibuffer_start.row, 0);
buffer_end = excerpt.buffer.anchor_before(buffer_end_point);
}
excerpt_start_point.row..excerpt_end_point.row
}
- cmp::Ordering::Equal if row_range.end == 0 => {
+ cmp::Ordering::Equal if row_range.end.0 == 0 => {
buffer_end = buffer_start;
0..0
}
@@ -3422,7 +3437,7 @@ impl MultiBufferSnapshot {
.git_diff_hunks_intersecting_range(buffer_start..buffer_end)
.map(move |hunk| {
let buffer_range = if excerpt_rows.start == 0 && excerpt_rows.end == 0 {
- 0..1
+ MultiBufferRow(0)..MultiBufferRow(1)
} else {
let start = multibuffer_start.row
+ hunk
@@ -3435,7 +3450,7 @@ impl MultiBufferSnapshot {
.end
.min(excerpt_rows.end + 1)
.saturating_sub(excerpt_rows.start);
- start..end
+ MultiBufferRow(start)..MultiBufferRow(end)
};
DiffHunk {
associated_range: buffer_range,
@@ -4096,7 +4111,7 @@ impl sum_tree::Item for Excerpt {
ExcerptSummary {
excerpt_id: self.id,
excerpt_locator: self.locator.clone(),
- max_buffer_row: self.max_buffer_row,
+ max_buffer_row: MultiBufferRow(self.max_buffer_row),
text,
}
}
@@ -4198,22 +4213,22 @@ impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Option<ExcerptId> {
}
impl<'a> MultiBufferRows<'a> {
- pub fn seek(&mut self, row: u32) {
+ pub fn seek(&mut self, row: MultiBufferRow) {
self.buffer_row_range = 0..0;
self.excerpts
- .seek_forward(&Point::new(row, 0), Bias::Right, &());
+ .seek_forward(&Point::new(row.0, 0), Bias::Right, &());
if self.excerpts.item().is_none() {
self.excerpts.prev(&());
- if self.excerpts.item().is_none() && row == 0 {
+ if self.excerpts.item().is_none() && row.0 == 0 {
self.buffer_row_range = 0..1;
return;
}
}
if let Some(excerpt) = self.excerpts.item() {
- let overshoot = row - self.excerpts.start().row;
+ let overshoot = row.0 - self.excerpts.start().row;
let excerpt_start = excerpt.range.context.start.to_point(&excerpt.buffer).row;
self.buffer_row_range.start = excerpt_start + overshoot;
self.buffer_row_range.end = excerpt_start + excerpt.text_summary.lines.row + 1;
@@ -4546,7 +4561,7 @@ mod tests {
assert_eq!(snapshot.text(), buffer.read(cx).text());
assert_eq!(
- snapshot.buffer_rows(0).collect::<Vec<_>>(),
+ snapshot.buffer_rows(MultiBufferRow(0)).collect::<Vec<_>>(),
(0..buffer.read(cx).row_count())
.map(Some)
.collect::<Vec<_>>()
@@ -4557,7 +4572,7 @@ mod tests {
assert_eq!(snapshot.text(), buffer.read(cx).text());
assert_eq!(
- snapshot.buffer_rows(0).collect::<Vec<_>>(),
+ snapshot.buffer_rows(MultiBufferRow(0)).collect::<Vec<_>>(),
(0..buffer.read(cx).row_count())
.map(Some)
.collect::<Vec<_>>()
@@ -4685,27 +4700,33 @@ mod tests {
)
);
assert_eq!(
- snapshot.buffer_rows(0).collect::<Vec<_>>(),
+ snapshot.buffer_rows(MultiBufferRow(0)).collect::<Vec<_>>(),
[Some(1), Some(2), Some(3), Some(4), Some(3)]
);
assert_eq!(
- snapshot.buffer_rows(2).collect::<Vec<_>>(),
+ snapshot.buffer_rows(MultiBufferRow(2)).collect::<Vec<_>>(),
[Some(3), Some(4), Some(3)]
);
- assert_eq!(snapshot.buffer_rows(4).collect::<Vec<_>>(), [Some(3)]);
- assert_eq!(snapshot.buffer_rows(5).collect::<Vec<_>>(), []);
+ assert_eq!(
+ snapshot.buffer_rows(MultiBufferRow(4)).collect::<Vec<_>>(),
+ [Some(3)]
+ );
+ assert_eq!(
+ snapshot.buffer_rows(MultiBufferRow(5)).collect::<Vec<_>>(),
+ []
+ );
assert_eq!(
boundaries_in_range(Point::new(0, 0)..Point::new(4, 2), &snapshot),
&[
- (0, "bbbb\nccccc".to_string(), true),
- (2, "ddd\neeee".to_string(), false),
- (4, "jj".to_string(), true),
+ (MultiBufferRow(0), "bbbb\nccccc".to_string(), true),
+ (MultiBufferRow(2), "ddd\neeee".to_string(), false),
+ (MultiBufferRow(4), "jj".to_string(), true),
]
);
assert_eq!(
boundaries_in_range(Point::new(0, 0)..Point::new(2, 0), &snapshot),
- &[(0, "bbbb\nccccc".to_string(), true)]
+ &[(MultiBufferRow(0), "bbbb\nccccc".to_string(), true)]
);
assert_eq!(
boundaries_in_range(Point::new(1, 0)..Point::new(1, 5), &snapshot),
@@ -4717,19 +4738,19 @@ mod tests {
);
assert_eq!(
boundaries_in_range(Point::new(1, 0)..Point::new(4, 0), &snapshot),
- &[(2, "ddd\neeee".to_string(), false)]
+ &[(MultiBufferRow(2), "ddd\neeee".to_string(), false)]
);
assert_eq!(
boundaries_in_range(Point::new(1, 0)..Point::new(4, 0), &snapshot),
- &[(2, "ddd\neeee".to_string(), false)]
+ &[(MultiBufferRow(2), "ddd\neeee".to_string(), false)]
);
assert_eq!(
boundaries_in_range(Point::new(2, 0)..Point::new(3, 0), &snapshot),
- &[(2, "ddd\neeee".to_string(), false)]
+ &[(MultiBufferRow(2), "ddd\neeee".to_string(), false)]
);
assert_eq!(
boundaries_in_range(Point::new(4, 0)..Point::new(4, 2), &snapshot),
- &[(4, "jj".to_string(), true)]
+ &[(MultiBufferRow(4), "jj".to_string(), true)]
);
assert_eq!(
boundaries_in_range(Point::new(4, 2)..Point::new(4, 2), &snapshot),
@@ -4812,7 +4833,7 @@ mod tests {
fn boundaries_in_range(
range: Range<Point>,
snapshot: &MultiBufferSnapshot,
- ) -> Vec<(u32, String, bool)> {
+ ) -> Vec<(MultiBufferRow, String, bool)> {
snapshot
.excerpt_boundaries_in_range(range)
.map(|boundary| {
@@ -5100,8 +5121,14 @@ mod tests {
let snapshot = multibuffer.read(cx).snapshot(cx);
assert_eq!(snapshot.text(), "");
- assert_eq!(snapshot.buffer_rows(0).collect::<Vec<_>>(), &[Some(0)]);
- assert_eq!(snapshot.buffer_rows(1).collect::<Vec<_>>(), &[]);
+ assert_eq!(
+ snapshot.buffer_rows(MultiBufferRow(0)).collect::<Vec<_>>(),
+ &[Some(0)]
+ );
+ assert_eq!(
+ snapshot.buffer_rows(MultiBufferRow(1)).collect::<Vec<_>>(),
+ &[]
+ );
}
#[gpui::test]
@@ -5518,14 +5545,16 @@ mod tests {
log::info!("MultiBuffer text: {:?}", expected_text);
assert_eq!(
- snapshot.buffer_rows(0).collect::<Vec<_>>(),
+ snapshot.buffer_rows(MultiBufferRow(0)).collect::<Vec<_>>(),
expected_buffer_rows,
);
for _ in 0..5 {
let start_row = rng.gen_range(0..=expected_buffer_rows.len());
assert_eq!(
- snapshot.buffer_rows(start_row as u32).collect::<Vec<_>>(),
+ snapshot
+ .buffer_rows(MultiBufferRow(start_row as u32))
+ .collect::<Vec<_>>(),
&expected_buffer_rows[start_row..],
"buffer_rows({})",
start_row
@@ -5533,7 +5562,7 @@ mod tests {
}
assert_eq!(
- snapshot.max_buffer_row(),
+ snapshot.max_buffer_row().0,
expected_buffer_rows.into_iter().flatten().max().unwrap()
);
@@ -5666,7 +5695,7 @@ mod tests {
for (row, line) in expected_text.split('\n').enumerate() {
assert_eq!(
- snapshot.line_len(row as u32),
+ snapshot.line_len(MultiBufferRow(row as u32)),
line.len() as u32,
"line_len({}).",
row
@@ -486,6 +486,7 @@ mod tests {
editor
.highlighted_display_rows(HashSet::default(), cx)
.into_keys()
+ .map(|r| r.0)
.collect()
})
}
@@ -1090,7 +1090,7 @@ mod tests {
use std::ops::Range;
use super::*;
- use editor::{DisplayPoint, Editor};
+ use editor::{display_map::DisplayRow, DisplayPoint, Editor};
use gpui::{Context, Hsla, TestAppContext, VisualTestContext};
use language::Buffer;
use project::Project;
@@ -1157,8 +1157,8 @@ mod tests {
assert_eq!(
display_points_of(editor.all_text_background_highlights(cx)),
&[
- DisplayPoint::new(2, 17)..DisplayPoint::new(2, 19),
- DisplayPoint::new(2, 43)..DisplayPoint::new(2, 45),
+ DisplayPoint::new(DisplayRow(2), 17)..DisplayPoint::new(DisplayRow(2), 19),
+ DisplayPoint::new(DisplayRow(2), 43)..DisplayPoint::new(DisplayRow(2), 45),
]
);
});
@@ -1172,7 +1172,7 @@ mod tests {
editor.update(cx, |editor, cx| {
assert_eq!(
display_points_of(editor.all_text_background_highlights(cx)),
- &[DisplayPoint::new(2, 43)..DisplayPoint::new(2, 45),]
+ &[DisplayPoint::new(DisplayRow(2), 43)..DisplayPoint::new(DisplayRow(2), 45),]
);
});
@@ -1186,13 +1186,13 @@ mod tests {
assert_eq!(
display_points_of(editor.all_text_background_highlights(cx)),
&[
- DisplayPoint::new(0, 24)..DisplayPoint::new(0, 26),
- DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43),
- DisplayPoint::new(2, 71)..DisplayPoint::new(2, 73),
- DisplayPoint::new(3, 1)..DisplayPoint::new(3, 3),
- DisplayPoint::new(3, 11)..DisplayPoint::new(3, 13),
- DisplayPoint::new(3, 56)..DisplayPoint::new(3, 58),
- DisplayPoint::new(3, 60)..DisplayPoint::new(3, 62),
+ DisplayPoint::new(DisplayRow(0), 24)..DisplayPoint::new(DisplayRow(0), 26),
+ DisplayPoint::new(DisplayRow(0), 41)..DisplayPoint::new(DisplayRow(0), 43),
+ DisplayPoint::new(DisplayRow(2), 71)..DisplayPoint::new(DisplayRow(2), 73),
+ DisplayPoint::new(DisplayRow(3), 1)..DisplayPoint::new(DisplayRow(3), 3),
+ DisplayPoint::new(DisplayRow(3), 11)..DisplayPoint::new(DisplayRow(3), 13),
+ DisplayPoint::new(DisplayRow(3), 56)..DisplayPoint::new(DisplayRow(3), 58),
+ DisplayPoint::new(DisplayRow(3), 60)..DisplayPoint::new(DisplayRow(3), 62),
]
);
});
@@ -1207,16 +1207,18 @@ mod tests {
assert_eq!(
display_points_of(editor.all_text_background_highlights(cx)),
&[
- DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43),
- DisplayPoint::new(3, 11)..DisplayPoint::new(3, 13),
- DisplayPoint::new(3, 56)..DisplayPoint::new(3, 58),
+ DisplayPoint::new(DisplayRow(0), 41)..DisplayPoint::new(DisplayRow(0), 43),
+ DisplayPoint::new(DisplayRow(3), 11)..DisplayPoint::new(DisplayRow(3), 13),
+ DisplayPoint::new(DisplayRow(3), 56)..DisplayPoint::new(DisplayRow(3), 58),
]
);
});
editor.update(cx, |editor, cx| {
editor.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)])
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0)
+ ])
});
});
search_bar.update(cx, |search_bar, cx| {
@@ -1224,7 +1226,7 @@ mod tests {
search_bar.select_next_match(&SelectNextMatch, cx);
assert_eq!(
editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43)]
+ [DisplayPoint::new(DisplayRow(0), 41)..DisplayPoint::new(DisplayRow(0), 43)]
);
});
search_bar.update(cx, |search_bar, _| {
@@ -1235,7 +1237,7 @@ mod tests {
search_bar.select_next_match(&SelectNextMatch, cx);
assert_eq!(
editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(3, 11)..DisplayPoint::new(3, 13)]
+ [DisplayPoint::new(DisplayRow(3), 11)..DisplayPoint::new(DisplayRow(3), 13)]
);
});
search_bar.update(cx, |search_bar, _| {
@@ -1246,7 +1248,7 @@ mod tests {
search_bar.select_next_match(&SelectNextMatch, cx);
assert_eq!(
editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(3, 56)..DisplayPoint::new(3, 58)]
+ [DisplayPoint::new(DisplayRow(3), 56)..DisplayPoint::new(DisplayRow(3), 58)]
);
});
search_bar.update(cx, |search_bar, _| {
@@ -1257,7 +1259,7 @@ mod tests {
search_bar.select_next_match(&SelectNextMatch, cx);
assert_eq!(
editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43)]
+ [DisplayPoint::new(DisplayRow(0), 41)..DisplayPoint::new(DisplayRow(0), 43)]
);
});
search_bar.update(cx, |search_bar, _| {
@@ -1268,7 +1270,7 @@ mod tests {
search_bar.select_prev_match(&SelectPrevMatch, cx);
assert_eq!(
editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(3, 56)..DisplayPoint::new(3, 58)]
+ [DisplayPoint::new(DisplayRow(3), 56)..DisplayPoint::new(DisplayRow(3), 58)]
);
});
search_bar.update(cx, |search_bar, _| {
@@ -1279,7 +1281,7 @@ mod tests {
search_bar.select_prev_match(&SelectPrevMatch, cx);
assert_eq!(
editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(3, 11)..DisplayPoint::new(3, 13)]
+ [DisplayPoint::new(DisplayRow(3), 11)..DisplayPoint::new(DisplayRow(3), 13)]
);
});
search_bar.update(cx, |search_bar, _| {
@@ -1290,7 +1292,7 @@ mod tests {
search_bar.select_prev_match(&SelectPrevMatch, cx);
assert_eq!(
editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43)]
+ [DisplayPoint::new(DisplayRow(0), 41)..DisplayPoint::new(DisplayRow(0), 43)]
);
});
search_bar.update(cx, |search_bar, _| {
@@ -1301,7 +1303,9 @@ mod tests {
// the closest match to the left.
editor.update(cx, |editor, cx| {
editor.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)])
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0)
+ ])
});
});
search_bar.update(cx, |search_bar, cx| {
@@ -1309,7 +1313,7 @@ mod tests {
search_bar.select_prev_match(&SelectPrevMatch, cx);
assert_eq!(
editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43)]
+ [DisplayPoint::new(DisplayRow(0), 41)..DisplayPoint::new(DisplayRow(0), 43)]
);
});
search_bar.update(cx, |search_bar, _| {
@@ -1320,7 +1324,9 @@ mod tests {
// closest match to the right.
editor.update(cx, |editor, cx| {
editor.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)])
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(1), 0)..DisplayPoint::new(DisplayRow(1), 0)
+ ])
});
});
search_bar.update(cx, |search_bar, cx| {
@@ -1328,7 +1334,7 @@ mod tests {
search_bar.select_next_match(&SelectNextMatch, cx);
assert_eq!(
editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(3, 11)..DisplayPoint::new(3, 13)]
+ [DisplayPoint::new(DisplayRow(3), 11)..DisplayPoint::new(DisplayRow(3), 13)]
);
});
search_bar.update(cx, |search_bar, _| {
@@ -1339,7 +1345,9 @@ mod tests {
// the last match.
editor.update(cx, |editor, cx| {
editor.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(3, 60)..DisplayPoint::new(3, 60)])
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(3), 60)..DisplayPoint::new(DisplayRow(3), 60)
+ ])
});
});
search_bar.update(cx, |search_bar, cx| {
@@ -1347,7 +1355,7 @@ mod tests {
search_bar.select_prev_match(&SelectPrevMatch, cx);
assert_eq!(
editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(3, 56)..DisplayPoint::new(3, 58)]
+ [DisplayPoint::new(DisplayRow(3), 56)..DisplayPoint::new(DisplayRow(3), 58)]
);
});
search_bar.update(cx, |search_bar, _| {
@@ -1358,7 +1366,9 @@ mod tests {
// first match.
editor.update(cx, |editor, cx| {
editor.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(3, 60)..DisplayPoint::new(3, 60)])
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(3), 60)..DisplayPoint::new(DisplayRow(3), 60)
+ ])
});
});
search_bar.update(cx, |search_bar, cx| {
@@ -1366,7 +1376,7 @@ mod tests {
search_bar.select_next_match(&SelectNextMatch, cx);
assert_eq!(
editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(0, 41)..DisplayPoint::new(0, 43)]
+ [DisplayPoint::new(DisplayRow(0), 41)..DisplayPoint::new(DisplayRow(0), 43)]
);
});
search_bar.update(cx, |search_bar, _| {
@@ -1377,7 +1387,9 @@ mod tests {
// selects the last match.
editor.update(cx, |editor, cx| {
editor.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(0, 0)..DisplayPoint::new(0, 0)])
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 0)
+ ])
});
});
search_bar.update(cx, |search_bar, cx| {
@@ -1385,7 +1397,7 @@ mod tests {
search_bar.select_prev_match(&SelectPrevMatch, cx);
assert_eq!(
editor.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(3, 56)..DisplayPoint::new(3, 58)]
+ [DisplayPoint::new(DisplayRow(3), 56)..DisplayPoint::new(DisplayRow(3), 58)]
);
});
search_bar.update(cx, |search_bar, _| {
@@ -1414,7 +1426,7 @@ mod tests {
editor.update(cx, |editor, cx| {
assert_eq!(
display_points_of(editor.all_text_background_highlights(cx)),
- &[DisplayPoint::new(2, 43)..DisplayPoint::new(2, 45),]
+ &[DisplayPoint::new(DisplayRow(2), 43)..DisplayPoint::new(DisplayRow(2), 45),]
);
});
@@ -1439,7 +1451,7 @@ mod tests {
editor.update(cx, |editor, cx| {
assert_eq!(
display_points_of(editor.all_text_background_highlights(cx)),
- &[DisplayPoint::new(0, 35)..DisplayPoint::new(0, 40),]
+ &[DisplayPoint::new(DisplayRow(0), 35)..DisplayPoint::new(DisplayRow(0), 40),]
);
});
@@ -2041,8 +2053,8 @@ mod tests {
assert_eq!(
display_points_of(editor.all_text_background_highlights(cx)),
&[
- DisplayPoint::new(0, 10)..DisplayPoint::new(0, 20),
- DisplayPoint::new(1, 9)..DisplayPoint::new(1, 19),
+ DisplayPoint::new(DisplayRow(0), 10)..DisplayPoint::new(DisplayRow(0), 20),
+ DisplayPoint::new(DisplayRow(1), 9)..DisplayPoint::new(DisplayRow(1), 19),
],
);
});
@@ -1688,7 +1688,7 @@ fn register_workspace_action_for_present_search<A: Action>(
#[cfg(test)]
pub mod tests {
use super::*;
- use editor::DisplayPoint;
+ use editor::{display_map::DisplayRow, DisplayPoint};
use gpui::{Action, TestAppContext, WindowHandle};
use project::FakeFs;
use serde_json::json;
@@ -1730,15 +1730,15 @@ pub mod tests {
.update(cx, |editor, cx| editor.all_text_background_highlights(cx)),
&[
(
- DisplayPoint::new(2, 32)..DisplayPoint::new(2, 35),
+ DisplayPoint::new(DisplayRow(2), 32)..DisplayPoint::new(DisplayRow(2), 35),
match_background_color
),
(
- DisplayPoint::new(2, 37)..DisplayPoint::new(2, 40),
+ DisplayPoint::new(DisplayRow(2), 37)..DisplayPoint::new(DisplayRow(2), 40),
match_background_color
),
(
- DisplayPoint::new(5, 6)..DisplayPoint::new(5, 9),
+ DisplayPoint::new(DisplayRow(5), 6)..DisplayPoint::new(DisplayRow(5), 9),
match_background_color
)
]
@@ -1748,7 +1748,7 @@ pub mod tests {
search_view
.results_editor
.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(2, 32)..DisplayPoint::new(2, 35)]
+ [DisplayPoint::new(DisplayRow(2), 32)..DisplayPoint::new(DisplayRow(2), 35)]
);
search_view.select_match(Direction::Next, cx);
@@ -1761,7 +1761,7 @@ pub mod tests {
search_view
.results_editor
.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(2, 37)..DisplayPoint::new(2, 40)]
+ [DisplayPoint::new(DisplayRow(2), 37)..DisplayPoint::new(DisplayRow(2), 40)]
);
search_view.select_match(Direction::Next, cx);
})
@@ -1774,7 +1774,7 @@ pub mod tests {
search_view
.results_editor
.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(5, 6)..DisplayPoint::new(5, 9)]
+ [DisplayPoint::new(DisplayRow(5), 6)..DisplayPoint::new(DisplayRow(5), 9)]
);
search_view.select_match(Direction::Next, cx);
})
@@ -1787,7 +1787,7 @@ pub mod tests {
search_view
.results_editor
.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(2, 32)..DisplayPoint::new(2, 35)]
+ [DisplayPoint::new(DisplayRow(2), 32)..DisplayPoint::new(DisplayRow(2), 35)]
);
search_view.select_match(Direction::Prev, cx);
})
@@ -1800,7 +1800,7 @@ pub mod tests {
search_view
.results_editor
.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(5, 6)..DisplayPoint::new(5, 9)]
+ [DisplayPoint::new(DisplayRow(5), 6)..DisplayPoint::new(DisplayRow(5), 9)]
);
search_view.select_match(Direction::Prev, cx);
})
@@ -1813,7 +1813,7 @@ pub mod tests {
search_view
.results_editor
.update(cx, |editor, cx| editor.selections.display_ranges(cx)),
- [DisplayPoint::new(2, 37)..DisplayPoint::new(2, 40)]
+ [DisplayPoint::new(DisplayRow(2), 37)..DisplayPoint::new(DisplayRow(2), 40)]
);
})
.unwrap();
@@ -26,6 +26,7 @@ gpui.workspace = true
itertools.workspace = true
language.workspace = true
log.workspace = true
+multi_buffer.workspace = true
nvim-rs = { git = "https://github.com/KillTheMule/nvim-rs", branch = "master", features = [
"use_tokio",
], optional = true }
@@ -1,13 +1,14 @@
use editor::{
- display_map::{DisplaySnapshot, FoldPoint, ToDisplayPoint},
+ display_map::{DisplayRow, DisplaySnapshot, FoldPoint, ToDisplayPoint},
movement::{
self, find_boundary, find_preceding_boundary_display_point, FindRange, TextLayoutDetails,
},
scroll::Autoscroll,
- Anchor, Bias, DisplayPoint, ToOffset,
+ Anchor, Bias, DisplayPoint, RowExt, ToOffset,
};
use gpui::{actions, impl_actions, px, ViewContext, WindowContext};
use language::{char_kind, CharKind, Point, Selection, SelectionGoal};
+use multi_buffer::MultiBufferRow;
use serde::Deserialize;
use std::ops::Range;
use workspace::Workspace;
@@ -843,7 +844,7 @@ impl Motion {
selection.end = map.clip_point(selection.end, Bias::Right);
// Don't reset the end here
return Some(selection.start..selection.end);
- } else if selection.start.row() > 0 {
+ } else if selection.start.row().0 > 0 {
*selection.start.row_mut() -= 1;
*selection.start.column_mut() = map.line_len(selection.start.row());
selection.start = map.clip_point(selection.start, Bias::Left);
@@ -860,10 +861,10 @@ impl Motion {
ignore_punctuation: _,
} = self
{
- let start_row = selection.start.to_point(&map).row;
- if selection.end.to_point(&map).row > start_row {
+ let start_row = MultiBufferRow(selection.start.to_point(&map).row);
+ if selection.end.to_point(&map).row > start_row.0 {
selection.end =
- Point::new(start_row, map.buffer_snapshot.line_len(start_row))
+ Point::new(start_row.0, map.buffer_snapshot.line_len(start_row))
.to_display_point(&map)
}
}
@@ -997,7 +998,7 @@ fn up_down_buffer_rows(
map.fold_snapshot
.clip_point(FoldPoint::new(start.row(), 0), Bias::Left),
);
- let select_nth_wrapped_row = point.row() - begin_folded_line.row();
+ let select_nth_wrapped_row = point.row().0 - begin_folded_line.row().0;
let (goal_wrap, goal_x) = match goal {
SelectionGoal::WrappedHorizontalPosition((row, x)) => (row, x),
@@ -1020,7 +1021,7 @@ fn up_down_buffer_rows(
let mut i = 0;
while i < goal_wrap && begin_folded_line.row() < map.max_point().row() {
- let next_folded_line = DisplayPoint::new(begin_folded_line.row() + 1, 0);
+ let next_folded_line = DisplayPoint::new(begin_folded_line.row().next_row(), 0);
if map
.display_point_to_fold_point(next_folded_line, Bias::Right)
.row()
@@ -1215,7 +1216,7 @@ fn previous_word_end(
let scope = map.buffer_snapshot.language_scope_at(point.to_point(map));
let mut point = point.to_point(map);
- if point.column < map.buffer_snapshot.line_len(point.row) {
+ if point.column < map.buffer_snapshot.line_len(MultiBufferRow(point.row)) {
point.column += 1;
}
for _ in 0..times {
@@ -1375,7 +1376,7 @@ fn previous_subword_end(
let scope = map.buffer_snapshot.language_scope_at(point.to_point(map));
let mut point = point.to_point(map);
- if point.column < map.buffer_snapshot.line_len(point.row) {
+ if point.column < map.buffer_snapshot.line_len(MultiBufferRow(point.row)) {
point.column += 1;
}
for _ in 0..times {
@@ -1497,7 +1498,7 @@ fn end_of_document(
let new_row = if let Some(line) = line {
(line - 1) as u32
} else {
- map.max_buffer_row()
+ map.max_buffer_row().0
};
let new_point = Point::new(new_row, point.column());
@@ -1672,22 +1673,24 @@ fn window_top(
.anchor
.to_display_point(map);
- if first_visible_line.row() != 0 && text_layout_details.vertical_scroll_margin as usize > times
+ if first_visible_line.row() != DisplayRow(0)
+ && text_layout_details.vertical_scroll_margin as usize > times
{
times = text_layout_details.vertical_scroll_margin.ceil() as usize;
}
if let Some(visible_rows) = text_layout_details.visible_rows {
- let bottom_row = first_visible_line.row() + visible_rows as u32;
- let new_row = (first_visible_line.row() + (times as u32))
+ let bottom_row = first_visible_line.row().0 + visible_rows as u32;
+ let new_row = (first_visible_line.row().0 + (times as u32))
.min(bottom_row)
- .min(map.max_point().row());
+ .min(map.max_point().row().0);
let new_col = point.column().min(map.line_len(first_visible_line.row()));
- let new_point = DisplayPoint::new(new_row, new_col);
+ let new_point = DisplayPoint::new(DisplayRow(new_row), new_col);
(map.clip_point(new_point, Bias::Left), SelectionGoal::None)
} else {
- let new_row = (first_visible_line.row() + (times as u32)).min(map.max_point().row());
+ let new_row =
+ DisplayRow((first_visible_line.row().0 + (times as u32)).min(map.max_point().row().0));
let new_col = point.column().min(map.line_len(first_visible_line.row()));
let new_point = DisplayPoint::new(new_row, new_col);
@@ -1707,10 +1710,11 @@ fn window_middle(
.to_display_point(map);
let max_visible_rows =
- (visible_rows as u32).min(map.max_point().row() - first_visible_line.row());
+ (visible_rows as u32).min(map.max_point().row().0 - first_visible_line.row().0);
let new_row =
- (first_visible_line.row() + (max_visible_rows / 2)).min(map.max_point().row());
+ (first_visible_line.row().0 + (max_visible_rows / 2)).min(map.max_point().row().0);
+ let new_row = DisplayRow(new_row);
let new_col = point.column().min(map.line_len(new_row));
let new_point = DisplayPoint::new(new_row, new_col);
(map.clip_point(new_point, Bias::Left), SelectionGoal::None)
@@ -1730,18 +1734,19 @@ fn window_bottom(
.scroll_anchor
.anchor
.to_display_point(map);
- let bottom_row = first_visible_line.row()
+ let bottom_row = first_visible_line.row().0
+ (visible_rows + text_layout_details.scroll_anchor.offset.y - 1.).floor() as u32;
- if bottom_row < map.max_point().row()
+ if bottom_row < map.max_point().row().0
&& text_layout_details.vertical_scroll_margin as usize > times
{
times = text_layout_details.vertical_scroll_margin.ceil() as usize;
}
- let bottom_row_capped = bottom_row.min(map.max_point().row());
- let new_row = if bottom_row_capped.saturating_sub(times as u32) < first_visible_line.row() {
+ let bottom_row_capped = bottom_row.min(map.max_point().row().0);
+ let new_row = if bottom_row_capped.saturating_sub(times as u32) < first_visible_line.row().0
+ {
first_visible_line.row()
} else {
- bottom_row_capped.saturating_sub(times as u32)
+ DisplayRow(bottom_row_capped.saturating_sub(times as u32))
};
let new_col = point.column().min(map.line_len(new_row));
let new_point = DisplayPoint::new(new_row, new_col);
@@ -25,6 +25,7 @@ use editor::Bias;
use gpui::{actions, ViewContext, WindowContext};
use language::{Point, SelectionGoal};
use log::error;
+use multi_buffer::MultiBufferRow;
use workspace::Workspace;
use self::{
@@ -314,7 +315,7 @@ fn insert_line_above(_: &mut Workspace, _: &InsertLineAbove, cx: &mut ViewContex
.collect();
let edits = selection_start_rows.into_iter().map(|row| {
let indent = snapshot
- .indent_size_for_line(row)
+ .indent_size_for_line(MultiBufferRow(row))
.chars()
.collect::<String>();
let start_of_line = Point::new(row, 0);
@@ -349,10 +350,10 @@ fn insert_line_below(_: &mut Workspace, _: &InsertLineBelow, cx: &mut ViewContex
.collect();
let edits = selection_end_rows.into_iter().map(|row| {
let indent = snapshot
- .indent_size_for_line(row)
+ .indent_size_for_line(MultiBufferRow(row))
.chars()
.collect::<String>();
- let end_of_line = Point::new(row, snapshot.line_len(row));
+ let end_of_line = Point::new(row, snapshot.line_len(MultiBufferRow(row)));
(end_of_line..end_of_line, "\n".to_string() + &indent)
});
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
@@ -1,6 +1,7 @@
use editor::scroll::Autoscroll;
use gpui::ViewContext;
use language::{Bias, Point};
+use multi_buffer::MultiBufferRow;
use workspace::Workspace;
use crate::{
@@ -48,8 +49,10 @@ where
match vim.state().mode {
Mode::VisualLine => {
let start = Point::new(selection.start.row, 0);
- let end =
- Point::new(selection.end.row, snapshot.line_len(selection.end.row));
+ let end = Point::new(
+ selection.end.row,
+ snapshot.line_len(MultiBufferRow(selection.end.row)),
+ );
ranges.push(start..end);
cursor_positions.push(start..start);
}
@@ -71,7 +74,7 @@ where
}
ranges.push(start..end);
- if end.column == snapshot.line_len(end.row) {
+ if end.column == snapshot.line_len(MultiBufferRow(end.row)) {
end = snapshot.clip_point(end - Point::new(0, 1), Bias::Left);
}
cursor_positions.push(end..end)
@@ -7,6 +7,7 @@ use editor::{
};
use gpui::WindowContext;
use language::{Point, Selection};
+use multi_buffer::MultiBufferRow;
pub fn delete_motion(vim: &mut Vim, motion: Motion, times: Option<usize>, cx: &mut WindowContext) {
vim.stop_recording();
@@ -29,7 +30,7 @@ pub fn delete_motion(vim: &mut Vim, motion: Motion, times: Option<usize>, cx: &m
if selection.is_empty()
&& map
.buffer_snapshot
- .line_len(selection.start.to_point(&map).row)
+ .line_len(MultiBufferRow(selection.start.to_point(&map).row))
== 0
{
selection.end = map
@@ -79,7 +80,7 @@ pub fn delete_object(vim: &mut Vim, object: Object, around: bool, cx: &mut Windo
let mut move_selection_start_to_previous_line =
|map: &DisplaySnapshot, selection: &mut Selection<DisplayPoint>| {
let start = selection.start.to_offset(map, Bias::Left);
- if selection.start.row() > 0 {
+ if selection.start.row().0 > 0 {
should_move_to_start.insert(selection.id);
selection.start = (start - '\n'.len_utf8()).to_display_point(map);
}
@@ -2,6 +2,7 @@ use std::cmp;
use editor::{
display_map::ToDisplayPoint, movement, scroll::Autoscroll, ClipboardSelection, DisplayPoint,
+ RowExt,
};
use gpui::{impl_actions, AppContext, ViewContext};
use language::{Bias, SelectionGoal};
@@ -99,13 +100,13 @@ fn paste(_: &mut Workspace, action: &Paste, cx: &mut ViewContext<Workspace>) {
.map(|selection| cmp::min(selection.start.column(), selection.end.column()))
.min()
.unwrap();
- let mut row = current_selections.last().unwrap().end.row() + 1;
+ let mut row = current_selections.last().unwrap().end.row().next_row();
while i < clipboard_selections.len() {
let cursor =
display_map.clip_point(DisplayPoint::new(row, left), Bias::Left);
selections_to_process.push((cursor..cursor, false));
i += 1;
- row += 1;
+ row.0 += 1;
}
}
@@ -1,6 +1,8 @@
use crate::Vim;
use editor::{
- display_map::ToDisplayPoint, scroll::ScrollAmount, DisplayPoint, Editor, EditorSettings,
+ display_map::{DisplayRow, ToDisplayPoint},
+ scroll::ScrollAmount,
+ DisplayPoint, Editor, EditorSettings,
};
use gpui::{actions, ViewContext};
use language::Bias;
@@ -85,11 +87,13 @@ fn scroll_editor(
if preserve_cursor_position {
let old_top = old_top_anchor.to_display_point(map);
- let new_row = top.row() + selection.head().row() - old_top.row();
+ let new_row =
+ DisplayRow(top.row().0 + selection.head().row().0 - old_top.row().0);
head = map.clip_point(DisplayPoint::new(new_row, head.column()), Bias::Left)
}
- let min_row = top.row() + vertical_scroll_margin as u32;
- let max_row = top.row() + visible_rows - vertical_scroll_margin as u32 - 1;
+ let min_row = DisplayRow(top.row().0 + vertical_scroll_margin as u32);
+ let max_row =
+ DisplayRow(top.row().0 + visible_rows - vertical_scroll_margin as u32 - 1);
let new_head = if head.row() < min_row {
map.clip_point(DisplayPoint::new(min_row, head.column()), Bias::Left)
@@ -509,7 +509,7 @@ fn parse_replace_all(query: &str) -> Replacement {
#[cfg(test)]
mod test {
- use editor::DisplayPoint;
+ use editor::{display_map::DisplayRow, DisplayPoint};
use indoc::indoc;
use search::BufferSearchBar;
@@ -582,7 +582,7 @@ mod test {
let highlights = editor.all_text_background_highlights(cx);
assert_eq!(3, highlights.len());
assert_eq!(
- DisplayPoint::new(2, 0)..DisplayPoint::new(2, 2),
+ DisplayPoint::new(DisplayRow(2), 0)..DisplayPoint::new(DisplayRow(2), 2),
highlights[0].0
)
});
@@ -14,6 +14,7 @@ use itertools::Itertools;
use gpui::{actions, impl_actions, ViewContext, WindowContext};
use language::{char_kind, BufferSnapshot, CharKind, Point, Selection};
+use multi_buffer::MultiBufferRow;
use serde::Deserialize;
use workspace::Workspace;
@@ -724,7 +725,7 @@ fn paragraph(
let paragraph_end_row = paragraph_end.row();
let paragraph_ends_with_eof = paragraph_end_row == map.max_point().row();
let point = relative_to.to_point(map);
- let current_line_is_empty = map.buffer_snapshot.is_line_blank(point.row);
+ let current_line_is_empty = map.buffer_snapshot.is_line_blank(MultiBufferRow(point.row));
if around {
if paragraph_ends_with_eof {
@@ -733,13 +734,13 @@ fn paragraph(
}
let paragraph_start_row = paragraph_start.row();
- if paragraph_start_row != 0 {
+ if paragraph_start_row.0 != 0 {
let previous_paragraph_last_line_start =
- Point::new(paragraph_start_row - 1, 0).to_display_point(map);
+ Point::new(paragraph_start_row.0 - 1, 0).to_display_point(map);
paragraph_start = start_of_paragraph(map, previous_paragraph_last_line_start);
}
} else {
- let next_paragraph_start = Point::new(paragraph_end_row + 1, 0).to_display_point(map);
+ let next_paragraph_start = Point::new(paragraph_end_row.0 + 1, 0).to_display_point(map);
paragraph_end = end_of_paragraph(map, next_paragraph_start);
}
}
@@ -756,10 +757,10 @@ pub fn start_of_paragraph(map: &DisplaySnapshot, display_point: DisplayPoint) ->
return DisplayPoint::zero();
}
- let is_current_line_blank = map.buffer_snapshot.is_line_blank(point.row);
+ let is_current_line_blank = map.buffer_snapshot.is_line_blank(MultiBufferRow(point.row));
for row in (0..point.row).rev() {
- let blank = map.buffer_snapshot.is_line_blank(row);
+ let blank = map.buffer_snapshot.is_line_blank(MultiBufferRow(row));
if blank != is_current_line_blank {
return Point::new(row + 1, 0).to_display_point(map);
}
@@ -773,18 +774,21 @@ pub fn start_of_paragraph(map: &DisplaySnapshot, display_point: DisplayPoint) ->
/// The trailing newline is excluded from the paragraph.
pub fn end_of_paragraph(map: &DisplaySnapshot, display_point: DisplayPoint) -> DisplayPoint {
let point = display_point.to_point(map);
- if point.row == map.max_buffer_row() {
+ if point.row == map.max_buffer_row().0 {
return map.max_point();
}
- let is_current_line_blank = map.buffer_snapshot.is_line_blank(point.row);
+ let is_current_line_blank = map.buffer_snapshot.is_line_blank(MultiBufferRow(point.row));
- for row in point.row + 1..map.max_buffer_row() + 1 {
- let blank = map.buffer_snapshot.is_line_blank(row);
+ for row in point.row + 1..map.max_buffer_row().0 + 1 {
+ let blank = map.buffer_snapshot.is_line_blank(MultiBufferRow(row));
if blank != is_current_line_blank {
let previous_row = row - 1;
- return Point::new(previous_row, map.buffer_snapshot.line_len(previous_row))
- .to_display_point(map);
+ return Point::new(
+ previous_row,
+ map.buffer_snapshot.line_len(MultiBufferRow(previous_row)),
+ )
+ .to_display_point(map);
}
}
@@ -6,7 +6,7 @@ mod vim_test_context;
use std::time::Duration;
use command_palette::CommandPalette;
-use editor::DisplayPoint;
+use editor::{display_map::DisplayRow, DisplayPoint};
use futures::StreamExt;
use gpui::{KeyBinding, Modifiers, MouseButton, TestAppContext};
pub use neovim_backed_binding_test_context::*;
@@ -235,7 +235,7 @@ async fn test_selection_on_search(cx: &mut gpui::TestAppContext) {
let highlights = editor.all_text_background_highlights(cx);
assert_eq!(3, highlights.len());
assert_eq!(
- DisplayPoint::new(2, 0)..DisplayPoint::new(2, 2),
+ DisplayPoint::new(DisplayRow(2), 0)..DisplayPoint::new(DisplayRow(2), 2),
highlights[0].0
)
});
@@ -3,6 +3,7 @@ use std::time::Duration;
use editor::{ClipboardSelection, Editor};
use gpui::{ClipboardItem, ViewContext};
use language::{CharKind, Point};
+use multi_buffer::MultiBufferRow;
use settings::Settings;
use crate::{state::Mode, UseSystemClipboard, Vim, VimSettings};
@@ -74,10 +75,10 @@ fn copy_selections_content_internal(
// contains a newline (so that delete works as expected). We undo that change
// here.
let is_last_line = linewise
- && end.row == buffer.max_buffer_row()
+ && end.row == buffer.max_buffer_row().0
&& buffer.max_point().column > 0
- && start.row < buffer.max_buffer_row()
- && start == Point::new(start.row, buffer.line_len(start.row));
+ && start.row < buffer.max_buffer_row().0
+ && start == Point::new(start.row, buffer.line_len(MultiBufferRow(start.row)));
if is_last_line {
start = Point::new(start.row + 1, 0);
@@ -96,7 +97,7 @@ fn copy_selections_content_internal(
clipboard_selections.push(ClipboardSelection {
len: text.len() - initial_len,
is_entire_line: linewise,
- first_line_indent: buffer.indent_size_for_line(start.row).len,
+ first_line_indent: buffer.indent_size_for_line(MultiBufferRow(start.row)).len,
});
}
}
@@ -9,6 +9,7 @@ use editor::{
};
use gpui::{actions, ViewContext, WindowContext};
use language::{Point, Selection, SelectionGoal};
+use multi_buffer::MultiBufferRow;
use search::BufferSearchBar;
use util::ResultExt;
use workspace::{searchable::Direction, Workspace};
@@ -251,9 +252,9 @@ pub fn visual_block_motion(
break;
}
if tail.row() > head.row() {
- row -= 1
+ row.0 -= 1
} else {
- row += 1
+ row.0 += 1
}
}
@@ -313,13 +314,15 @@ pub fn visual_object(object: Object, cx: &mut WindowContext) {
// trailing newline is included in its selection from the beginning.
if object == Object::Paragraph && range.start != range.end {
let row_of_selection_end_line = selection.end.to_point(map).row;
- let new_selection_end =
- if map.buffer_snapshot.line_len(row_of_selection_end_line) == 0
- {
- Point::new(row_of_selection_end_line + 1, 0)
- } else {
- Point::new(row_of_selection_end_line, 1)
- };
+ let new_selection_end = if map
+ .buffer_snapshot
+ .line_len(MultiBufferRow(row_of_selection_end_line))
+ == 0
+ {
+ Point::new(row_of_selection_end_line + 1, 0)
+ } else {
+ Point::new(row_of_selection_end_line, 1)
+ };
selection.end = new_selection_end.to_display_point(map);
}
}
@@ -910,7 +910,7 @@ mod tests {
use super::*;
use assets::Assets;
use collections::HashSet;
- use editor::{scroll::Autoscroll, DisplayPoint, Editor};
+ use editor::{display_map::DisplayRow, scroll::Autoscroll, DisplayPoint, Editor};
use gpui::{
actions, Action, AnyWindowHandle, AppContext, AssetSource, BorrowAppContext, Entity,
TestAppContext, VisualTestContext, WindowHandle,
@@ -2229,9 +2229,8 @@ mod tests {
.update(cx, |_, cx| {
editor1.update(cx, |editor, cx| {
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
- s.select_display_ranges(
- [DisplayPoint::new(10, 0)..DisplayPoint::new(10, 0)],
- )
+ s.select_display_ranges([DisplayPoint::new(DisplayRow(10), 0)
+ ..DisplayPoint::new(DisplayRow(10), 0)])
});
});
})
@@ -2256,9 +2255,8 @@ mod tests {
.update(cx, |_, cx| {
editor3.update(cx, |editor, cx| {
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
- s.select_display_ranges(
- [DisplayPoint::new(12, 0)..DisplayPoint::new(12, 0)],
- )
+ s.select_display_ranges([DisplayPoint::new(DisplayRow(12), 0)
+ ..DisplayPoint::new(DisplayRow(12), 0)])
});
editor.newline(&Default::default(), cx);
editor.newline(&Default::default(), cx);
@@ -2279,7 +2277,7 @@ mod tests {
.unwrap();
assert_eq!(
active_location(&workspace, cx),
- (file3.clone(), DisplayPoint::new(16, 0), 12.5)
+ (file3.clone(), DisplayPoint::new(DisplayRow(16), 0), 12.5)
);
workspace
@@ -2289,7 +2287,7 @@ mod tests {
.unwrap();
assert_eq!(
active_location(&workspace, cx),
- (file3.clone(), DisplayPoint::new(0, 0), 0.)
+ (file3.clone(), DisplayPoint::new(DisplayRow(0), 0), 0.)
);
workspace
@@ -2299,7 +2297,7 @@ mod tests {
.unwrap();
assert_eq!(
active_location(&workspace, cx),
- (file2.clone(), DisplayPoint::new(0, 0), 0.)
+ (file2.clone(), DisplayPoint::new(DisplayRow(0), 0), 0.)
);
workspace
@@ -2309,7 +2307,7 @@ mod tests {
.unwrap();
assert_eq!(
active_location(&workspace, cx),
- (file1.clone(), DisplayPoint::new(10, 0), 0.)
+ (file1.clone(), DisplayPoint::new(DisplayRow(10), 0), 0.)
);
workspace
@@ -2319,7 +2317,7 @@ mod tests {
.unwrap();
assert_eq!(
active_location(&workspace, cx),
- (file1.clone(), DisplayPoint::new(0, 0), 0.)
+ (file1.clone(), DisplayPoint::new(DisplayRow(0), 0), 0.)
);
// Go back one more time and ensure we don't navigate past the first item in the history.
@@ -2330,7 +2328,7 @@ mod tests {
.unwrap();
assert_eq!(
active_location(&workspace, cx),
- (file1.clone(), DisplayPoint::new(0, 0), 0.)
+ (file1.clone(), DisplayPoint::new(DisplayRow(0), 0), 0.)
);
workspace
@@ -2340,7 +2338,7 @@ mod tests {
.unwrap();
assert_eq!(
active_location(&workspace, cx),
- (file1.clone(), DisplayPoint::new(10, 0), 0.)
+ (file1.clone(), DisplayPoint::new(DisplayRow(10), 0), 0.)
);
workspace
@@ -2350,7 +2348,7 @@ mod tests {
.unwrap();
assert_eq!(
active_location(&workspace, cx),
- (file2.clone(), DisplayPoint::new(0, 0), 0.)
+ (file2.clone(), DisplayPoint::new(DisplayRow(0), 0), 0.)
);
// Go forward to an item that has been closed, ensuring it gets re-opened at the same
@@ -2373,7 +2371,7 @@ mod tests {
.unwrap();
assert_eq!(
active_location(&workspace, cx),
- (file3.clone(), DisplayPoint::new(0, 0), 0.)
+ (file3.clone(), DisplayPoint::new(DisplayRow(0), 0), 0.)
);
workspace
@@ -2383,7 +2381,7 @@ mod tests {
.unwrap();
assert_eq!(
active_location(&workspace, cx),
- (file3.clone(), DisplayPoint::new(16, 0), 12.5)
+ (file3.clone(), DisplayPoint::new(DisplayRow(16), 0), 12.5)
);
workspace
@@ -2393,7 +2391,7 @@ mod tests {
.unwrap();
assert_eq!(
active_location(&workspace, cx),
- (file3.clone(), DisplayPoint::new(0, 0), 0.)
+ (file3.clone(), DisplayPoint::new(DisplayRow(0), 0), 0.)
);
// Go back to an item that has been closed and removed from disk
@@ -2422,7 +2420,7 @@ mod tests {
.unwrap();
assert_eq!(
active_location(&workspace, cx),
- (file2.clone(), DisplayPoint::new(0, 0), 0.)
+ (file2.clone(), DisplayPoint::new(DisplayRow(0), 0), 0.)
);
workspace
.update(cx, |w, cx| w.go_forward(w.active_pane().downgrade(), cx))
@@ -2431,7 +2429,7 @@ mod tests {
.unwrap();
assert_eq!(
active_location(&workspace, cx),
- (file3.clone(), DisplayPoint::new(0, 0), 0.)
+ (file3.clone(), DisplayPoint::new(DisplayRow(0), 0), 0.)
);
// Modify file to collapse multiple nav history entries into the same location.
@@ -2440,9 +2438,8 @@ mod tests {
.update(cx, |_, cx| {
editor1.update(cx, |editor, cx| {
editor.change_selections(None, cx, |s| {
- s.select_display_ranges(
- [DisplayPoint::new(15, 0)..DisplayPoint::new(15, 0)],
- )
+ s.select_display_ranges([DisplayPoint::new(DisplayRow(15), 0)
+ ..DisplayPoint::new(DisplayRow(15), 0)])
})
});
})
@@ -2452,9 +2449,8 @@ mod tests {
.update(cx, |_, cx| {
editor1.update(cx, |editor, cx| {
editor.change_selections(None, cx, |s| {
- s.select_display_ranges([
- DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0)
- ])
+ s.select_display_ranges([DisplayPoint::new(DisplayRow(3), 0)
+ ..DisplayPoint::new(DisplayRow(3), 0)])
});
});
})
@@ -2464,9 +2460,8 @@ mod tests {
.update(cx, |_, cx| {
editor1.update(cx, |editor, cx| {
editor.change_selections(None, cx, |s| {
- s.select_display_ranges([
- DisplayPoint::new(13, 0)..DisplayPoint::new(13, 0)
- ])
+ s.select_display_ranges([DisplayPoint::new(DisplayRow(13), 0)
+ ..DisplayPoint::new(DisplayRow(13), 0)])
})
});
})
@@ -2477,9 +2472,8 @@ mod tests {
editor1.update(cx, |editor, cx| {
editor.transact(cx, |editor, cx| {
editor.change_selections(None, cx, |s| {
- s.select_display_ranges([
- DisplayPoint::new(2, 0)..DisplayPoint::new(14, 0)
- ])
+ s.select_display_ranges([DisplayPoint::new(DisplayRow(2), 0)
+ ..DisplayPoint::new(DisplayRow(14), 0)])
});
editor.insert("", cx);
})
@@ -2491,7 +2485,8 @@ mod tests {
.update(cx, |_, cx| {
editor1.update(cx, |editor, cx| {
editor.change_selections(None, cx, |s| {
- s.select_display_ranges([DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)])
+ s.select_display_ranges([DisplayPoint::new(DisplayRow(1), 0)
+ ..DisplayPoint::new(DisplayRow(1), 0)])
})
});
})
@@ -2503,7 +2498,7 @@ mod tests {
.unwrap();
assert_eq!(
active_location(&workspace, cx),
- (file1.clone(), DisplayPoint::new(2, 0), 0.)
+ (file1.clone(), DisplayPoint::new(DisplayRow(2), 0), 0.)
);
workspace
.update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
@@ -2512,7 +2507,7 @@ mod tests {
.unwrap();
assert_eq!(
active_location(&workspace, cx),
- (file1.clone(), DisplayPoint::new(3, 0), 0.)
+ (file1.clone(), DisplayPoint::new(DisplayRow(3), 0), 0.)
);
fn active_location(