Add c and d operators to vim normal mode

Extracted motions from normal mode
Changed vim_submode to be vim_operator to enable better composition of operators
This commit is contained in:
Keith Simmons 2022-04-15 16:00:44 -07:00
parent 670757e5c9
commit 63278041e1
10 changed files with 862 additions and 433 deletions

82
crates/vim/src/state.rs Normal file
View file

@ -0,0 +1,82 @@
use editor::CursorShape;
use gpui::keymap::Context;
use serde::Deserialize;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize)]
pub enum Mode {
Normal,
Insert,
}
impl Default for Mode {
fn default() -> Self {
Self::Normal
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize)]
pub enum Namespace {
G,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize)]
pub enum Operator {
Namespace(Namespace),
Change,
Delete,
}
#[derive(Default)]
pub struct VimState {
pub mode: Mode,
pub operator_stack: Vec<Operator>,
}
impl VimState {
pub fn cursor_shape(&self) -> CursorShape {
match self.mode {
Mode::Normal => CursorShape::Block,
Mode::Insert => CursorShape::Bar,
}
}
pub fn vim_controlled(&self) -> bool {
!matches!(self.mode, Mode::Insert)
}
pub fn keymap_context_layer(&self) -> Context {
let mut context = Context::default();
context.map.insert(
"vim_mode".to_string(),
match self.mode {
Mode::Normal => "normal",
Mode::Insert => "insert",
}
.to_string(),
);
if self.vim_controlled() {
context.set.insert("VimControl".to_string());
}
if let Some(operator) = &self.operator_stack.last() {
operator.set_context(&mut context);
}
context
}
}
impl Operator {
pub fn set_context(&self, context: &mut Context) {
let operator_context = match self {
Operator::Namespace(Namespace::G) => "g",
Operator::Change => "c",
Operator::Delete => "d",
}
.to_owned();
context
.map
.insert("vim_operator".to_string(), operator_context.to_string());
}
}