Get the project running!
This commit is contained in:
parent
e7badb38e9
commit
ef7e2c5d86
12 changed files with 353 additions and 183 deletions
|
@ -3,7 +3,7 @@ use std::cmp;
|
|||
use editor::{
|
||||
char_kind,
|
||||
display_map::{DisplaySnapshot, FoldPoint, ToDisplayPoint},
|
||||
movement::{self, find_boundary, find_preceding_boundary, FindRange},
|
||||
movement::{self, find_boundary, find_preceding_boundary, FindRange, TextLayoutDetails},
|
||||
Bias, CharKind, DisplayPoint, ToOffset,
|
||||
};
|
||||
use gpui::{actions, impl_actions, AppContext, WindowContext};
|
||||
|
@ -361,6 +361,7 @@ impl Motion {
|
|||
point: DisplayPoint,
|
||||
goal: SelectionGoal,
|
||||
maybe_times: Option<usize>,
|
||||
text_layout_details: &TextLayoutDetails,
|
||||
) -> Option<(DisplayPoint, SelectionGoal)> {
|
||||
let times = maybe_times.unwrap_or(1);
|
||||
use Motion::*;
|
||||
|
@ -373,13 +374,13 @@ impl Motion {
|
|||
} => down(map, point, goal, times),
|
||||
Down {
|
||||
display_lines: true,
|
||||
} => down_display(map, point, goal, times),
|
||||
} => down_display(map, point, goal, times, &text_layout_details),
|
||||
Up {
|
||||
display_lines: false,
|
||||
} => up(map, point, goal, times),
|
||||
Up {
|
||||
display_lines: true,
|
||||
} => up_display(map, point, goal, times),
|
||||
} => up_display(map, point, goal, times, &text_layout_details),
|
||||
Right => (right(map, point, times), SelectionGoal::None),
|
||||
NextWordStart { ignore_punctuation } => (
|
||||
next_word_start(map, point, *ignore_punctuation, times),
|
||||
|
@ -442,10 +443,15 @@ impl Motion {
|
|||
selection: &mut Selection<DisplayPoint>,
|
||||
times: Option<usize>,
|
||||
expand_to_surrounding_newline: bool,
|
||||
text_layout_details: &TextLayoutDetails,
|
||||
) -> bool {
|
||||
if let Some((new_head, goal)) =
|
||||
self.move_point(map, selection.head(), selection.goal, times)
|
||||
{
|
||||
if let Some((new_head, goal)) = self.move_point(
|
||||
map,
|
||||
selection.head(),
|
||||
selection.goal,
|
||||
times,
|
||||
&text_layout_details,
|
||||
) {
|
||||
selection.set_head(new_head, goal);
|
||||
|
||||
if self.linewise() {
|
||||
|
@ -566,9 +572,10 @@ fn down_display(
|
|||
mut point: DisplayPoint,
|
||||
mut goal: SelectionGoal,
|
||||
times: usize,
|
||||
text_layout_details: &TextLayoutDetails,
|
||||
) -> (DisplayPoint, SelectionGoal) {
|
||||
for _ in 0..times {
|
||||
(point, goal) = movement::down(map, point, goal, true);
|
||||
(point, goal) = movement::down(map, point, goal, true, text_layout_details);
|
||||
}
|
||||
|
||||
(point, goal)
|
||||
|
@ -606,9 +613,10 @@ fn up_display(
|
|||
mut point: DisplayPoint,
|
||||
mut goal: SelectionGoal,
|
||||
times: usize,
|
||||
text_layout_details: &TextLayoutDetails,
|
||||
) -> (DisplayPoint, SelectionGoal) {
|
||||
for _ in 0..times {
|
||||
(point, goal) = movement::up(map, point, goal, true);
|
||||
(point, goal) = movement::up(map, point, goal, true, &text_layout_details);
|
||||
}
|
||||
|
||||
(point, goal)
|
||||
|
@ -707,7 +715,7 @@ fn previous_word_start(
|
|||
point
|
||||
}
|
||||
|
||||
fn first_non_whitespace(
|
||||
pub(crate) fn first_non_whitespace(
|
||||
map: &DisplaySnapshot,
|
||||
display_lines: bool,
|
||||
from: DisplayPoint,
|
||||
|
@ -890,7 +898,11 @@ fn next_line_start(map: &DisplaySnapshot, point: DisplayPoint, times: usize) ->
|
|||
first_non_whitespace(map, false, correct_line)
|
||||
}
|
||||
|
||||
fn next_line_end(map: &DisplaySnapshot, mut point: DisplayPoint, times: usize) -> DisplayPoint {
|
||||
pub(crate) fn next_line_end(
|
||||
map: &DisplaySnapshot,
|
||||
mut point: DisplayPoint,
|
||||
times: usize,
|
||||
) -> DisplayPoint {
|
||||
if times > 1 {
|
||||
point = down(map, point, SelectionGoal::None, times - 1).0;
|
||||
}
|
||||
|
|
|
@ -12,13 +12,13 @@ mod yank;
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
motion::{self, Motion},
|
||||
motion::{self, first_non_whitespace, next_line_end, right, Motion},
|
||||
object::Object,
|
||||
state::{Mode, Operator},
|
||||
Vim,
|
||||
};
|
||||
use collections::HashSet;
|
||||
use editor::scroll::autoscroll::Autoscroll;
|
||||
use editor::{movement::TextLayoutDetails, scroll::autoscroll::Autoscroll};
|
||||
use editor::{Bias, DisplayPoint};
|
||||
use gpui::{actions, AppContext, ViewContext, WindowContext};
|
||||
use language::SelectionGoal;
|
||||
|
@ -177,10 +177,11 @@ pub(crate) fn move_cursor(
|
|||
cx: &mut WindowContext,
|
||||
) {
|
||||
vim.update_active_editor(cx, |editor, cx| {
|
||||
let text_layout_details = TextLayoutDetails::new(editor, cx);
|
||||
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.move_cursors_with(|map, cursor, goal| {
|
||||
motion
|
||||
.move_point(map, cursor, goal, times)
|
||||
.move_point(map, cursor, goal, times, &text_layout_details)
|
||||
.unwrap_or((cursor, goal))
|
||||
})
|
||||
})
|
||||
|
@ -193,8 +194,8 @@ fn insert_after(_: &mut Workspace, _: &InsertAfter, cx: &mut ViewContext<Workspa
|
|||
vim.switch_mode(Mode::Insert, false, cx);
|
||||
vim.update_active_editor(cx, |editor, cx| {
|
||||
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.maybe_move_cursors_with(|map, cursor, goal| {
|
||||
Motion::Right.move_point(map, cursor, goal, None)
|
||||
s.move_cursors_with(|map, cursor, goal| {
|
||||
(right(map, cursor, 1), SelectionGoal::None)
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -218,11 +219,11 @@ fn insert_first_non_whitespace(
|
|||
vim.switch_mode(Mode::Insert, false, cx);
|
||||
vim.update_active_editor(cx, |editor, cx| {
|
||||
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.maybe_move_cursors_with(|map, cursor, goal| {
|
||||
Motion::FirstNonWhitespace {
|
||||
display_lines: false,
|
||||
}
|
||||
.move_point(map, cursor, goal, None)
|
||||
s.move_cursors_with(|map, cursor, goal| {
|
||||
(
|
||||
first_non_whitespace(map, false, cursor),
|
||||
SelectionGoal::None,
|
||||
)
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -235,8 +236,8 @@ fn insert_end_of_line(_: &mut Workspace, _: &InsertEndOfLine, cx: &mut ViewConte
|
|||
vim.switch_mode(Mode::Insert, false, cx);
|
||||
vim.update_active_editor(cx, |editor, cx| {
|
||||
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.maybe_move_cursors_with(|map, cursor, goal| {
|
||||
Motion::CurrentLine.move_point(map, cursor, goal, None)
|
||||
s.move_cursors_with(|map, cursor, goal| {
|
||||
(next_line_end(map, cursor, 1), SelectionGoal::None)
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -281,6 +282,7 @@ fn insert_line_below(_: &mut Workspace, _: &InsertLineBelow, cx: &mut ViewContex
|
|||
vim.start_recording(cx);
|
||||
vim.switch_mode(Mode::Insert, false, cx);
|
||||
vim.update_active_editor(cx, |editor, cx| {
|
||||
let text_layout_details = TextLayoutDetails::new(editor, cx);
|
||||
editor.transact(cx, |editor, cx| {
|
||||
let (map, old_selections) = editor.selections.all_display(cx);
|
||||
|
||||
|
@ -299,7 +301,13 @@ fn insert_line_below(_: &mut Workspace, _: &InsertLineBelow, cx: &mut ViewContex
|
|||
});
|
||||
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.maybe_move_cursors_with(|map, cursor, goal| {
|
||||
Motion::CurrentLine.move_point(map, cursor, goal, None)
|
||||
Motion::CurrentLine.move_point(
|
||||
map,
|
||||
cursor,
|
||||
goal,
|
||||
None,
|
||||
&text_layout_details,
|
||||
)
|
||||
});
|
||||
});
|
||||
editor.edit_with_autoindent(edits, cx);
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::{motion::Motion, object::Object, state::Mode, utils::copy_selections_
|
|||
use editor::{
|
||||
char_kind,
|
||||
display_map::DisplaySnapshot,
|
||||
movement::{self, FindRange},
|
||||
movement::{self, FindRange, TextLayoutDetails},
|
||||
scroll::autoscroll::Autoscroll,
|
||||
CharKind, DisplayPoint,
|
||||
};
|
||||
|
@ -20,6 +20,7 @@ pub fn change_motion(vim: &mut Vim, motion: Motion, times: Option<usize>, cx: &m
|
|||
| Motion::StartOfLine { .. }
|
||||
);
|
||||
vim.update_active_editor(cx, |editor, cx| {
|
||||
let text_layout_details = TextLayoutDetails::new(editor, cx);
|
||||
editor.transact(cx, |editor, cx| {
|
||||
// We are swapping to insert mode anyway. Just set the line end clipping behavior now
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
|
@ -27,9 +28,15 @@ pub fn change_motion(vim: &mut Vim, motion: Motion, times: Option<usize>, cx: &m
|
|||
s.move_with(|map, selection| {
|
||||
motion_succeeded |= if let Motion::NextWordStart { ignore_punctuation } = motion
|
||||
{
|
||||
expand_changed_word_selection(map, selection, times, ignore_punctuation)
|
||||
expand_changed_word_selection(
|
||||
map,
|
||||
selection,
|
||||
times,
|
||||
ignore_punctuation,
|
||||
&text_layout_details,
|
||||
)
|
||||
} else {
|
||||
motion.expand_selection(map, selection, times, false)
|
||||
motion.expand_selection(map, selection, times, false, &text_layout_details)
|
||||
};
|
||||
});
|
||||
});
|
||||
|
@ -81,6 +88,7 @@ fn expand_changed_word_selection(
|
|||
selection: &mut Selection<DisplayPoint>,
|
||||
times: Option<usize>,
|
||||
ignore_punctuation: bool,
|
||||
text_layout_details: &TextLayoutDetails,
|
||||
) -> bool {
|
||||
if times.is_none() || times.unwrap() == 1 {
|
||||
let scope = map
|
||||
|
@ -103,11 +111,22 @@ fn expand_changed_word_selection(
|
|||
});
|
||||
true
|
||||
} else {
|
||||
Motion::NextWordStart { ignore_punctuation }
|
||||
.expand_selection(map, selection, None, false)
|
||||
Motion::NextWordStart { ignore_punctuation }.expand_selection(
|
||||
map,
|
||||
selection,
|
||||
None,
|
||||
false,
|
||||
&text_layout_details,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Motion::NextWordStart { ignore_punctuation }.expand_selection(map, selection, times, false)
|
||||
Motion::NextWordStart { ignore_punctuation }.expand_selection(
|
||||
map,
|
||||
selection,
|
||||
times,
|
||||
false,
|
||||
&text_layout_details,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
use crate::{motion::Motion, object::Object, utils::copy_selections_content, Vim};
|
||||
use collections::{HashMap, HashSet};
|
||||
use editor::{display_map::ToDisplayPoint, scroll::autoscroll::Autoscroll, Bias};
|
||||
use editor::{
|
||||
display_map::ToDisplayPoint, movement::TextLayoutDetails, scroll::autoscroll::Autoscroll, Bias,
|
||||
};
|
||||
use gpui::WindowContext;
|
||||
use language::Point;
|
||||
|
||||
pub fn delete_motion(vim: &mut Vim, motion: Motion, times: Option<usize>, cx: &mut WindowContext) {
|
||||
vim.stop_recording();
|
||||
vim.update_active_editor(cx, |editor, cx| {
|
||||
let text_layout_details = TextLayoutDetails::new(editor, cx);
|
||||
editor.transact(cx, |editor, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let mut original_columns: HashMap<_, _> = Default::default();
|
||||
|
@ -14,7 +17,7 @@ pub fn delete_motion(vim: &mut Vim, motion: Motion, times: Option<usize>, cx: &m
|
|||
s.move_with(|map, selection| {
|
||||
let original_head = selection.head();
|
||||
original_columns.insert(selection.id, original_head.column());
|
||||
motion.expand_selection(map, selection, times, true);
|
||||
motion.expand_selection(map, selection, times, true, &text_layout_details);
|
||||
|
||||
// Motion::NextWordStart on an empty line should delete it.
|
||||
if let Motion::NextWordStart {
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use std::{borrow::Cow, cmp};
|
||||
|
||||
use editor::{
|
||||
display_map::ToDisplayPoint, movement, scroll::autoscroll::Autoscroll, ClipboardSelection,
|
||||
DisplayPoint,
|
||||
display_map::ToDisplayPoint,
|
||||
movement::{self, TextLayoutDetails},
|
||||
scroll::autoscroll::Autoscroll,
|
||||
ClipboardSelection, DisplayPoint,
|
||||
};
|
||||
use gpui::{impl_actions, AppContext, ViewContext};
|
||||
use language::{Bias, SelectionGoal};
|
||||
|
@ -30,6 +32,7 @@ fn paste(_: &mut Workspace, action: &Paste, cx: &mut ViewContext<Workspace>) {
|
|||
Vim::update(cx, |vim, cx| {
|
||||
vim.record_current_action(cx);
|
||||
vim.update_active_editor(cx, |editor, cx| {
|
||||
let text_layout_details = TextLayoutDetails::new(editor, cx);
|
||||
editor.transact(cx, |editor, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
|
||||
|
@ -168,8 +171,14 @@ fn paste(_: &mut Workspace, action: &Paste, cx: &mut ViewContext<Workspace>) {
|
|||
let mut cursor = anchor.to_display_point(map);
|
||||
if *line_mode {
|
||||
if !before {
|
||||
cursor =
|
||||
movement::down(map, cursor, SelectionGoal::None, false).0;
|
||||
cursor = movement::down(
|
||||
map,
|
||||
cursor,
|
||||
SelectionGoal::None,
|
||||
false,
|
||||
&text_layout_details,
|
||||
)
|
||||
.0;
|
||||
}
|
||||
cursor = movement::indented_line_beginning(map, cursor, true);
|
||||
} else if !is_multiline {
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
use editor::movement;
|
||||
use editor::movement::{self, TextLayoutDetails};
|
||||
use gpui::{actions, AppContext, WindowContext};
|
||||
use language::Point;
|
||||
use workspace::Workspace;
|
||||
|
||||
use crate::{motion::Motion, utils::copy_selections_content, Mode, Vim};
|
||||
use crate::{
|
||||
motion::{right, Motion},
|
||||
utils::copy_selections_content,
|
||||
Mode, Vim,
|
||||
};
|
||||
|
||||
actions!(vim, [Substitute, SubstituteLine]);
|
||||
|
||||
|
@ -32,10 +36,17 @@ pub fn substitute(vim: &mut Vim, count: Option<usize>, line_mode: bool, cx: &mut
|
|||
vim.update_active_editor(cx, |editor, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
editor.transact(cx, |editor, cx| {
|
||||
let text_layout_details = TextLayoutDetails::new(editor, cx);
|
||||
editor.change_selections(None, cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
if selection.start == selection.end {
|
||||
Motion::Right.expand_selection(map, selection, count, true);
|
||||
Motion::Right.expand_selection(
|
||||
map,
|
||||
selection,
|
||||
count,
|
||||
true,
|
||||
&text_layout_details,
|
||||
);
|
||||
}
|
||||
if line_mode {
|
||||
// in Visual mode when the selection contains the newline at the end
|
||||
|
@ -43,7 +54,13 @@ pub fn substitute(vim: &mut Vim, count: Option<usize>, line_mode: bool, cx: &mut
|
|||
if !selection.is_empty() && selection.end.column() == 0 {
|
||||
selection.end = movement::left(map, selection.end);
|
||||
}
|
||||
Motion::CurrentLine.expand_selection(map, selection, None, false);
|
||||
Motion::CurrentLine.expand_selection(
|
||||
map,
|
||||
selection,
|
||||
None,
|
||||
false,
|
||||
&text_layout_details,
|
||||
);
|
||||
if let Some((point, _)) = (Motion::FirstNonWhitespace {
|
||||
display_lines: false,
|
||||
})
|
||||
|
@ -52,6 +69,7 @@ pub fn substitute(vim: &mut Vim, count: Option<usize>, line_mode: bool, cx: &mut
|
|||
selection.start,
|
||||
selection.goal,
|
||||
None,
|
||||
&text_layout_details,
|
||||
) {
|
||||
selection.start = point;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use crate::{motion::Motion, object::Object, utils::copy_selections_content, Vim};
|
||||
use collections::HashMap;
|
||||
use editor::movement::TextLayoutDetails;
|
||||
use gpui::WindowContext;
|
||||
|
||||
pub fn yank_motion(vim: &mut Vim, motion: Motion, times: Option<usize>, cx: &mut WindowContext) {
|
||||
vim.update_active_editor(cx, |editor, cx| {
|
||||
let text_layout_details = TextLayoutDetails::new(editor, cx);
|
||||
editor.transact(cx, |editor, cx| {
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
let mut original_positions: HashMap<_, _> = Default::default();
|
||||
|
@ -11,7 +13,7 @@ pub fn yank_motion(vim: &mut Vim, motion: Motion, times: Option<usize>, cx: &mut
|
|||
s.move_with(|map, selection| {
|
||||
let original_position = (selection.head(), selection.goal);
|
||||
original_positions.insert(selection.id, original_position);
|
||||
motion.expand_selection(map, selection, times, true);
|
||||
motion.expand_selection(map, selection, times, true, &text_layout_details);
|
||||
});
|
||||
});
|
||||
copy_selections_content(editor, motion.linewise(), cx);
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::{cmp, sync::Arc};
|
|||
use collections::HashMap;
|
||||
use editor::{
|
||||
display_map::{DisplaySnapshot, ToDisplayPoint},
|
||||
movement,
|
||||
movement::{self, TextLayoutDetails},
|
||||
scroll::autoscroll::Autoscroll,
|
||||
Bias, DisplayPoint, Editor,
|
||||
};
|
||||
|
@ -57,6 +57,7 @@ pub fn init(cx: &mut AppContext) {
|
|||
pub fn visual_motion(motion: Motion, times: Option<usize>, cx: &mut WindowContext) {
|
||||
Vim::update(cx, |vim, cx| {
|
||||
vim.update_active_editor(cx, |editor, cx| {
|
||||
let text_layout_details = TextLayoutDetails::new(editor, cx);
|
||||
if vim.state().mode == Mode::VisualBlock
|
||||
&& !matches!(
|
||||
motion,
|
||||
|
@ -67,7 +68,7 @@ pub fn visual_motion(motion: Motion, times: Option<usize>, cx: &mut WindowContex
|
|||
{
|
||||
let is_up_or_down = matches!(motion, Motion::Up { .. } | Motion::Down { .. });
|
||||
visual_block_motion(is_up_or_down, editor, cx, |map, point, goal| {
|
||||
motion.move_point(map, point, goal, times)
|
||||
motion.move_point(map, point, goal, times, &text_layout_details)
|
||||
})
|
||||
} else {
|
||||
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
|
@ -89,9 +90,13 @@ pub fn visual_motion(motion: Motion, times: Option<usize>, cx: &mut WindowContex
|
|||
current_head = movement::left(map, selection.end)
|
||||
}
|
||||
|
||||
let Some((new_head, goal)) =
|
||||
motion.move_point(map, current_head, selection.goal, times)
|
||||
else {
|
||||
let Some((new_head, goal)) = motion.move_point(
|
||||
map,
|
||||
current_head,
|
||||
selection.goal,
|
||||
times,
|
||||
&text_layout_details,
|
||||
) else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue