Add emacs mark mode (#23297)
Updates #21927 Replaces https://github.com/zed-industries/zed/pull/22904 Closes #8580 Adds actions (default keybinds with emacs keymap): - editor::SetMark (`ctrl-space` and `ctrl-@`) - editor::ExchangeMark (`ctrl-x ctrl-x`) Co-Authored-By: Peter <peter@zed.dev> Release Notes: - Add Emacs mark mode (`ctrl-space` / `ctrl-@` to set mark; `ctrl-x ctrl-x` to swap mark/cursor) - Breaking change: `selection` keyboard context has been replaced with `selection_mode` --------- Co-authored-by: Peter <peter@zed.dev>
This commit is contained in:
parent
c4542ca731
commit
94189e1784
5 changed files with 98 additions and 10 deletions
|
@ -377,6 +377,8 @@ gpui::actions!(
|
|||
ToggleInlayHints,
|
||||
ToggleInlineCompletions,
|
||||
ToggleLineNumbers,
|
||||
ExchangeMark,
|
||||
SetMark,
|
||||
ToggleRelativeLineNumbers,
|
||||
ToggleSelectionMenu,
|
||||
ToggleSoftWrap,
|
||||
|
|
|
@ -706,6 +706,7 @@ pub struct Editor {
|
|||
next_scroll_position: NextScrollCursorCenterTopBottom,
|
||||
addons: HashMap<TypeId, Box<dyn Addon>>,
|
||||
registered_buffers: HashMap<BufferId, OpenLspBufferHandle>,
|
||||
selection_mark_mode: bool,
|
||||
toggle_fold_multiple_buffers: Task<()>,
|
||||
_scroll_cursor_center_top_bottom_task: Task<()>,
|
||||
}
|
||||
|
@ -1364,6 +1365,7 @@ impl Editor {
|
|||
addons: HashMap::default(),
|
||||
registered_buffers: HashMap::default(),
|
||||
_scroll_cursor_center_top_bottom_task: Task::ready(()),
|
||||
selection_mark_mode: false,
|
||||
toggle_fold_multiple_buffers: Task::ready(()),
|
||||
text_style_refinement: None,
|
||||
};
|
||||
|
@ -1456,13 +1458,8 @@ impl Editor {
|
|||
key_context.add("inline_completion");
|
||||
}
|
||||
|
||||
if !self
|
||||
.selections
|
||||
.disjoint
|
||||
.iter()
|
||||
.all(|selection| selection.start == selection.end)
|
||||
{
|
||||
key_context.add("selection");
|
||||
if self.selection_mark_mode {
|
||||
key_context.add("selection_mode");
|
||||
}
|
||||
|
||||
key_context
|
||||
|
@ -2477,6 +2474,8 @@ impl Editor {
|
|||
}
|
||||
|
||||
pub fn cancel(&mut self, _: &Cancel, cx: &mut ViewContext<Self>) {
|
||||
self.selection_mark_mode = false;
|
||||
|
||||
if self.clear_expanded_diff_hunks(cx) {
|
||||
cx.notify();
|
||||
return;
|
||||
|
@ -10622,6 +10621,32 @@ impl Editor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_mark(&mut self, _: &actions::SetMark, cx: &mut ViewContext<Self>) {
|
||||
if self.selection_mark_mode {
|
||||
self.change_selections(None, cx, |s| {
|
||||
s.move_with(|_, sel| {
|
||||
sel.collapse_to(sel.head(), SelectionGoal::None);
|
||||
});
|
||||
})
|
||||
}
|
||||
self.selection_mark_mode = true;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn exchange_mark(&mut self, _: &actions::ExchangeMark, cx: &mut ViewContext<Self>) {
|
||||
if self.selection_mark_mode {
|
||||
self.change_selections(None, cx, |s| {
|
||||
s.move_with(|_, sel| {
|
||||
if sel.start != sel.end {
|
||||
sel.reversed = !sel.reversed
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
self.selection_mark_mode = true;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn toggle_fold(&mut self, _: &actions::ToggleFold, cx: &mut ViewContext<Self>) {
|
||||
if self.is_singleton(cx) {
|
||||
let selection = self.selections.newest::<Point>(cx);
|
||||
|
@ -15234,7 +15259,6 @@ fn check_multiline_range(buffer: &Buffer, range: Range<usize>) -> Range<usize> {
|
|||
range.start..range.start
|
||||
}
|
||||
}
|
||||
|
||||
pub struct KillRing(ClipboardItem);
|
||||
impl Global for KillRing {}
|
||||
|
||||
|
|
|
@ -356,6 +356,8 @@ impl EditorElement {
|
|||
register_action(view, cx, Editor::unfold_all);
|
||||
register_action(view, cx, Editor::unfold_at);
|
||||
register_action(view, cx, Editor::fold_selected_ranges);
|
||||
register_action(view, cx, Editor::set_mark);
|
||||
register_action(view, cx, Editor::exchange_mark);
|
||||
register_action(view, cx, Editor::show_completions);
|
||||
register_action(view, cx, Editor::toggle_code_actions);
|
||||
register_action(view, cx, Editor::open_excerpts);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue