Add a mode indicator for vim

This is the second most common remaining complaint (after :w not
working).

Fixes: zed-industries/community#409
This commit is contained in:
Conrad Irwin 2023-07-20 12:32:27 -06:00
parent 35400d5797
commit 458916409c
7 changed files with 77 additions and 0 deletions

View file

@ -32,6 +32,7 @@ language = { path = "../language" }
search = { path = "../search" }
settings = { path = "../settings" }
workspace = { path = "../workspace" }
theme = { path = "../theme" }
[dev-dependencies]
indoc.workspace = true
@ -44,3 +45,4 @@ project = { path = "../project", features = ["test-support"] }
util = { path = "../util", features = ["test-support"] }
settings = { path = "../settings" }
workspace = { path = "../workspace", features = ["test-support"] }
theme = { path = "../theme", features = ["test-support"] }

View file

@ -0,0 +1,68 @@
use gpui::{
elements::{Empty, Label},
AnyElement, Element, Entity, View, ViewContext,
};
use workspace::{item::ItemHandle, StatusItemView};
use crate::{state::Mode, Vim};
pub struct ModeIndicator {
mode: Option<Mode>,
}
impl ModeIndicator {
pub fn new(cx: &mut ViewContext<Self>) -> Self {
cx.observe_global::<Vim, _>(|this, cx| {
let vim = Vim::read(cx);
if vim.enabled {
this.set_mode(Some(Vim::read(cx).state.mode), cx)
} else {
this.set_mode(None, cx)
}
})
.detach();
Self { mode: None }
}
pub fn set_mode(&mut self, mode: Option<Mode>, cx: &mut ViewContext<Self>) {
if mode != self.mode {
self.mode = mode;
cx.notify();
}
}
}
impl Entity for ModeIndicator {
type Event = ();
}
impl View for ModeIndicator {
fn ui_name() -> &'static str {
"ModeIndicator"
}
fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
if let Some(mode) = self.mode {
let theme = &theme::current(cx).workspace.status_bar;
let text = match mode {
Mode::Normal => "",
Mode::Insert => "--- INSERT ---",
Mode::Visual { line: false } => "--- VISUAL ---",
Mode::Visual { line: true } => "--- VISUAL LINE ---",
};
Label::new(text, theme.vim_mode.clone()).into_any()
} else {
Empty::new().into_any()
}
}
}
impl StatusItemView for ModeIndicator {
fn set_active_pane_item(
&mut self,
_active_pane_item: Option<&dyn ItemHandle>,
_cx: &mut ViewContext<Self>,
) {
// nothing to do.
}
}

View file

@ -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::{
ViewHandle, WeakViewHandle, WindowContext,
};
use language::CursorShape;
pub use mode_indicator::ModeIndicator;
use motion::Motion;
use normal::normal_replace;
use serde::Deserialize;