vim visual block (#2849)
Release notes: - vim: add Visual Block mode ([#984](https://github.com/zed-industries/community/issues/984)), ([#1415](https://github.com/zed-industries/community/issues/1415)). - vim: add support for `a<object>` and `i<object>` in visual modes - vim: fix scroll shortcuts (`ctrl-{f,b,d,u,e,y}`) in visual modes - allow `shift-enter` to type a newline.
This commit is contained in:
commit
d1aa82bb48
28 changed files with 946 additions and 321 deletions
|
@ -577,6 +577,7 @@ pub struct Editor {
|
|||
searchable: bool,
|
||||
cursor_shape: CursorShape,
|
||||
collapse_matches: bool,
|
||||
autoindent_mode: Option<AutoindentMode>,
|
||||
workspace: Option<(WeakViewHandle<Workspace>, i64)>,
|
||||
keymap_context_layers: BTreeMap<TypeId, KeymapContext>,
|
||||
input_enabled: bool,
|
||||
|
@ -1412,6 +1413,7 @@ impl Editor {
|
|||
searchable: true,
|
||||
override_text_style: None,
|
||||
cursor_shape: Default::default(),
|
||||
autoindent_mode: Some(AutoindentMode::EachLine),
|
||||
collapse_matches: false,
|
||||
workspace: None,
|
||||
keymap_context_layers: Default::default(),
|
||||
|
@ -1590,6 +1592,14 @@ impl Editor {
|
|||
self.input_enabled = input_enabled;
|
||||
}
|
||||
|
||||
pub fn set_autoindent(&mut self, autoindent: bool) {
|
||||
if autoindent {
|
||||
self.autoindent_mode = Some(AutoindentMode::EachLine);
|
||||
} else {
|
||||
self.autoindent_mode = None;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_read_only(&mut self, read_only: bool) {
|
||||
self.read_only = read_only;
|
||||
}
|
||||
|
@ -1722,7 +1732,7 @@ impl Editor {
|
|||
}
|
||||
|
||||
self.buffer.update(cx, |buffer, cx| {
|
||||
buffer.edit(edits, Some(AutoindentMode::EachLine), cx)
|
||||
buffer.edit(edits, self.autoindent_mode.clone(), cx)
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2197,7 +2207,7 @@ impl Editor {
|
|||
drop(snapshot);
|
||||
self.transact(cx, |this, cx| {
|
||||
this.buffer.update(cx, |buffer, cx| {
|
||||
buffer.edit(edits, Some(AutoindentMode::EachLine), cx);
|
||||
buffer.edit(edits, this.autoindent_mode.clone(), cx);
|
||||
});
|
||||
|
||||
let new_anchor_selections = new_selections.iter().map(|e| &e.0);
|
||||
|
@ -3037,7 +3047,7 @@ impl Editor {
|
|||
this.buffer.update(cx, |buffer, cx| {
|
||||
buffer.edit(
|
||||
ranges.iter().map(|range| (range.clone(), text)),
|
||||
Some(AutoindentMode::EachLine),
|
||||
this.autoindent_mode.clone(),
|
||||
cx,
|
||||
);
|
||||
});
|
||||
|
|
|
@ -61,10 +61,10 @@ pub fn up_by_rows(
|
|||
goal: SelectionGoal,
|
||||
preserve_column_at_start: bool,
|
||||
) -> (DisplayPoint, SelectionGoal) {
|
||||
let mut goal_column = if let SelectionGoal::Column(column) = goal {
|
||||
column
|
||||
} else {
|
||||
map.column_to_chars(start.row(), start.column())
|
||||
let mut goal_column = match goal {
|
||||
SelectionGoal::Column(column) => column,
|
||||
SelectionGoal::ColumnRange { end, .. } => end,
|
||||
_ => map.column_to_chars(start.row(), start.column()),
|
||||
};
|
||||
|
||||
let prev_row = start.row().saturating_sub(row_count);
|
||||
|
@ -95,10 +95,10 @@ pub fn down_by_rows(
|
|||
goal: SelectionGoal,
|
||||
preserve_column_at_end: bool,
|
||||
) -> (DisplayPoint, SelectionGoal) {
|
||||
let mut goal_column = if let SelectionGoal::Column(column) = goal {
|
||||
column
|
||||
} else {
|
||||
map.column_to_chars(start.row(), start.column())
|
||||
let mut goal_column = match goal {
|
||||
SelectionGoal::Column(column) => column,
|
||||
SelectionGoal::ColumnRange { end, .. } => end,
|
||||
_ => map.column_to_chars(start.row(), start.column()),
|
||||
};
|
||||
|
||||
let new_row = start.row() + row_count;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::{
|
||||
cell::Ref,
|
||||
cmp, iter, mem,
|
||||
ops::{Deref, Range, Sub},
|
||||
ops::{Deref, DerefMut, Range, Sub},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
|
@ -53,7 +53,7 @@ impl SelectionsCollection {
|
|||
}
|
||||
}
|
||||
|
||||
fn display_map(&self, cx: &mut AppContext) -> DisplaySnapshot {
|
||||
pub fn display_map(&self, cx: &mut AppContext) -> DisplaySnapshot {
|
||||
self.display_map.update(cx, |map, cx| map.snapshot(cx))
|
||||
}
|
||||
|
||||
|
@ -250,6 +250,10 @@ impl SelectionsCollection {
|
|||
resolve(self.oldest_anchor(), &self.buffer(cx))
|
||||
}
|
||||
|
||||
pub fn first_anchor(&self) -> Selection<Anchor> {
|
||||
self.disjoint[0].clone()
|
||||
}
|
||||
|
||||
pub fn first<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||
&self,
|
||||
cx: &AppContext,
|
||||
|
@ -352,7 +356,7 @@ pub struct MutableSelectionsCollection<'a> {
|
|||
}
|
||||
|
||||
impl<'a> MutableSelectionsCollection<'a> {
|
||||
fn display_map(&mut self) -> DisplaySnapshot {
|
||||
pub fn display_map(&mut self) -> DisplaySnapshot {
|
||||
self.collection.display_map(self.cx)
|
||||
}
|
||||
|
||||
|
@ -607,6 +611,10 @@ impl<'a> MutableSelectionsCollection<'a> {
|
|||
self.select_anchors(selections)
|
||||
}
|
||||
|
||||
pub fn new_selection_id(&mut self) -> usize {
|
||||
post_inc(&mut self.next_selection_id)
|
||||
}
|
||||
|
||||
pub fn select_display_ranges<T>(&mut self, ranges: T)
|
||||
where
|
||||
T: IntoIterator<Item = Range<DisplayPoint>>,
|
||||
|
@ -831,6 +839,12 @@ impl<'a> Deref for MutableSelectionsCollection<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> DerefMut for MutableSelectionsCollection<'a> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.collection
|
||||
}
|
||||
}
|
||||
|
||||
// Panics if passed selections are not in order
|
||||
pub fn resolve_multiple<'a, D, I>(
|
||||
selections: I,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue