Move DisplayMap's reading methods to DisplayMapSnapshot
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
use crate::{
|
||||
editor::{
|
||||
buffer::{Anchor, Buffer, Point, ToOffset as _, ToPoint as _},
|
||||
display_map::DisplayMap,
|
||||
Bias, DisplayPoint,
|
||||
Bias, DisplayMapSnapshot, DisplayPoint,
|
||||
},
|
||||
time,
|
||||
};
|
||||
use gpui::AppContext;
|
||||
use std::{cmp::Ordering, mem, ops::Range};
|
||||
|
||||
pub type SelectionSetId = time::Lamport;
|
||||
@@ -81,9 +79,9 @@ impl Selection {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display_range(&self, map: &DisplayMap, cx: &AppContext) -> Range<DisplayPoint> {
|
||||
let start = self.start.to_display_point(map, cx);
|
||||
let end = self.end.to_display_point(map, cx);
|
||||
pub fn display_range(&self, map: &DisplayMapSnapshot) -> Range<DisplayPoint> {
|
||||
let start = self.start.to_display_point(map);
|
||||
let end = self.end.to_display_point(map);
|
||||
if self.reversed {
|
||||
end..start
|
||||
} else {
|
||||
@@ -94,23 +92,22 @@ impl Selection {
|
||||
pub fn buffer_rows_for_display_rows(
|
||||
&self,
|
||||
include_end_if_at_line_start: bool,
|
||||
map: &DisplayMap,
|
||||
cx: &AppContext,
|
||||
map: &DisplayMapSnapshot,
|
||||
) -> (Range<u32>, Range<u32>) {
|
||||
let display_start = self.start.to_display_point(map, cx);
|
||||
let display_start = self.start.to_display_point(map);
|
||||
let buffer_start =
|
||||
DisplayPoint::new(display_start.row(), 0).to_buffer_point(map, Bias::Left, cx);
|
||||
DisplayPoint::new(display_start.row(), 0).to_buffer_point(map, Bias::Left);
|
||||
|
||||
let mut display_end = self.end.to_display_point(map, cx);
|
||||
let mut display_end = self.end.to_display_point(map);
|
||||
if !include_end_if_at_line_start
|
||||
&& display_end.row() != map.max_point(cx).row()
|
||||
&& display_end.row() != map.max_point().row()
|
||||
&& display_start.row() != display_end.row()
|
||||
&& display_end.column() == 0
|
||||
{
|
||||
*display_end.row_mut() -= 1;
|
||||
}
|
||||
let buffer_end = DisplayPoint::new(display_end.row(), map.line_len(display_end.row(), cx))
|
||||
.to_buffer_point(map, Bias::Left, cx);
|
||||
let buffer_end = DisplayPoint::new(display_end.row(), map.line_len(display_end.row()))
|
||||
.to_buffer_point(map, Bias::Left);
|
||||
|
||||
(
|
||||
buffer_start.row..buffer_end.row + 1,
|
||||
|
||||
+95
-115
@@ -26,6 +26,7 @@ impl DisplayMap {
|
||||
|
||||
pub fn snapshot(&self, cx: &AppContext) -> DisplayMapSnapshot {
|
||||
DisplayMapSnapshot {
|
||||
buffer_snapshot: self.buffer.read(cx).snapshot(),
|
||||
folds_snapshot: self.fold_map.snapshot(cx),
|
||||
tab_size: self.tab_size,
|
||||
}
|
||||
@@ -46,80 +47,10 @@ impl DisplayMap {
|
||||
) {
|
||||
self.fold_map.unfold(ranges, cx)
|
||||
}
|
||||
|
||||
pub fn intersects_fold<T: ToOffset>(&self, offset: T, cx: &AppContext) -> bool {
|
||||
self.fold_map.snapshot(cx).intersects_fold(offset)
|
||||
}
|
||||
|
||||
pub fn is_line_folded(&self, display_row: u32, cx: &AppContext) -> bool {
|
||||
self.fold_map.snapshot(cx).is_line_folded(display_row)
|
||||
}
|
||||
|
||||
pub fn text(&self, cx: &AppContext) -> String {
|
||||
self.snapshot(cx).chunks_at(DisplayPoint::zero()).collect()
|
||||
}
|
||||
|
||||
pub fn line(&self, display_row: u32, cx: &AppContext) -> String {
|
||||
let mut result = String::new();
|
||||
for chunk in self
|
||||
.snapshot(cx)
|
||||
.chunks_at(DisplayPoint::new(display_row, 0))
|
||||
{
|
||||
if let Some(ix) = chunk.find('\n') {
|
||||
result.push_str(&chunk[0..ix]);
|
||||
break;
|
||||
} else {
|
||||
result.push_str(chunk);
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub fn line_indent(&self, display_row: u32, cx: &AppContext) -> (u32, bool) {
|
||||
let mut indent = 0;
|
||||
let mut is_blank = true;
|
||||
for c in self
|
||||
.snapshot(cx)
|
||||
.chars_at(DisplayPoint::new(display_row, 0))
|
||||
{
|
||||
if c == ' ' {
|
||||
indent += 1;
|
||||
} else {
|
||||
is_blank = c == '\n';
|
||||
break;
|
||||
}
|
||||
}
|
||||
(indent, is_blank)
|
||||
}
|
||||
|
||||
pub fn line_len(&self, row: u32, cx: &AppContext) -> u32 {
|
||||
DisplayPoint::new(row, self.fold_map.snapshot(cx).line_len(row))
|
||||
.expand_tabs(self, cx)
|
||||
.column()
|
||||
}
|
||||
|
||||
pub fn max_point(&self, cx: &AppContext) -> DisplayPoint {
|
||||
self.snapshot(cx).max_point().expand_tabs(self, cx)
|
||||
}
|
||||
|
||||
pub fn longest_row(&self, cx: &AppContext) -> u32 {
|
||||
self.fold_map.snapshot(cx).longest_row()
|
||||
}
|
||||
|
||||
pub fn anchor_before(&self, point: DisplayPoint, bias: Bias, cx: &AppContext) -> Anchor {
|
||||
self.buffer
|
||||
.read(cx)
|
||||
.anchor_before(point.to_buffer_point(self, bias, cx))
|
||||
}
|
||||
|
||||
pub fn anchor_after(&self, point: DisplayPoint, bias: Bias, cx: &AppContext) -> Anchor {
|
||||
self.buffer
|
||||
.read(cx)
|
||||
.anchor_after(point.to_buffer_point(self, bias, cx))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DisplayMapSnapshot {
|
||||
buffer_snapshot: buffer::Snapshot,
|
||||
folds_snapshot: FoldMapSnapshot,
|
||||
tab_size: usize,
|
||||
}
|
||||
@@ -208,6 +139,64 @@ impl DisplayMapSnapshot {
|
||||
self.folds_snapshot.folds_in_range(range)
|
||||
}
|
||||
|
||||
pub fn intersects_fold<T: ToOffset>(&self, offset: T) -> bool {
|
||||
self.folds_snapshot.intersects_fold(offset)
|
||||
}
|
||||
|
||||
pub fn is_line_folded(&self, display_row: u32) -> bool {
|
||||
self.folds_snapshot.is_line_folded(display_row)
|
||||
}
|
||||
|
||||
pub fn text(&self) -> String {
|
||||
self.chunks_at(DisplayPoint::zero()).collect()
|
||||
}
|
||||
|
||||
pub fn line(&self, display_row: u32) -> String {
|
||||
let mut result = String::new();
|
||||
for chunk in self.chunks_at(DisplayPoint::new(display_row, 0)) {
|
||||
if let Some(ix) = chunk.find('\n') {
|
||||
result.push_str(&chunk[0..ix]);
|
||||
break;
|
||||
} else {
|
||||
result.push_str(chunk);
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub fn line_indent(&self, display_row: u32) -> (u32, bool) {
|
||||
let mut indent = 0;
|
||||
let mut is_blank = true;
|
||||
for c in self.chars_at(DisplayPoint::new(display_row, 0)) {
|
||||
if c == ' ' {
|
||||
indent += 1;
|
||||
} else {
|
||||
is_blank = c == '\n';
|
||||
break;
|
||||
}
|
||||
}
|
||||
(indent, is_blank)
|
||||
}
|
||||
|
||||
pub fn line_len(&self, row: u32) -> u32 {
|
||||
self.expand_tabs(DisplayPoint::new(row, self.folds_snapshot.line_len(row)))
|
||||
.column()
|
||||
}
|
||||
|
||||
pub fn longest_row(&self) -> u32 {
|
||||
self.folds_snapshot.longest_row()
|
||||
}
|
||||
|
||||
pub fn anchor_before(&self, point: DisplayPoint, bias: Bias) -> Anchor {
|
||||
self.buffer_snapshot
|
||||
.anchor_before(point.to_buffer_point(self, bias))
|
||||
}
|
||||
|
||||
pub fn anchor_after(&self, point: DisplayPoint, bias: Bias) -> Anchor {
|
||||
self.buffer_snapshot
|
||||
.anchor_after(point.to_buffer_point(self, bias))
|
||||
}
|
||||
|
||||
fn expand_tabs(&self, mut point: DisplayPoint) -> DisplayPoint {
|
||||
let chars = self
|
||||
.folds_snapshot
|
||||
@@ -257,32 +246,23 @@ impl DisplayPoint {
|
||||
&mut self.0.column
|
||||
}
|
||||
|
||||
pub fn to_buffer_point(self, map: &DisplayMap, bias: Bias, cx: &AppContext) -> Point {
|
||||
map.fold_map
|
||||
.snapshot(cx)
|
||||
.to_buffer_point(self.collapse_tabs(map, bias, cx))
|
||||
pub fn to_buffer_point(self, map: &DisplayMapSnapshot, bias: Bias) -> Point {
|
||||
map.folds_snapshot
|
||||
.to_buffer_point(map.collapse_tabs(self, bias).0)
|
||||
}
|
||||
|
||||
pub fn to_buffer_offset(self, map: &DisplayMap, bias: Bias, cx: &AppContext) -> usize {
|
||||
map.fold_map
|
||||
.snapshot(cx)
|
||||
.to_buffer_offset(self.collapse_tabs(&map, bias, cx))
|
||||
}
|
||||
|
||||
fn expand_tabs(self, map: &DisplayMap, cx: &AppContext) -> Self {
|
||||
map.snapshot(cx).expand_tabs(self)
|
||||
}
|
||||
|
||||
fn collapse_tabs(self, map: &DisplayMap, bias: Bias, cx: &AppContext) -> Self {
|
||||
map.snapshot(cx).collapse_tabs(self, bias).0
|
||||
pub fn to_buffer_offset(self, map: &DisplayMapSnapshot, bias: Bias) -> usize {
|
||||
map.folds_snapshot
|
||||
.to_buffer_offset(map.collapse_tabs(self, bias).0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Point {
|
||||
pub fn to_display_point(self, map: &DisplayMap, cx: &AppContext) -> DisplayPoint {
|
||||
let mut display_point = map.fold_map.snapshot(cx).to_display_point(self);
|
||||
let snapshot = map.fold_map.snapshot(cx);
|
||||
let chars = snapshot.chars_at(DisplayPoint::new(display_point.row(), 0));
|
||||
pub fn to_display_point(self, map: &DisplayMapSnapshot) -> DisplayPoint {
|
||||
let mut display_point = map.folds_snapshot.to_display_point(self);
|
||||
let chars = map
|
||||
.folds_snapshot
|
||||
.chars_at(DisplayPoint::new(display_point.row(), 0));
|
||||
*display_point.column_mut() =
|
||||
expand_tabs(chars, display_point.column() as usize, map.tab_size) as u32;
|
||||
display_point
|
||||
@@ -290,8 +270,8 @@ impl Point {
|
||||
}
|
||||
|
||||
impl Anchor {
|
||||
pub fn to_display_point(&self, map: &DisplayMap, cx: &AppContext) -> DisplayPoint {
|
||||
self.to_point(map.buffer.read(cx)).to_display_point(map, cx)
|
||||
pub fn to_display_point(&self, map: &DisplayMapSnapshot) -> DisplayPoint {
|
||||
self.to_point(&map.buffer_snapshot).to_display_point(map)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -610,9 +590,9 @@ mod tests {
|
||||
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx));
|
||||
let cx = cx.as_ref();
|
||||
let map = DisplayMap::new(buffer.clone(), 4, cx);
|
||||
assert_eq!(map.text(cx), display_text);
|
||||
|
||||
let map = map.snapshot(cx);
|
||||
|
||||
assert_eq!(map.text(), display_text);
|
||||
for (input_column, bias, output_column) in vec![
|
||||
("'a', '".len(), Left, "'a', '".len()),
|
||||
("'a', '".len() + 1, Left, "'a', '".len()),
|
||||
@@ -652,62 +632,59 @@ mod tests {
|
||||
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx));
|
||||
let cx = cx.as_ref();
|
||||
let map = DisplayMap::new(buffer.clone(), 4, cx);
|
||||
assert_eq!(map.text(cx), "✅ α\nβ \n🏀β γ");
|
||||
let map = map.snapshot(cx);
|
||||
assert_eq!(map.text(), "✅ α\nβ \n🏀β γ");
|
||||
|
||||
let point = Point::new(0, "✅\t\t".len() as u32);
|
||||
let display_point = DisplayPoint::new(0, "✅ ".len() as u32);
|
||||
assert_eq!(point.to_display_point(&map, cx), display_point);
|
||||
assert_eq!(display_point.to_buffer_point(&map, Bias::Left, cx), point,);
|
||||
assert_eq!(point.to_display_point(&map), display_point);
|
||||
assert_eq!(display_point.to_buffer_point(&map, Bias::Left), point,);
|
||||
|
||||
let point = Point::new(1, "β\t".len() as u32);
|
||||
let display_point = DisplayPoint::new(1, "β ".len() as u32);
|
||||
assert_eq!(point.to_display_point(&map, cx), display_point);
|
||||
assert_eq!(display_point.to_buffer_point(&map, Bias::Left, cx), point,);
|
||||
assert_eq!(point.to_display_point(&map), display_point);
|
||||
assert_eq!(display_point.to_buffer_point(&map, Bias::Left), point,);
|
||||
|
||||
let point = Point::new(2, "🏀β\t\t".len() as u32);
|
||||
let display_point = DisplayPoint::new(2, "🏀β ".len() as u32);
|
||||
assert_eq!(point.to_display_point(&map, cx), display_point);
|
||||
assert_eq!(display_point.to_buffer_point(&map, Bias::Left, cx), point,);
|
||||
assert_eq!(point.to_display_point(&map), display_point);
|
||||
assert_eq!(display_point.to_buffer_point(&map, Bias::Left), point,);
|
||||
|
||||
// Display points inside of expanded tabs
|
||||
assert_eq!(
|
||||
DisplayPoint::new(0, "✅ ".len() as u32).to_buffer_point(&map, Bias::Right, cx),
|
||||
DisplayPoint::new(0, "✅ ".len() as u32).to_buffer_point(&map, Bias::Right),
|
||||
Point::new(0, "✅\t\t".len() as u32),
|
||||
);
|
||||
assert_eq!(
|
||||
DisplayPoint::new(0, "✅ ".len() as u32).to_buffer_point(&map, Bias::Left, cx),
|
||||
DisplayPoint::new(0, "✅ ".len() as u32).to_buffer_point(&map, Bias::Left),
|
||||
Point::new(0, "✅\t".len() as u32),
|
||||
);
|
||||
assert_eq!(
|
||||
map.snapshot(cx)
|
||||
.chunks_at(DisplayPoint::new(0, "✅ ".len() as u32))
|
||||
map.chunks_at(DisplayPoint::new(0, "✅ ".len() as u32))
|
||||
.collect::<String>(),
|
||||
" α\nβ \n🏀β γ"
|
||||
);
|
||||
assert_eq!(
|
||||
DisplayPoint::new(0, "✅ ".len() as u32).to_buffer_point(&map, Bias::Right, cx),
|
||||
DisplayPoint::new(0, "✅ ".len() as u32).to_buffer_point(&map, Bias::Right),
|
||||
Point::new(0, "✅\t".len() as u32),
|
||||
);
|
||||
assert_eq!(
|
||||
DisplayPoint::new(0, "✅ ".len() as u32).to_buffer_point(&map, Bias::Left, cx),
|
||||
DisplayPoint::new(0, "✅ ".len() as u32).to_buffer_point(&map, Bias::Left),
|
||||
Point::new(0, "✅".len() as u32),
|
||||
);
|
||||
assert_eq!(
|
||||
map.snapshot(cx)
|
||||
.chunks_at(DisplayPoint::new(0, "✅ ".len() as u32))
|
||||
map.chunks_at(DisplayPoint::new(0, "✅ ".len() as u32))
|
||||
.collect::<String>(),
|
||||
" α\nβ \n🏀β γ"
|
||||
);
|
||||
|
||||
// Clipping display points inside of multi-byte characters
|
||||
assert_eq!(
|
||||
map.snapshot(cx)
|
||||
.clip_point(DisplayPoint::new(0, "✅".len() as u32 - 1), Bias::Left),
|
||||
map.clip_point(DisplayPoint::new(0, "✅".len() as u32 - 1), Bias::Left),
|
||||
DisplayPoint::new(0, 0)
|
||||
);
|
||||
assert_eq!(
|
||||
map.snapshot(cx)
|
||||
.clip_point(DisplayPoint::new(0, "✅".len() as u32 - 1), Bias::Right),
|
||||
map.clip_point(DisplayPoint::new(0, "✅".len() as u32 - 1), Bias::Right),
|
||||
DisplayPoint::new(0, "✅".len() as u32)
|
||||
);
|
||||
}
|
||||
@@ -716,6 +693,9 @@ mod tests {
|
||||
fn test_max_point(cx: &mut gpui::MutableAppContext) {
|
||||
let buffer = cx.add_model(|cx| Buffer::new(0, "aaa\n\t\tbbb", cx));
|
||||
let map = DisplayMap::new(buffer.clone(), 4, cx.as_ref());
|
||||
assert_eq!(map.max_point(cx.as_ref()), DisplayPoint::new(1, 11))
|
||||
assert_eq!(
|
||||
map.snapshot(cx.as_ref()).max_point(),
|
||||
DisplayPoint::new(1, 11)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::{
|
||||
time,
|
||||
util::Bias,
|
||||
};
|
||||
use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task};
|
||||
use gpui::{Entity, ModelContext, ModelHandle, Task};
|
||||
use parking_lot::Mutex;
|
||||
use postage::{
|
||||
mpsc,
|
||||
|
||||
+20
-34
@@ -1,35 +1,32 @@
|
||||
use super::{Bias, DisplayMap, DisplayPoint, SelectionGoal};
|
||||
use super::{Bias, DisplayMapSnapshot, DisplayPoint, SelectionGoal};
|
||||
use anyhow::Result;
|
||||
use gpui::AppContext;
|
||||
|
||||
pub fn left(map: &DisplayMap, mut point: DisplayPoint, cx: &AppContext) -> Result<DisplayPoint> {
|
||||
pub fn left(map: &DisplayMapSnapshot, mut point: DisplayPoint) -> Result<DisplayPoint> {
|
||||
if point.column() > 0 {
|
||||
*point.column_mut() -= 1;
|
||||
} else if point.row() > 0 {
|
||||
*point.row_mut() -= 1;
|
||||
*point.column_mut() = map.line_len(point.row(), cx);
|
||||
*point.column_mut() = map.line_len(point.row());
|
||||
}
|
||||
Ok(map.snapshot(cx).clip_point(point, Bias::Left))
|
||||
Ok(map.clip_point(point, Bias::Left))
|
||||
}
|
||||
|
||||
pub fn right(map: &DisplayMap, mut point: DisplayPoint, cx: &AppContext) -> Result<DisplayPoint> {
|
||||
let max_column = map.line_len(point.row(), cx);
|
||||
pub fn right(map: &DisplayMapSnapshot, mut point: DisplayPoint) -> Result<DisplayPoint> {
|
||||
let max_column = map.line_len(point.row());
|
||||
if point.column() < max_column {
|
||||
*point.column_mut() += 1;
|
||||
} else if point.row() < map.max_point(cx).row() {
|
||||
} else if point.row() < map.max_point().row() {
|
||||
*point.row_mut() += 1;
|
||||
*point.column_mut() = 0;
|
||||
}
|
||||
Ok(map.snapshot(cx).clip_point(point, Bias::Right))
|
||||
Ok(map.clip_point(point, Bias::Right))
|
||||
}
|
||||
|
||||
pub fn up(
|
||||
map: &DisplayMap,
|
||||
map: &DisplayMapSnapshot,
|
||||
mut point: DisplayPoint,
|
||||
goal: SelectionGoal,
|
||||
cx: &AppContext,
|
||||
) -> Result<(DisplayPoint, SelectionGoal)> {
|
||||
let map = map.snapshot(cx);
|
||||
let goal_column = if let SelectionGoal::Column(column) = goal {
|
||||
column
|
||||
} else {
|
||||
@@ -47,13 +44,11 @@ pub fn up(
|
||||
}
|
||||
|
||||
pub fn down(
|
||||
map: &DisplayMap,
|
||||
map: &DisplayMapSnapshot,
|
||||
mut point: DisplayPoint,
|
||||
goal: SelectionGoal,
|
||||
cx: &AppContext,
|
||||
) -> Result<(DisplayPoint, SelectionGoal)> {
|
||||
let max_point = map.max_point(cx);
|
||||
let map = map.snapshot(cx);
|
||||
let max_point = map.max_point();
|
||||
let goal_column = if let SelectionGoal::Column(column) = goal {
|
||||
column
|
||||
} else {
|
||||
@@ -71,12 +66,11 @@ pub fn down(
|
||||
}
|
||||
|
||||
pub fn line_beginning(
|
||||
map: &DisplayMap,
|
||||
map: &DisplayMapSnapshot,
|
||||
point: DisplayPoint,
|
||||
toggle_indent: bool,
|
||||
cx: &AppContext,
|
||||
) -> Result<DisplayPoint> {
|
||||
let (indent, is_blank) = map.line_indent(point.row(), cx);
|
||||
let (indent, is_blank) = map.line_indent(point.row());
|
||||
if toggle_indent && !is_blank && point.column() != indent {
|
||||
Ok(DisplayPoint::new(point.row(), indent))
|
||||
} else {
|
||||
@@ -84,30 +78,23 @@ pub fn line_beginning(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn line_end(map: &DisplayMap, point: DisplayPoint, cx: &AppContext) -> Result<DisplayPoint> {
|
||||
Ok(DisplayPoint::new(
|
||||
point.row(),
|
||||
map.line_len(point.row(), cx),
|
||||
))
|
||||
pub fn line_end(map: &DisplayMapSnapshot, point: DisplayPoint) -> Result<DisplayPoint> {
|
||||
Ok(DisplayPoint::new(point.row(), map.line_len(point.row())))
|
||||
}
|
||||
|
||||
pub fn prev_word_boundary(
|
||||
map: &DisplayMap,
|
||||
point: DisplayPoint,
|
||||
cx: &AppContext,
|
||||
) -> Result<DisplayPoint> {
|
||||
pub fn prev_word_boundary(map: &DisplayMapSnapshot, point: DisplayPoint) -> Result<DisplayPoint> {
|
||||
if point.column() == 0 {
|
||||
if point.row() == 0 {
|
||||
Ok(DisplayPoint::new(0, 0))
|
||||
} else {
|
||||
let row = point.row() - 1;
|
||||
Ok(DisplayPoint::new(row, map.line_len(row, cx)))
|
||||
Ok(DisplayPoint::new(row, map.line_len(row)))
|
||||
}
|
||||
} else {
|
||||
let mut boundary = DisplayPoint::new(point.row(), 0);
|
||||
let mut column = 0;
|
||||
let mut prev_c = None;
|
||||
for c in map.snapshot(cx).chars_at(boundary) {
|
||||
for c in map.chars_at(boundary) {
|
||||
if column >= point.column() {
|
||||
break;
|
||||
}
|
||||
@@ -124,12 +111,11 @@ pub fn prev_word_boundary(
|
||||
}
|
||||
|
||||
pub fn next_word_boundary(
|
||||
map: &DisplayMap,
|
||||
map: &DisplayMapSnapshot,
|
||||
mut point: DisplayPoint,
|
||||
cx: &AppContext,
|
||||
) -> Result<DisplayPoint> {
|
||||
let mut prev_c = None;
|
||||
for c in map.snapshot(cx).chars_at(point) {
|
||||
for c in map.chars_at(point) {
|
||||
if prev_c.is_some() && (c == '\n' || char_kind(prev_c.unwrap()) != char_kind(c)) {
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user