Fix vim selection to include entire range
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
parent
e6f3e0ab9c
commit
b53fb8633e
21 changed files with 489 additions and 335 deletions
|
@ -35,6 +35,12 @@ pub enum FoldStatus {
|
|||
Foldable,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Clip {
|
||||
None,
|
||||
EndOfLine,
|
||||
}
|
||||
|
||||
pub trait ToDisplayPoint {
|
||||
fn to_display_point(&self, map: &DisplaySnapshot) -> DisplayPoint;
|
||||
}
|
||||
|
@ -50,7 +56,7 @@ pub struct DisplayMap {
|
|||
wrap_map: ModelHandle<WrapMap>,
|
||||
block_map: BlockMap,
|
||||
text_highlights: TextHighlights,
|
||||
pub clip_at_line_ends: bool,
|
||||
pub default_clip: Clip,
|
||||
}
|
||||
|
||||
impl Entity for DisplayMap {
|
||||
|
@ -85,7 +91,7 @@ impl DisplayMap {
|
|||
wrap_map,
|
||||
block_map,
|
||||
text_highlights: Default::default(),
|
||||
clip_at_line_ends: false,
|
||||
default_clip: Clip::None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,7 +115,7 @@ impl DisplayMap {
|
|||
wrap_snapshot,
|
||||
block_snapshot,
|
||||
text_highlights: self.text_highlights.clone(),
|
||||
clip_at_line_ends: self.clip_at_line_ends,
|
||||
default_clip: self.default_clip,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -296,7 +302,7 @@ pub struct DisplaySnapshot {
|
|||
wrap_snapshot: wrap_map::WrapSnapshot,
|
||||
block_snapshot: block_map::BlockSnapshot,
|
||||
text_highlights: TextHighlights,
|
||||
clip_at_line_ends: bool,
|
||||
default_clip: Clip,
|
||||
}
|
||||
|
||||
impl DisplaySnapshot {
|
||||
|
@ -577,21 +583,33 @@ impl DisplaySnapshot {
|
|||
column
|
||||
}
|
||||
|
||||
pub fn clip_point(&self, point: DisplayPoint, bias: Bias) -> DisplayPoint {
|
||||
let mut clipped = self.block_snapshot.clip_point(point.0, bias);
|
||||
if self.clip_at_line_ends {
|
||||
clipped = self.clip_at_line_end(DisplayPoint(clipped)).0
|
||||
}
|
||||
DisplayPoint(clipped)
|
||||
pub fn move_left(&self, point: DisplayPoint, clip: Clip) -> DisplayPoint {
|
||||
self.clip_point_with(
|
||||
DisplayPoint::new(point.row(), point.column().saturating_sub(1)),
|
||||
Bias::Left,
|
||||
clip,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn clip_at_line_end(&self, point: DisplayPoint) -> DisplayPoint {
|
||||
let mut point = point.0;
|
||||
if point.column == self.line_len(point.row) {
|
||||
point.column = point.column.saturating_sub(1);
|
||||
point = self.block_snapshot.clip_point(point, Bias::Left);
|
||||
pub fn move_right(&self, point: DisplayPoint, clip: Clip) -> DisplayPoint {
|
||||
self.clip_point_with(
|
||||
DisplayPoint::new(point.row(), point.column() + 1),
|
||||
Bias::Right,
|
||||
clip,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn clip_point_with(&self, point: DisplayPoint, bias: Bias, clip: Clip) -> DisplayPoint {
|
||||
let new_point = DisplayPoint(self.block_snapshot.clip_point(point.0, bias));
|
||||
if clip == Clip::EndOfLine && new_point.column() == self.line_len(new_point.row()) {
|
||||
self.move_left(new_point, Clip::None)
|
||||
} else {
|
||||
new_point
|
||||
}
|
||||
DisplayPoint(point)
|
||||
}
|
||||
|
||||
pub fn clip_point(&self, point: DisplayPoint, bias: Bias) -> DisplayPoint {
|
||||
self.clip_point_with(point, bias, self.default_clip)
|
||||
}
|
||||
|
||||
pub fn folds_in_range<T>(&self, range: Range<T>) -> impl Iterator<Item = &Range<Anchor>>
|
||||
|
@ -1580,7 +1598,7 @@ pub mod tests {
|
|||
|
||||
fn assert(text: &str, cx: &mut gpui::AppContext) {
|
||||
let (mut unmarked_snapshot, markers) = marked_display_snapshot(text, cx);
|
||||
unmarked_snapshot.clip_at_line_ends = true;
|
||||
unmarked_snapshot.default_clip = Clip::EndOfLine;
|
||||
assert_eq!(
|
||||
unmarked_snapshot.clip_point(markers[1], Bias::Left),
|
||||
markers[0]
|
||||
|
|
|
@ -1544,10 +1544,10 @@ impl Editor {
|
|||
range.clone()
|
||||
}
|
||||
|
||||
pub fn set_clip_at_line_ends(&mut self, clip: bool, cx: &mut ViewContext<Self>) {
|
||||
if self.display_map.read(cx).clip_at_line_ends != clip {
|
||||
pub fn set_default_clip(&mut self, clip: Clip, cx: &mut ViewContext<Self>) {
|
||||
if self.display_map.read(cx).default_clip != clip {
|
||||
self.display_map
|
||||
.update(cx, |map, _| map.clip_at_line_ends = clip);
|
||||
.update(cx, |map, _| map.default_clip = clip);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ enum FoldMarkers {}
|
|||
|
||||
struct SelectionLayout {
|
||||
head: DisplayPoint,
|
||||
reversed: bool,
|
||||
cursor_shape: CursorShape,
|
||||
is_newest: bool,
|
||||
range: Range<DisplayPoint>,
|
||||
|
@ -78,6 +79,7 @@ impl SelectionLayout {
|
|||
let point_range = map.expand_to_line(selection.range());
|
||||
Self {
|
||||
head: selection.head().to_display_point(map),
|
||||
reversed: selection.reversed,
|
||||
cursor_shape,
|
||||
is_newest,
|
||||
range: point_range.start.to_display_point(map)
|
||||
|
@ -87,6 +89,7 @@ impl SelectionLayout {
|
|||
let selection = selection.map(|p| p.to_display_point(map));
|
||||
Self {
|
||||
head: selection.head(),
|
||||
reversed: selection.reversed,
|
||||
cursor_shape,
|
||||
is_newest,
|
||||
range: selection.range(),
|
||||
|
@ -844,6 +847,7 @@ impl EditorElement {
|
|||
|
||||
if editor.show_local_cursors(cx) || replica_id != local_replica_id {
|
||||
let cursor_position = selection.head;
|
||||
|
||||
if layout
|
||||
.visible_display_row_range
|
||||
.contains(&cursor_position.row())
|
||||
|
@ -851,7 +855,15 @@ impl EditorElement {
|
|||
let cursor_row_layout = &layout.position_map.line_layouts
|
||||
[(cursor_position.row() - start_row) as usize]
|
||||
.line;
|
||||
let cursor_column = cursor_position.column() as usize;
|
||||
let mut cursor_column = cursor_position.column() as usize;
|
||||
|
||||
if CursorShape::Block == selection.cursor_shape
|
||||
&& !selection.range.is_empty()
|
||||
&& !selection.reversed
|
||||
&& cursor_column > 0
|
||||
{
|
||||
cursor_column -= 1;
|
||||
}
|
||||
|
||||
let cursor_character_x = cursor_row_layout.x_for_index(cursor_column);
|
||||
let mut block_width =
|
||||
|
@ -863,7 +875,10 @@ impl EditorElement {
|
|||
layout
|
||||
.position_map
|
||||
.snapshot
|
||||
.chars_at(cursor_position)
|
||||
.chars_at(DisplayPoint::new(
|
||||
cursor_position.row(),
|
||||
cursor_column as u32,
|
||||
))
|
||||
.next()
|
||||
.and_then(|(character, _)| {
|
||||
let font_id =
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue