Add a mode indicator for vim (#2763)
Release Notes: - vim: add a mode indicator ([#409](https://github.com/zed-industries/community/issues/409)) Now updated screenshots with @iamnbutler <img width="1043" alt="Screenshot 2023-07-25 at 11 11 57" src="https://github.com/zed-industries/zed/assets/94272/8301479a-8b58-42d8-81a1-bc40e1e0a4df"> <img width="1043" alt="Screenshot 2023-07-25 at 11 12 00" src="https://github.com/zed-industries/zed/assets/94272/89c3b8bd-9cbc-4fd7-ad10-dac5538ed3a3"> <img width="1043" alt="Screenshot 2023-07-25 at 11 12 12" src="https://github.com/zed-industries/zed/assets/94272/adc87fe3-a720-4779-853b-df9443407046">
This commit is contained in:
commit
39f02c2b72
9 changed files with 238 additions and 18 deletions
|
@ -3,6 +3,7 @@ mod test;
|
|||
|
||||
mod editor_events;
|
||||
mod insert;
|
||||
mod mode_indicator;
|
||||
mod motion;
|
||||
mod normal;
|
||||
mod object;
|
||||
|
@ -18,6 +19,7 @@ use gpui::{
|
|||
Subscription, ViewContext, ViewHandle, WeakViewHandle, WindowContext,
|
||||
};
|
||||
use language::CursorShape;
|
||||
pub use mode_indicator::ModeIndicator;
|
||||
use motion::Motion;
|
||||
use normal::normal_replace;
|
||||
use serde::Deserialize;
|
||||
|
@ -119,6 +121,7 @@ pub fn observe_keystrokes(cx: &mut WindowContext) {
|
|||
pub struct Vim {
|
||||
active_editor: Option<WeakViewHandle<Editor>>,
|
||||
editor_subscription: Option<Subscription>,
|
||||
mode_indicator: Option<ViewHandle<ModeIndicator>>,
|
||||
|
||||
enabled: bool,
|
||||
state: VimState,
|
||||
|
@ -178,6 +181,10 @@ impl Vim {
|
|||
self.state.mode = mode;
|
||||
self.state.operator_stack.clear();
|
||||
|
||||
if let Some(mode_indicator) = &self.mode_indicator {
|
||||
mode_indicator.update(cx, |mode_indicator, cx| mode_indicator.set_mode(mode, cx))
|
||||
}
|
||||
|
||||
// Sync editor settings like clip mode
|
||||
self.sync_vim_settings(cx);
|
||||
|
||||
|
@ -264,6 +271,44 @@ impl Vim {
|
|||
}
|
||||
}
|
||||
|
||||
fn sync_mode_indicator(cx: &mut WindowContext) {
|
||||
let Some(workspace) = cx.root_view()
|
||||
.downcast_ref::<Workspace>()
|
||||
.map(|workspace| workspace.downgrade()) else {
|
||||
return;
|
||||
};
|
||||
|
||||
cx.spawn(|mut cx| async move {
|
||||
workspace.update(&mut cx, |workspace, cx| {
|
||||
Vim::update(cx, |vim, cx| {
|
||||
workspace.status_bar().update(cx, |status_bar, cx| {
|
||||
let current_position = status_bar.position_of_item::<ModeIndicator>();
|
||||
|
||||
if vim.enabled && current_position.is_none() {
|
||||
if vim.mode_indicator.is_none() {
|
||||
vim.mode_indicator =
|
||||
Some(cx.add_view(|_| ModeIndicator::new(vim.state.mode)));
|
||||
};
|
||||
let mode_indicator = vim.mode_indicator.as_ref().unwrap();
|
||||
let position = status_bar
|
||||
.position_of_item::<language_selector::ActiveBufferLanguage>();
|
||||
if let Some(position) = position {
|
||||
status_bar.insert_item_after(position, mode_indicator.clone(), cx)
|
||||
} else {
|
||||
status_bar.add_left_item(mode_indicator.clone(), cx)
|
||||
}
|
||||
} else if !vim.enabled {
|
||||
if let Some(position) = current_position {
|
||||
status_bar.remove_item_at(position, cx)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
fn set_enabled(&mut self, enabled: bool, cx: &mut AppContext) {
|
||||
if self.enabled != enabled {
|
||||
self.enabled = enabled;
|
||||
|
@ -314,6 +359,8 @@ impl Vim {
|
|||
self.unhook_vim_settings(editor, cx);
|
||||
}
|
||||
});
|
||||
|
||||
Vim::sync_mode_indicator(cx);
|
||||
}
|
||||
|
||||
fn unhook_vim_settings(&self, editor: &mut Editor, cx: &mut ViewContext<Editor>) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue