fix vim repeat (#8513)

Release Notes:

- vim: Fixed `.` when multiple windows are open
([#7446](https://github.com/zed-industries/zed/issues/7446)).
- vim: Fixed switching to normal mode after `J`, `<` or `>` in visual
mode ([#4439](https://github.com/zed-industries/zed/issues/4439))
- vim: Added `ctrl-t` and `ctrl-d` for indent/outdent in insert mode.

- Fixed indent/outdent/join lines appearing to work in read-only buffers
([#8423](https://github.com/zed-industries/zed/issues/8423))
- Fixed indent with an empty selection when the cursor was in column 0
This commit is contained in:
Conrad Irwin 2024-02-27 21:36:12 -07:00 committed by GitHub
parent 9a7a267203
commit 9906b31691
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 82 additions and 48 deletions

View file

@ -22,8 +22,8 @@ use editor::{
Editor, EditorEvent, EditorMode,
};
use gpui::{
actions, impl_actions, Action, AppContext, EntityId, Global, Subscription, View, ViewContext,
WeakView, WindowContext,
actions, impl_actions, Action, AppContext, EntityId, Global, KeystrokeEvent, Subscription,
View, ViewContext, WeakView, WindowContext,
};
use language::{CursorShape, Point, Selection, SelectionGoal};
pub use mode_indicator::ModeIndicator;
@ -76,6 +76,7 @@ pub fn init(cx: &mut AppContext) {
VimModeSetting::register(cx);
VimSettings::register(cx);
cx.observe_keystrokes(observe_keystrokes).detach();
editor_events::init(cx);
cx.observe_new_views(|workspace: &mut Workspace, cx| register(workspace, cx))
@ -135,46 +136,42 @@ fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
visual::register(workspace, cx);
}
/// Registers a keystroke observer to observe keystrokes for the Vim integration.
pub fn observe_keystrokes(cx: &mut WindowContext) {
cx.observe_keystrokes(|keystroke_event, cx| {
if let Some(action) = keystroke_event
.action
.as_ref()
.map(|action| action.boxed_clone())
{
Vim::update(cx, |vim, _| {
if vim.workspace_state.recording {
vim.workspace_state
.recorded_actions
.push(ReplayableAction::Action(action.boxed_clone()));
/// Called whenever an keystroke is typed so vim can observe all actions
/// and keystrokes accordingly.
fn observe_keystrokes(keystroke_event: &KeystrokeEvent, cx: &mut WindowContext) {
if let Some(action) = keystroke_event
.action
.as_ref()
.map(|action| action.boxed_clone())
{
Vim::update(cx, |vim, _| {
if vim.workspace_state.recording {
vim.workspace_state
.recorded_actions
.push(ReplayableAction::Action(action.boxed_clone()));
if vim.workspace_state.stop_recording_after_next_action {
vim.workspace_state.recording = false;
vim.workspace_state.stop_recording_after_next_action = false;
}
if vim.workspace_state.stop_recording_after_next_action {
vim.workspace_state.recording = false;
vim.workspace_state.stop_recording_after_next_action = false;
}
});
// Keystroke is handled by the vim system, so continue forward
if action.name().starts_with("vim::") {
return;
}
} else if cx.has_pending_keystrokes() {
});
// Keystroke is handled by the vim system, so continue forward
if action.name().starts_with("vim::") {
return;
}
} else if cx.has_pending_keystrokes() {
return;
}
Vim::update(cx, |vim, cx| match vim.active_operator() {
Some(
Operator::FindForward { .. } | Operator::FindBackward { .. } | Operator::Replace,
) => {}
Some(_) => {
vim.clear_operator(cx);
}
_ => {}
});
})
.detach()
Vim::update(cx, |vim, cx| match vim.active_operator() {
Some(Operator::FindForward { .. } | Operator::FindBackward { .. } | Operator::Replace) => {}
Some(_) => {
vim.clear_operator(cx);
}
_ => {}
});
}
/// The state pertaining to Vim mode.