Merge pull request #684 from zed-industries/subword
Add bindings for subword movement and deletion
This commit is contained in:
commit
fe1f857e84
1 changed files with 128 additions and 26 deletions
|
@ -71,8 +71,10 @@ action!(Newline);
|
||||||
action!(Tab);
|
action!(Tab);
|
||||||
action!(Outdent);
|
action!(Outdent);
|
||||||
action!(DeleteLine);
|
action!(DeleteLine);
|
||||||
action!(DeleteToPreviousWordBoundary);
|
action!(DeleteToPreviousWordStart);
|
||||||
action!(DeleteToNextWordBoundary);
|
action!(DeleteToPreviousSubwordStart);
|
||||||
|
action!(DeleteToNextWordEnd);
|
||||||
|
action!(DeleteToNextSubwordEnd);
|
||||||
action!(DeleteToBeginningOfLine);
|
action!(DeleteToBeginningOfLine);
|
||||||
action!(DeleteToEndOfLine);
|
action!(DeleteToEndOfLine);
|
||||||
action!(CutToEndOfLine);
|
action!(CutToEndOfLine);
|
||||||
|
@ -89,7 +91,9 @@ action!(MoveDown);
|
||||||
action!(MoveLeft);
|
action!(MoveLeft);
|
||||||
action!(MoveRight);
|
action!(MoveRight);
|
||||||
action!(MoveToPreviousWordStart);
|
action!(MoveToPreviousWordStart);
|
||||||
|
action!(MoveToPreviousSubwordStart);
|
||||||
action!(MoveToNextWordEnd);
|
action!(MoveToNextWordEnd);
|
||||||
|
action!(MoveToNextSubwordEnd);
|
||||||
action!(MoveToBeginningOfLine);
|
action!(MoveToBeginningOfLine);
|
||||||
action!(MoveToEndOfLine);
|
action!(MoveToEndOfLine);
|
||||||
action!(MoveToBeginning);
|
action!(MoveToBeginning);
|
||||||
|
@ -98,8 +102,10 @@ action!(SelectUp);
|
||||||
action!(SelectDown);
|
action!(SelectDown);
|
||||||
action!(SelectLeft);
|
action!(SelectLeft);
|
||||||
action!(SelectRight);
|
action!(SelectRight);
|
||||||
action!(SelectToPreviousWordBoundary);
|
action!(SelectToPreviousWordStart);
|
||||||
action!(SelectToNextWordBoundary);
|
action!(SelectToPreviousSubwordStart);
|
||||||
|
action!(SelectToNextWordEnd);
|
||||||
|
action!(SelectToNextSubwordEnd);
|
||||||
action!(SelectToBeginningOfLine, bool);
|
action!(SelectToBeginningOfLine, bool);
|
||||||
action!(SelectToEndOfLine, bool);
|
action!(SelectToEndOfLine, bool);
|
||||||
action!(SelectToBeginning);
|
action!(SelectToBeginning);
|
||||||
|
@ -173,14 +179,18 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||||
),
|
),
|
||||||
Binding::new("shift-tab", Outdent, Some("Editor")),
|
Binding::new("shift-tab", Outdent, Some("Editor")),
|
||||||
Binding::new("ctrl-shift-K", DeleteLine, Some("Editor")),
|
Binding::new("ctrl-shift-K", DeleteLine, Some("Editor")),
|
||||||
|
Binding::new("alt-backspace", DeleteToPreviousWordStart, Some("Editor")),
|
||||||
|
Binding::new("alt-h", DeleteToPreviousWordStart, Some("Editor")),
|
||||||
Binding::new(
|
Binding::new(
|
||||||
"alt-backspace",
|
"ctrl-alt-backspace",
|
||||||
DeleteToPreviousWordBoundary,
|
DeleteToPreviousSubwordStart,
|
||||||
Some("Editor"),
|
Some("Editor"),
|
||||||
),
|
),
|
||||||
Binding::new("alt-h", DeleteToPreviousWordBoundary, Some("Editor")),
|
Binding::new("ctrl-alt-h", DeleteToPreviousSubwordStart, Some("Editor")),
|
||||||
Binding::new("alt-delete", DeleteToNextWordBoundary, Some("Editor")),
|
Binding::new("alt-delete", DeleteToNextWordEnd, Some("Editor")),
|
||||||
Binding::new("alt-d", DeleteToNextWordBoundary, Some("Editor")),
|
Binding::new("alt-d", DeleteToNextWordEnd, Some("Editor")),
|
||||||
|
Binding::new("ctrl-alt-delete", DeleteToNextSubwordEnd, Some("Editor")),
|
||||||
|
Binding::new("ctrl-alt-d", DeleteToNextSubwordEnd, Some("Editor")),
|
||||||
Binding::new("cmd-backspace", DeleteToBeginningOfLine, Some("Editor")),
|
Binding::new("cmd-backspace", DeleteToBeginningOfLine, Some("Editor")),
|
||||||
Binding::new("cmd-delete", DeleteToEndOfLine, Some("Editor")),
|
Binding::new("cmd-delete", DeleteToEndOfLine, Some("Editor")),
|
||||||
Binding::new("ctrl-k", CutToEndOfLine, Some("Editor")),
|
Binding::new("ctrl-k", CutToEndOfLine, Some("Editor")),
|
||||||
|
@ -202,8 +212,12 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||||
Binding::new("ctrl-f", MoveRight, Some("Editor")),
|
Binding::new("ctrl-f", MoveRight, Some("Editor")),
|
||||||
Binding::new("alt-left", MoveToPreviousWordStart, Some("Editor")),
|
Binding::new("alt-left", MoveToPreviousWordStart, Some("Editor")),
|
||||||
Binding::new("alt-b", MoveToPreviousWordStart, Some("Editor")),
|
Binding::new("alt-b", MoveToPreviousWordStart, Some("Editor")),
|
||||||
|
Binding::new("ctrl-alt-left", MoveToPreviousSubwordStart, Some("Editor")),
|
||||||
|
Binding::new("ctrl-alt-b", MoveToPreviousSubwordStart, Some("Editor")),
|
||||||
Binding::new("alt-right", MoveToNextWordEnd, Some("Editor")),
|
Binding::new("alt-right", MoveToNextWordEnd, Some("Editor")),
|
||||||
Binding::new("alt-f", MoveToNextWordEnd, Some("Editor")),
|
Binding::new("alt-f", MoveToNextWordEnd, Some("Editor")),
|
||||||
|
Binding::new("ctrl-alt-right", MoveToNextSubwordEnd, Some("Editor")),
|
||||||
|
Binding::new("ctrl-alt-f", MoveToNextSubwordEnd, Some("Editor")),
|
||||||
Binding::new("cmd-left", MoveToBeginningOfLine, Some("Editor")),
|
Binding::new("cmd-left", MoveToBeginningOfLine, Some("Editor")),
|
||||||
Binding::new("ctrl-a", MoveToBeginningOfLine, Some("Editor")),
|
Binding::new("ctrl-a", MoveToBeginningOfLine, Some("Editor")),
|
||||||
Binding::new("cmd-right", MoveToEndOfLine, Some("Editor")),
|
Binding::new("cmd-right", MoveToEndOfLine, Some("Editor")),
|
||||||
|
@ -218,19 +232,31 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||||
Binding::new("ctrl-shift-B", SelectLeft, Some("Editor")),
|
Binding::new("ctrl-shift-B", SelectLeft, Some("Editor")),
|
||||||
Binding::new("shift-right", SelectRight, Some("Editor")),
|
Binding::new("shift-right", SelectRight, Some("Editor")),
|
||||||
Binding::new("ctrl-shift-F", SelectRight, Some("Editor")),
|
Binding::new("ctrl-shift-F", SelectRight, Some("Editor")),
|
||||||
|
Binding::new("alt-shift-left", SelectToPreviousWordStart, Some("Editor")),
|
||||||
|
Binding::new("alt-shift-B", SelectToPreviousWordStart, Some("Editor")),
|
||||||
Binding::new(
|
Binding::new(
|
||||||
"alt-shift-left",
|
"ctrl-alt-shift-left",
|
||||||
SelectToPreviousWordBoundary,
|
SelectToPreviousSubwordStart,
|
||||||
Some("Editor"),
|
Some("Editor"),
|
||||||
),
|
),
|
||||||
Binding::new("alt-shift-B", SelectToPreviousWordBoundary, Some("Editor")),
|
Binding::new(
|
||||||
Binding::new("alt-shift-right", SelectToNextWordBoundary, Some("Editor")),
|
"ctrl-alt-shift-B",
|
||||||
Binding::new("alt-shift-F", SelectToNextWordBoundary, Some("Editor")),
|
SelectToPreviousSubwordStart,
|
||||||
|
Some("Editor"),
|
||||||
|
),
|
||||||
|
Binding::new("alt-shift-right", SelectToNextWordEnd, Some("Editor")),
|
||||||
|
Binding::new("alt-shift-F", SelectToNextWordEnd, Some("Editor")),
|
||||||
Binding::new(
|
Binding::new(
|
||||||
"cmd-shift-left",
|
"cmd-shift-left",
|
||||||
SelectToBeginningOfLine(true),
|
SelectToBeginningOfLine(true),
|
||||||
Some("Editor"),
|
Some("Editor"),
|
||||||
),
|
),
|
||||||
|
Binding::new(
|
||||||
|
"ctrl-alt-shift-right",
|
||||||
|
SelectToNextSubwordEnd,
|
||||||
|
Some("Editor"),
|
||||||
|
),
|
||||||
|
Binding::new("ctrl-alt-shift-F", SelectToNextSubwordEnd, Some("Editor")),
|
||||||
Binding::new(
|
Binding::new(
|
||||||
"ctrl-shift-A",
|
"ctrl-shift-A",
|
||||||
SelectToBeginningOfLine(true),
|
SelectToBeginningOfLine(true),
|
||||||
|
@ -282,7 +308,9 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||||
cx.add_action(Editor::outdent);
|
cx.add_action(Editor::outdent);
|
||||||
cx.add_action(Editor::delete_line);
|
cx.add_action(Editor::delete_line);
|
||||||
cx.add_action(Editor::delete_to_previous_word_start);
|
cx.add_action(Editor::delete_to_previous_word_start);
|
||||||
|
cx.add_action(Editor::delete_to_previous_subword_start);
|
||||||
cx.add_action(Editor::delete_to_next_word_end);
|
cx.add_action(Editor::delete_to_next_word_end);
|
||||||
|
cx.add_action(Editor::delete_to_next_subword_end);
|
||||||
cx.add_action(Editor::delete_to_beginning_of_line);
|
cx.add_action(Editor::delete_to_beginning_of_line);
|
||||||
cx.add_action(Editor::delete_to_end_of_line);
|
cx.add_action(Editor::delete_to_end_of_line);
|
||||||
cx.add_action(Editor::cut_to_end_of_line);
|
cx.add_action(Editor::cut_to_end_of_line);
|
||||||
|
@ -299,7 +327,9 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||||
cx.add_action(Editor::move_left);
|
cx.add_action(Editor::move_left);
|
||||||
cx.add_action(Editor::move_right);
|
cx.add_action(Editor::move_right);
|
||||||
cx.add_action(Editor::move_to_previous_word_start);
|
cx.add_action(Editor::move_to_previous_word_start);
|
||||||
|
cx.add_action(Editor::move_to_previous_subword_start);
|
||||||
cx.add_action(Editor::move_to_next_word_end);
|
cx.add_action(Editor::move_to_next_word_end);
|
||||||
|
cx.add_action(Editor::move_to_next_subword_end);
|
||||||
cx.add_action(Editor::move_to_beginning_of_line);
|
cx.add_action(Editor::move_to_beginning_of_line);
|
||||||
cx.add_action(Editor::move_to_end_of_line);
|
cx.add_action(Editor::move_to_end_of_line);
|
||||||
cx.add_action(Editor::move_to_beginning);
|
cx.add_action(Editor::move_to_beginning);
|
||||||
|
@ -309,7 +339,9 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||||
cx.add_action(Editor::select_left);
|
cx.add_action(Editor::select_left);
|
||||||
cx.add_action(Editor::select_right);
|
cx.add_action(Editor::select_right);
|
||||||
cx.add_action(Editor::select_to_previous_word_start);
|
cx.add_action(Editor::select_to_previous_word_start);
|
||||||
|
cx.add_action(Editor::select_to_previous_subword_start);
|
||||||
cx.add_action(Editor::select_to_next_word_end);
|
cx.add_action(Editor::select_to_next_word_end);
|
||||||
|
cx.add_action(Editor::select_to_next_subword_end);
|
||||||
cx.add_action(Editor::select_to_beginning_of_line);
|
cx.add_action(Editor::select_to_beginning_of_line);
|
||||||
cx.add_action(Editor::select_to_end_of_line);
|
cx.add_action(Editor::select_to_end_of_line);
|
||||||
cx.add_action(Editor::select_to_beginning);
|
cx.add_action(Editor::select_to_beginning);
|
||||||
|
@ -3532,9 +3564,22 @@ impl Editor {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn move_to_previous_subword_start(
|
||||||
|
&mut self,
|
||||||
|
_: &MoveToPreviousSubwordStart,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) {
|
||||||
|
self.move_cursors(cx, |map, head, _| {
|
||||||
|
(
|
||||||
|
movement::previous_subword_start(map, head),
|
||||||
|
SelectionGoal::None,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn select_to_previous_word_start(
|
pub fn select_to_previous_word_start(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &SelectToPreviousWordBoundary,
|
_: &SelectToPreviousWordStart,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
self.move_selection_heads(cx, |map, head, _| {
|
self.move_selection_heads(cx, |map, head, _| {
|
||||||
|
@ -3545,9 +3590,22 @@ impl Editor {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn select_to_previous_subword_start(
|
||||||
|
&mut self,
|
||||||
|
_: &SelectToPreviousSubwordStart,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) {
|
||||||
|
self.move_selection_heads(cx, |map, head, _| {
|
||||||
|
(
|
||||||
|
movement::previous_subword_start(map, head),
|
||||||
|
SelectionGoal::None,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn delete_to_previous_word_start(
|
pub fn delete_to_previous_word_start(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &DeleteToPreviousWordBoundary,
|
_: &DeleteToPreviousWordStart,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
self.transact(cx, |this, cx| {
|
self.transact(cx, |this, cx| {
|
||||||
|
@ -3561,31 +3619,75 @@ impl Editor {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn delete_to_previous_subword_start(
|
||||||
|
&mut self,
|
||||||
|
_: &DeleteToPreviousSubwordStart,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) {
|
||||||
|
self.transact(cx, |this, cx| {
|
||||||
|
this.move_selections(cx, |map, selection| {
|
||||||
|
if selection.is_empty() {
|
||||||
|
let cursor = movement::previous_subword_start(map, selection.head());
|
||||||
|
selection.set_head(cursor, SelectionGoal::None);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.insert("", cx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn move_to_next_word_end(&mut self, _: &MoveToNextWordEnd, cx: &mut ViewContext<Self>) {
|
pub fn move_to_next_word_end(&mut self, _: &MoveToNextWordEnd, cx: &mut ViewContext<Self>) {
|
||||||
self.move_cursors(cx, |map, head, _| {
|
self.move_cursors(cx, |map, head, _| {
|
||||||
(movement::next_word_end(map, head), SelectionGoal::None)
|
(movement::next_word_end(map, head), SelectionGoal::None)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_to_next_word_end(
|
pub fn move_to_next_subword_end(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &SelectToNextWordBoundary,
|
_: &MoveToNextSubwordEnd,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
|
self.move_cursors(cx, |map, head, _| {
|
||||||
|
(movement::next_subword_end(map, head), SelectionGoal::None)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_to_next_word_end(&mut self, _: &SelectToNextWordEnd, cx: &mut ViewContext<Self>) {
|
||||||
self.move_selection_heads(cx, |map, head, _| {
|
self.move_selection_heads(cx, |map, head, _| {
|
||||||
(movement::next_word_end(map, head), SelectionGoal::None)
|
(movement::next_word_end(map, head), SelectionGoal::None)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_to_next_word_end(
|
pub fn select_to_next_subword_end(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &DeleteToNextWordBoundary,
|
_: &SelectToNextSubwordEnd,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) {
|
||||||
|
self.move_selection_heads(cx, |map, head, _| {
|
||||||
|
(movement::next_subword_end(map, head), SelectionGoal::None)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete_to_next_word_end(&mut self, _: &DeleteToNextWordEnd, cx: &mut ViewContext<Self>) {
|
||||||
|
self.transact(cx, |this, cx| {
|
||||||
|
this.move_selections(cx, |map, selection| {
|
||||||
|
if selection.is_empty() {
|
||||||
|
let cursor = movement::next_word_end(map, selection.head());
|
||||||
|
selection.set_head(cursor, SelectionGoal::None);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.insert("", cx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete_to_next_subword_end(
|
||||||
|
&mut self,
|
||||||
|
_: &DeleteToNextSubwordEnd,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
self.transact(cx, |this, cx| {
|
self.transact(cx, |this, cx| {
|
||||||
this.move_selections(cx, |map, selection| {
|
this.move_selections(cx, |map, selection| {
|
||||||
if selection.is_empty() {
|
if selection.is_empty() {
|
||||||
let cursor = movement::next_word_end(map, selection.head());
|
let cursor = movement::next_subword_end(map, selection.head());
|
||||||
selection.set_head(cursor, SelectionGoal::None);
|
selection.set_head(cursor, SelectionGoal::None);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -7090,7 +7192,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
view.move_right(&MoveRight, cx);
|
view.move_right(&MoveRight, cx);
|
||||||
view.select_to_previous_word_start(&SelectToPreviousWordBoundary, cx);
|
view.select_to_previous_word_start(&SelectToPreviousWordStart, cx);
|
||||||
assert_selection_ranges(
|
assert_selection_ranges(
|
||||||
"use std::>s<tr::{foo, bar}\n\n {]b[az.qux()}",
|
"use std::>s<tr::{foo, bar}\n\n {]b[az.qux()}",
|
||||||
vec![('<', '>'), ('[', ']')],
|
vec![('<', '>'), ('[', ']')],
|
||||||
|
@ -7098,7 +7200,7 @@ mod tests {
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
|
||||||
view.select_to_previous_word_start(&SelectToPreviousWordBoundary, cx);
|
view.select_to_previous_word_start(&SelectToPreviousWordStart, cx);
|
||||||
assert_selection_ranges(
|
assert_selection_ranges(
|
||||||
"use std>::s<tr::{foo, bar}\n\n ]{b[az.qux()}",
|
"use std>::s<tr::{foo, bar}\n\n ]{b[az.qux()}",
|
||||||
vec![('<', '>'), ('[', ']')],
|
vec![('<', '>'), ('[', ']')],
|
||||||
|
@ -7106,7 +7208,7 @@ mod tests {
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
|
||||||
view.select_to_next_word_end(&SelectToNextWordBoundary, cx);
|
view.select_to_next_word_end(&SelectToNextWordEnd, cx);
|
||||||
assert_selection_ranges(
|
assert_selection_ranges(
|
||||||
"use std::>s<tr::{foo, bar}\n\n {]b[az.qux()}",
|
"use std::>s<tr::{foo, bar}\n\n {]b[az.qux()}",
|
||||||
vec![('<', '>'), ('[', ']')],
|
vec![('<', '>'), ('[', ']')],
|
||||||
|
@ -7185,7 +7287,7 @@ mod tests {
|
||||||
],
|
],
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
view.delete_to_previous_word_start(&DeleteToPreviousWordBoundary, cx);
|
view.delete_to_previous_word_start(&DeleteToPreviousWordStart, cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(buffer.read(cx).read(cx).text(), "e two te four");
|
assert_eq!(buffer.read(cx).read(cx).text(), "e two te four");
|
||||||
|
@ -7200,7 +7302,7 @@ mod tests {
|
||||||
],
|
],
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
view.delete_to_next_word_end(&DeleteToNextWordBoundary, cx);
|
view.delete_to_next_word_end(&DeleteToNextWordEnd, cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(buffer.read(cx).read(cx).text(), "e t te our");
|
assert_eq!(buffer.read(cx).read(cx).text(), "e t te our");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue