Add clip_to_line_end to display_map/snapshot and set it to ensure vim positioning in normal mode
Co-authored-by: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
bb9b36dccd
commit
0aaf270650
10 changed files with 142 additions and 104 deletions
|
@ -3,13 +3,13 @@ use gpui::ViewContext;
|
|||
use language::{Selection, SelectionGoal};
|
||||
|
||||
pub trait VimEditorExt {
|
||||
fn adjust_selections(self: &mut Self, cx: &mut ViewContext<Self>);
|
||||
fn adjusted_move_selections(
|
||||
fn clip_selections(self: &mut Self, cx: &mut ViewContext<Self>);
|
||||
fn clipped_move_selections(
|
||||
self: &mut Self,
|
||||
cx: &mut ViewContext<Self>,
|
||||
move_selection: impl Fn(&DisplaySnapshot, &mut Selection<DisplayPoint>),
|
||||
);
|
||||
fn adjusted_move_selection_heads(
|
||||
fn clipped_move_selection_heads(
|
||||
&mut self,
|
||||
cx: &mut ViewContext<Self>,
|
||||
update_head: impl Fn(
|
||||
|
@ -18,7 +18,7 @@ pub trait VimEditorExt {
|
|||
SelectionGoal,
|
||||
) -> (DisplayPoint, SelectionGoal),
|
||||
);
|
||||
fn adjusted_move_cursors(
|
||||
fn clipped_move_cursors(
|
||||
self: &mut Self,
|
||||
cx: &mut ViewContext<Self>,
|
||||
update_cursor_position: impl Fn(
|
||||
|
@ -29,10 +29,7 @@ pub trait VimEditorExt {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn adjust_display_point(
|
||||
map: &DisplaySnapshot,
|
||||
mut display_point: DisplayPoint,
|
||||
) -> DisplayPoint {
|
||||
pub fn clip_display_point(map: &DisplaySnapshot, mut display_point: DisplayPoint) -> DisplayPoint {
|
||||
let next_char = map.chars_at(display_point).next();
|
||||
if next_char == Some('\n') || next_char == None {
|
||||
*display_point.column_mut() = display_point.column().saturating_sub(1);
|
||||
|
@ -42,31 +39,31 @@ pub fn adjust_display_point(
|
|||
}
|
||||
|
||||
impl VimEditorExt for Editor {
|
||||
fn adjust_selections(self: &mut Self, cx: &mut ViewContext<Self>) {
|
||||
fn clip_selections(self: &mut Self, cx: &mut ViewContext<Self>) {
|
||||
self.move_selections(cx, |map, selection| {
|
||||
if selection.is_empty() {
|
||||
let adjusted_cursor = adjust_display_point(map, selection.start);
|
||||
let adjusted_cursor = clip_display_point(map, selection.start);
|
||||
selection.collapse_to(adjusted_cursor, selection.goal);
|
||||
} else {
|
||||
let adjusted_head = adjust_display_point(map, selection.head());
|
||||
let adjusted_head = clip_display_point(map, selection.head());
|
||||
selection.set_head(adjusted_head, selection.goal);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn adjusted_move_selections(
|
||||
fn clipped_move_selections(
|
||||
self: &mut Self,
|
||||
cx: &mut ViewContext<Self>,
|
||||
move_selection: impl Fn(&DisplaySnapshot, &mut Selection<DisplayPoint>),
|
||||
) {
|
||||
self.move_selections(cx, |map, selection| {
|
||||
move_selection(map, selection);
|
||||
let adjusted_head = adjust_display_point(map, selection.head());
|
||||
let adjusted_head = clip_display_point(map, selection.head());
|
||||
selection.set_head(adjusted_head, selection.goal);
|
||||
})
|
||||
}
|
||||
|
||||
fn adjusted_move_selection_heads(
|
||||
fn clipped_move_selection_heads(
|
||||
&mut self,
|
||||
cx: &mut ViewContext<Self>,
|
||||
update_head: impl Fn(
|
||||
|
@ -75,14 +72,14 @@ impl VimEditorExt for Editor {
|
|||
SelectionGoal,
|
||||
) -> (DisplayPoint, SelectionGoal),
|
||||
) {
|
||||
self.adjusted_move_selections(cx, |map, selection| {
|
||||
self.clipped_move_selections(cx, |map, selection| {
|
||||
let (new_head, new_goal) = update_head(map, selection.head(), selection.goal);
|
||||
let adjusted_head = adjust_display_point(map, new_head);
|
||||
let adjusted_head = clip_display_point(map, new_head);
|
||||
selection.set_head(adjusted_head, new_goal);
|
||||
});
|
||||
}
|
||||
|
||||
fn adjusted_move_cursors(
|
||||
fn clipped_move_cursors(
|
||||
self: &mut Self,
|
||||
cx: &mut ViewContext<Self>,
|
||||
update_cursor_position: impl Fn(
|
||||
|
@ -93,7 +90,7 @@ impl VimEditorExt for Editor {
|
|||
) {
|
||||
self.move_selections(cx, |map, selection| {
|
||||
let (cursor, new_goal) = update_cursor_position(map, selection.head(), selection.goal);
|
||||
let adjusted_cursor = adjust_display_point(map, cursor);
|
||||
let adjusted_cursor = clip_display_point(map, cursor);
|
||||
selection.collapse_to(adjusted_cursor, new_goal);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ pub fn init(cx: &mut MutableAppContext) {
|
|||
fn normal_before(_: &mut Workspace, _: &NormalBefore, cx: &mut ViewContext<Workspace>) {
|
||||
VimState::switch_mode(&SwitchMode(Mode::Normal), cx);
|
||||
VimState::update_active_editor(cx, |editor, cx| {
|
||||
editor.adjusted_move_cursors(cx, |map, mut cursor, _| {
|
||||
editor.clipped_move_cursors(cx, |map, mut cursor, _| {
|
||||
*cursor.column_mut() = cursor.column().saturating_sub(1);
|
||||
(map.clip_point(cursor, Bias::Left), SelectionGoal::None)
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@ use gpui::{action, keymap::Binding, MutableAppContext, ViewContext};
|
|||
use language::SelectionGoal;
|
||||
use workspace::Workspace;
|
||||
|
||||
use crate::{editor_utils::VimEditorExt, Mode, SwitchMode, VimState};
|
||||
use crate::{Mode, SwitchMode, VimState};
|
||||
|
||||
action!(InsertBefore);
|
||||
action!(MoveLeft);
|
||||
|
@ -29,7 +29,7 @@ pub fn init(cx: &mut MutableAppContext) {
|
|||
|
||||
fn move_left(_: &mut Workspace, _: &MoveLeft, cx: &mut ViewContext<Workspace>) {
|
||||
VimState::update_active_editor(cx, |editor, cx| {
|
||||
editor.adjusted_move_cursors(cx, |map, mut cursor, _| {
|
||||
editor.move_cursors(cx, |map, mut cursor, _| {
|
||||
*cursor.column_mut() = cursor.column().saturating_sub(1);
|
||||
(map.clip_point(cursor, Bias::Left), SelectionGoal::None)
|
||||
});
|
||||
|
@ -38,19 +38,19 @@ fn move_left(_: &mut Workspace, _: &MoveLeft, cx: &mut ViewContext<Workspace>) {
|
|||
|
||||
fn move_down(_: &mut Workspace, _: &MoveDown, cx: &mut ViewContext<Workspace>) {
|
||||
VimState::update_active_editor(cx, |editor, cx| {
|
||||
editor.adjusted_move_cursors(cx, movement::down);
|
||||
editor.move_cursors(cx, movement::down);
|
||||
});
|
||||
}
|
||||
|
||||
fn move_up(_: &mut Workspace, _: &MoveUp, cx: &mut ViewContext<Workspace>) {
|
||||
VimState::update_active_editor(cx, |editor, cx| {
|
||||
editor.adjusted_move_cursors(cx, movement::up);
|
||||
editor.move_cursors(cx, movement::up);
|
||||
});
|
||||
}
|
||||
|
||||
fn move_right(_: &mut Workspace, _: &MoveRight, cx: &mut ViewContext<Workspace>) {
|
||||
VimState::update_active_editor(cx, |editor, cx| {
|
||||
editor.adjusted_move_cursors(cx, |map, mut cursor, _| {
|
||||
editor.move_cursors(cx, |map, mut cursor, _| {
|
||||
*cursor.column_mut() += 1;
|
||||
(map.clip_point(cursor, Bias::Right), SelectionGoal::None)
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@ mod normal;
|
|||
mod vim_tests;
|
||||
|
||||
use collections::HashMap;
|
||||
use editor::Editor;
|
||||
use editor::{CursorShape, Editor};
|
||||
use editor_utils::VimEditorExt;
|
||||
use gpui::{action, MutableAppContext, ViewContext, WeakViewHandle};
|
||||
|
||||
|
@ -59,7 +59,7 @@ impl VimState {
|
|||
active_editor.set_keymap_context_layer::<Self>(mode.keymap_context_layer());
|
||||
active_editor.set_input_enabled(*mode == Mode::Insert);
|
||||
if *mode != Mode::Insert {
|
||||
active_editor.adjust_selections(cx);
|
||||
active_editor.clip_selections(cx);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -89,6 +89,7 @@ impl VimState {
|
|||
if let Some(editor) = editor.upgrade(cx) {
|
||||
editor.update(cx, |editor, cx| {
|
||||
editor.set_cursor_shape(cursor_shape, cx);
|
||||
editor.set_clip_at_line_ends(cursor_shape == CursorShape::Block, cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use editor::{display_map::ToDisplayPoint, DisplayPoint};
|
||||
use gpui::{json::json, keymap::Keystroke, AppContext, ViewHandle};
|
||||
use gpui::{json::json, keymap::Keystroke, ViewHandle};
|
||||
use language::{Point, Selection};
|
||||
use workspace::{WorkspaceHandle, WorkspaceParams};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue