Fix clipping when dragging the mouse with vim-mode enabled and adjust single line editor selections

This commit is contained in:
K Simmons 2022-07-18 13:33:55 -07:00
parent c2868a39e8
commit 1cfaac1bc5
9 changed files with 36 additions and 43 deletions

View file

@ -1643,12 +1643,12 @@ impl PaintState {
} else { } else {
0 0
}; };
let column_overshoot = (0f32.max(x - line.width()) / layout.em_advance) as u32;
( let point = snapshot.clip_point(DisplayPoint::new(row, column), Bias::Left);
DisplayPoint::new(row, column), let mut column_overshoot = (0f32.max(x - line.width()) / layout.em_advance) as u32;
DisplayPoint::new(row_overshoot, column_overshoot), column_overshoot = column_overshoot + column - point.column();
)
(point, DisplayPoint::new(row_overshoot, column_overshoot))
} }
} }

View file

@ -238,6 +238,8 @@ impl Line {
None None
} }
// If round_to_closest, find the closest index to the given x position
// If !round_to_closest, find the largest index before the given x position
pub fn index_for_x(&self, x: f32) -> Option<usize> { pub fn index_for_x(&self, x: f32) -> Option<usize> {
if x >= self.layout.width { if x >= self.layout.width {
None None

View file

@ -34,12 +34,13 @@ fn editor_focused(EditorFocused(editor): &EditorFocused, cx: &mut MutableAppCont
} }
let editor = editor.read(cx); let editor = editor.read(cx);
if editor.selections.newest::<usize>(cx).is_empty() { let editor_mode = editor.mode();
if editor.mode() != EditorMode::Full { let newest_selection_empty = editor.selections.newest::<usize>(cx).is_empty();
vim.switch_mode(Mode::Insert, cx);
} if editor_mode != EditorMode::Full {
} else { vim.switch_mode(Mode::Insert, true, cx);
vim.switch_mode(Mode::Visual { line: false }, cx); } else if !newest_selection_empty {
vim.switch_mode(Mode::Visual { line: false }, true, cx);
} }
}); });
} }
@ -69,7 +70,7 @@ fn editor_released(EditorReleased(editor): &EditorReleased, cx: &mut MutableAppC
fn editor_local_selections_changed(newest_empty: bool, cx: &mut MutableAppContext) { fn editor_local_selections_changed(newest_empty: bool, cx: &mut MutableAppContext) {
Vim::update(cx, |vim, cx| { Vim::update(cx, |vim, cx| {
if vim.enabled && vim.state.mode == Mode::Normal && !newest_empty { if vim.enabled && vim.state.mode == Mode::Normal && !newest_empty {
vim.switch_mode(Mode::Visual { line: false }, cx) vim.switch_mode(Mode::Visual { line: false }, false, cx)
} }
}) })
} }

View file

@ -20,7 +20,7 @@ fn normal_before(_: &mut Workspace, _: &NormalBefore, cx: &mut ViewContext<Works
}); });
}); });
}); });
state.switch_mode(Mode::Normal, cx); state.switch_mode(Mode::Normal, false, cx);
}) })
} }

View file

@ -91,7 +91,7 @@ fn move_cursor(vim: &mut Vim, motion: Motion, cx: &mut MutableAppContext) {
fn insert_after(_: &mut Workspace, _: &InsertAfter, cx: &mut ViewContext<Workspace>) { fn insert_after(_: &mut Workspace, _: &InsertAfter, cx: &mut ViewContext<Workspace>) {
Vim::update(cx, |vim, cx| { Vim::update(cx, |vim, cx| {
vim.switch_mode(Mode::Insert, cx); vim.switch_mode(Mode::Insert, false, cx);
vim.update_active_editor(cx, |editor, cx| { vim.update_active_editor(cx, |editor, cx| {
editor.change_selections(Some(Autoscroll::Fit), cx, |s| { editor.change_selections(Some(Autoscroll::Fit), cx, |s| {
s.move_cursors_with(|map, cursor, goal| { s.move_cursors_with(|map, cursor, goal| {
@ -108,7 +108,7 @@ fn insert_first_non_whitespace(
cx: &mut ViewContext<Workspace>, cx: &mut ViewContext<Workspace>,
) { ) {
Vim::update(cx, |vim, cx| { Vim::update(cx, |vim, cx| {
vim.switch_mode(Mode::Insert, cx); vim.switch_mode(Mode::Insert, false, cx);
vim.update_active_editor(cx, |editor, cx| { vim.update_active_editor(cx, |editor, cx| {
editor.change_selections(Some(Autoscroll::Fit), cx, |s| { editor.change_selections(Some(Autoscroll::Fit), cx, |s| {
s.move_cursors_with(|map, cursor, goal| { s.move_cursors_with(|map, cursor, goal| {
@ -121,7 +121,7 @@ fn insert_first_non_whitespace(
fn insert_end_of_line(_: &mut Workspace, _: &InsertEndOfLine, cx: &mut ViewContext<Workspace>) { fn insert_end_of_line(_: &mut Workspace, _: &InsertEndOfLine, cx: &mut ViewContext<Workspace>) {
Vim::update(cx, |vim, cx| { Vim::update(cx, |vim, cx| {
vim.switch_mode(Mode::Insert, cx); vim.switch_mode(Mode::Insert, false, cx);
vim.update_active_editor(cx, |editor, cx| { vim.update_active_editor(cx, |editor, cx| {
editor.change_selections(Some(Autoscroll::Fit), cx, |s| { editor.change_selections(Some(Autoscroll::Fit), cx, |s| {
s.move_cursors_with(|map, cursor, goal| { s.move_cursors_with(|map, cursor, goal| {
@ -134,7 +134,7 @@ fn insert_end_of_line(_: &mut Workspace, _: &InsertEndOfLine, cx: &mut ViewConte
fn insert_line_above(_: &mut Workspace, _: &InsertLineAbove, cx: &mut ViewContext<Workspace>) { fn insert_line_above(_: &mut Workspace, _: &InsertLineAbove, cx: &mut ViewContext<Workspace>) {
Vim::update(cx, |vim, cx| { Vim::update(cx, |vim, cx| {
vim.switch_mode(Mode::Insert, cx); vim.switch_mode(Mode::Insert, false, cx);
vim.update_active_editor(cx, |editor, cx| { vim.update_active_editor(cx, |editor, cx| {
editor.transact(cx, |editor, cx| { editor.transact(cx, |editor, cx| {
let (map, old_selections) = editor.selections.all_display(cx); let (map, old_selections) = editor.selections.all_display(cx);
@ -166,7 +166,7 @@ fn insert_line_above(_: &mut Workspace, _: &InsertLineAbove, cx: &mut ViewContex
fn insert_line_below(_: &mut Workspace, _: &InsertLineBelow, cx: &mut ViewContext<Workspace>) { fn insert_line_below(_: &mut Workspace, _: &InsertLineBelow, cx: &mut ViewContext<Workspace>) {
Vim::update(cx, |vim, cx| { Vim::update(cx, |vim, cx| {
vim.switch_mode(Mode::Insert, cx); vim.switch_mode(Mode::Insert, false, cx);
vim.update_active_editor(cx, |editor, cx| { vim.update_active_editor(cx, |editor, cx| {
editor.transact(cx, |editor, cx| { editor.transact(cx, |editor, cx| {
let (map, old_selections) = editor.selections.all_display(cx); let (map, old_selections) = editor.selections.all_display(cx);

View file

@ -31,7 +31,7 @@ pub fn change_over(vim: &mut Vim, motion: Motion, cx: &mut MutableAppContext) {
editor.insert(&"", cx); editor.insert(&"", cx);
}); });
}); });
vim.switch_mode(Mode::Insert, cx) vim.switch_mode(Mode::Insert, false, cx)
} }
// From the docs https://vimhelp.org/change.txt.html#cw // From the docs https://vimhelp.org/change.txt.html#cw
@ -70,7 +70,7 @@ fn change_word(
editor.insert(&"", cx); editor.insert(&"", cx);
}); });
}); });
vim.switch_mode(Mode::Insert, cx); vim.switch_mode(Mode::Insert, false, cx);
}); });
} }

View file

@ -36,7 +36,7 @@ pub fn init(cx: &mut MutableAppContext) {
// Vim Actions // Vim Actions
cx.add_action(|_: &mut Workspace, &SwitchMode(mode): &SwitchMode, cx| { cx.add_action(|_: &mut Workspace, &SwitchMode(mode): &SwitchMode, cx| {
Vim::update(cx, |vim, cx| vim.switch_mode(mode, cx)) Vim::update(cx, |vim, cx| vim.switch_mode(mode, false, cx))
}); });
cx.add_action( cx.add_action(
|_: &mut Workspace, &PushOperator(operator): &PushOperator, cx| { |_: &mut Workspace, &PushOperator(operator): &PushOperator, cx| {
@ -62,7 +62,7 @@ pub fn init(cx: &mut MutableAppContext) {
if vim.state.mode != Mode::Normal || vim.active_operator().is_some() { if vim.state.mode != Mode::Normal || vim.active_operator().is_some() {
MutableAppContext::defer(cx, |cx| { MutableAppContext::defer(cx, |cx| {
Vim::update(cx, |state, cx| { Vim::update(cx, |state, cx| {
state.switch_mode(Mode::Normal, cx); state.switch_mode(Mode::Normal, false, cx);
}); });
}); });
} else { } else {
@ -115,37 +115,27 @@ impl Vim {
.map(|ae| ae.update(cx, update)) .map(|ae| ae.update(cx, update))
} }
fn switch_mode(&mut self, mode: Mode, cx: &mut MutableAppContext) { fn switch_mode(&mut self, mode: Mode, leave_selections: bool, cx: &mut MutableAppContext) {
let previous_mode = self.state.mode;
self.state.mode = mode; self.state.mode = mode;
self.state.operator_stack.clear(); self.state.operator_stack.clear();
// Sync editor settings like clip mode // Sync editor settings like clip mode
self.sync_vim_settings(cx); self.sync_vim_settings(cx);
if leave_selections {
return;
}
// Adjust selections // Adjust selections
for editor in self.editors.values() { for editor in self.editors.values() {
if let Some(editor) = editor.upgrade(cx) { if let Some(editor) = editor.upgrade(cx) {
editor.update(cx, |editor, cx| { editor.update(cx, |editor, cx| {
editor.change_selections(None, cx, |s| { editor.change_selections(None, cx, |s| {
s.move_with(|map, selection| { s.move_with(|map, selection| {
// If empty selections
if self.state.empty_selections_only() { if self.state.empty_selections_only() {
let new_head = map.clip_point(selection.head(), Bias::Left); let new_head = map.clip_point(selection.head(), Bias::Left);
selection.collapse_to(new_head, selection.goal) selection.collapse_to(new_head, selection.goal)
} else { } else {
if matches!(mode, Mode::Visual { line: false })
&& !matches!(previous_mode, Mode::Visual { .. })
&& !selection.reversed
&& !selection.is_empty()
{
// Mode wasn't visual mode before, but is now. We need to move the end
// back by one character so that the region to be modifed stays the same
*selection.end.column_mut() =
selection.end.column().saturating_sub(1);
selection.end = map.clip_point(selection.end, Bias::Left);
}
selection.set_head( selection.set_head(
map.clip_point(selection.head(), Bias::Left), map.clip_point(selection.head(), Bias::Left),
selection.goal, selection.goal,
@ -183,7 +173,7 @@ impl Vim {
self.enabled = enabled; self.enabled = enabled;
self.state = Default::default(); self.state = Default::default();
if enabled { if enabled {
self.switch_mode(Mode::Normal, cx); self.switch_mode(Mode::Normal, false, cx);
} }
self.sync_vim_settings(cx); self.sync_vim_settings(cx);
} }

View file

@ -119,7 +119,7 @@ impl<'a> VimTestContext<'a> {
pub fn set_state(&mut self, text: &str, mode: Mode) { pub fn set_state(&mut self, text: &str, mode: Mode) {
self.cx.update(|cx| { self.cx.update(|cx| {
Vim::update(cx, |vim, cx| { Vim::update(cx, |vim, cx| {
vim.switch_mode(mode, cx); vim.switch_mode(mode, false, cx);
}) })
}); });
self.cx.set_state(text); self.cx.set_state(text);

View file

@ -89,7 +89,7 @@ pub fn change(_: &mut Workspace, _: &VisualChange, cx: &mut ViewContext<Workspac
s.select_anchors(new_selections); s.select_anchors(new_selections);
}); });
}); });
vim.switch_mode(Mode::Insert, cx); vim.switch_mode(Mode::Insert, false, cx);
}); });
} }
@ -130,7 +130,7 @@ pub fn delete(_: &mut Workspace, _: &VisualDelete, cx: &mut ViewContext<Workspac
}); });
}); });
}); });
vim.switch_mode(Mode::Normal, cx); vim.switch_mode(Mode::Normal, false, cx);
}); });
} }
@ -158,7 +158,7 @@ pub fn yank(_: &mut Workspace, _: &VisualYank, cx: &mut ViewContext<Workspace>)
}); });
}); });
}); });
vim.switch_mode(Mode::Normal, cx); vim.switch_mode(Mode::Normal, false, cx);
}); });
} }
@ -266,7 +266,7 @@ pub fn paste(_: &mut Workspace, _: &VisualPaste, cx: &mut ViewContext<Workspace>
} }
}); });
}); });
vim.switch_mode(Mode::Normal, cx); vim.switch_mode(Mode::Normal, false, cx);
}); });
} }