Refactor mode indicator to remove itself
One of the problems we had is that the status_bar shows a gap between items, and we want to not add an additional gap for an invisible status indicator.
This commit is contained in:
parent
d14a484a20
commit
43d94e37ec
7 changed files with 142 additions and 41 deletions
|
|
@ -118,6 +118,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,
|
||||
|
|
@ -177,6 +178,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);
|
||||
|
||||
|
|
@ -259,6 +264,51 @@ impl Vim {
|
|||
}
|
||||
}
|
||||
|
||||
fn sync_mode_indicator(cx: &mut AppContext) {
|
||||
cx.spawn(|mut cx| async move {
|
||||
let workspace = match cx.update(|cx| {
|
||||
cx.update_active_window(|cx| {
|
||||
cx.root_view()
|
||||
.downcast_ref::<Workspace>()
|
||||
.map(|workspace| workspace.downgrade())
|
||||
})
|
||||
}) {
|
||||
Some(Some(workspace)) => workspace,
|
||||
_ => {
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
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();
|
||||
// TODO: would it be better to depend on the diagnostics crate
|
||||
// so we can pass the type directly?
|
||||
let position = status_bar.position_of_named_item("DiagnosticIndicator");
|
||||
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;
|
||||
|
|
@ -309,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