diff --git a/src/edit_mode/vi/command.rs b/src/edit_mode/vi/command.rs index 18999e5c..f7bcf724 100644 --- a/src/edit_mode/vi/command.rs +++ b/src/edit_mode/vi/command.rs @@ -109,6 +109,10 @@ where let _ = input.next(); Some(Command::DeleteChar) } + Some('X') => { + let _ = input.next(); + Some(Command::DeleteCharBackward) + } Some('r') => { let _ = input.next(); input @@ -177,6 +181,7 @@ pub enum Command { Incomplete, Delete, DeleteChar, + DeleteCharBackward, ReplaceChar(char), SubstituteCharWithInsert, NewlineAbove, @@ -242,6 +247,16 @@ impl Command { select: false, })], Self::RewriteCurrentLine => vec![ReedlineOption::Edit(EditCommand::CutCurrentLine)], + Self::DeleteCharBackward => { + if vi_state.mode == ViMode::Visual { + vec![ReedlineOption::Edit(EditCommand::CutSelection)] + } else { + vec![ + ReedlineOption::Edit(EditCommand::MoveLeft { select: false }), + ReedlineOption::Edit(EditCommand::CutChar), + ] + } + } Self::DeleteChar => { if vi_state.mode == ViMode::Visual { vec![ReedlineOption::Edit(EditCommand::CutSelection)] diff --git a/src/edit_mode/vi/parser.rs b/src/edit_mode/vi/parser.rs index da0839cd..5ba40db5 100644 --- a/src/edit_mode/vi/parser.rs +++ b/src/edit_mode/vi/parser.rs @@ -210,6 +210,36 @@ mod tests { parse(ViMode::Normal, &mut input.iter().peekable()) } + #[test] + fn test_delete_char_backward() { + let input = ['X']; + let output = vi_parse(&input); + assert_eq!( + output, + ParsedViSequence { + multiplier: None, + command: Some(Command::DeleteCharBackward), + count: None, + motion: ParseResult::Incomplete, + } + ); + } + + #[test] + fn test_two_delete_char_backward() { + let input = ['2', 'X']; + let output = vi_parse(&input); + assert_eq!( + output, + ParsedViSequence { + multiplier: Some(2), + command: Some(Command::DeleteCharBackward), + count: None, + motion: ParseResult::Incomplete, + } + ); + } + #[test] fn test_delete_without_motion() { let input = ['d'];