Add ! negation support, fix POSIX exit statuses, and improve vi emulation with comprehensive tests
This commit is contained in:
@@ -13,6 +13,10 @@ impl ViInsert {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
pub fn record_cmd(mut self, cmd: ViCmd) -> Self {
|
||||
self.cmds.push(cmd);
|
||||
self
|
||||
}
|
||||
pub fn with_count(mut self, repeat_count: u16) -> Self {
|
||||
self.repeat_count = repeat_count;
|
||||
self
|
||||
|
||||
@@ -434,7 +434,7 @@ impl ViNormal {
|
||||
'g' => {
|
||||
chars_clone.next();
|
||||
chars = chars_clone;
|
||||
break 'motion_parse Some(MotionCmd(count, Motion::BeginningOfBuffer));
|
||||
break 'motion_parse Some(MotionCmd(count, Motion::StartOfBuffer));
|
||||
}
|
||||
'e' => {
|
||||
chars = chars_clone;
|
||||
|
||||
@@ -4,19 +4,11 @@ use crate::readline::vicmd::{CmdFlags, RegisterName, To, Verb, VerbCmd, ViCmd};
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
pub struct ViVerbatim {
|
||||
pending_seq: String,
|
||||
sent_cmd: Vec<ViCmd>,
|
||||
repeat_count: u16,
|
||||
read_one: bool
|
||||
}
|
||||
|
||||
impl ViVerbatim {
|
||||
pub fn read_one() -> Self {
|
||||
Self {
|
||||
read_one: true,
|
||||
..Self::default()
|
||||
}
|
||||
}
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
@@ -31,7 +23,7 @@ impl ViVerbatim {
|
||||
impl ViMode for ViVerbatim {
|
||||
fn handle_key(&mut self, key: E) -> Option<ViCmd> {
|
||||
match key {
|
||||
E(K::Verbatim(seq), _mods) if self.read_one => {
|
||||
E(K::Verbatim(seq), _mods) => {
|
||||
log::debug!("Received verbatim key sequence: {:?}", seq);
|
||||
let cmd = ViCmd {
|
||||
register: RegisterName::default(),
|
||||
@@ -43,22 +35,6 @@ impl ViMode for ViVerbatim {
|
||||
self.sent_cmd.push(cmd.clone());
|
||||
Some(cmd)
|
||||
}
|
||||
E(K::Verbatim(seq), _mods) => {
|
||||
self.pending_seq.push_str(&seq);
|
||||
None
|
||||
}
|
||||
E(K::BracketedPasteEnd, _mods) => {
|
||||
log::debug!("Received verbatim paste: {:?}", self.pending_seq);
|
||||
let cmd = ViCmd {
|
||||
register: RegisterName::default(),
|
||||
verb: Some(VerbCmd(1, Verb::Insert(self.pending_seq.clone()))),
|
||||
motion: None,
|
||||
raw_seq: std::mem::take(&mut self.pending_seq),
|
||||
flags: CmdFlags::EXIT_CUR_MODE,
|
||||
};
|
||||
self.sent_cmd.push(cmd.clone());
|
||||
Some(cmd)
|
||||
}
|
||||
_ => common_cmds(key),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ impl ViVisual {
|
||||
let ch = chars_clone.next()?;
|
||||
return Some(ViCmd {
|
||||
register,
|
||||
verb: Some(VerbCmd(1, Verb::ReplaceChar(ch))),
|
||||
verb: Some(VerbCmd(1, Verb::ReplaceCharInplace(ch,1))),
|
||||
motion: None,
|
||||
raw_seq: self.take_cmd(),
|
||||
flags: CmdFlags::empty(),
|
||||
@@ -237,6 +237,24 @@ impl ViVisual {
|
||||
flags: CmdFlags::empty(),
|
||||
});
|
||||
}
|
||||
's' => {
|
||||
return Some(ViCmd {
|
||||
register,
|
||||
verb: Some(VerbCmd(count, Verb::Delete)),
|
||||
motion: None,
|
||||
raw_seq: self.take_cmd(),
|
||||
flags: CmdFlags::empty(),
|
||||
});
|
||||
}
|
||||
'S' => {
|
||||
return Some(ViCmd {
|
||||
register,
|
||||
verb: Some(VerbCmd(count, Verb::Change)),
|
||||
motion: None,
|
||||
raw_seq: self.take_cmd(),
|
||||
flags: CmdFlags::empty(),
|
||||
});
|
||||
}
|
||||
'U' => {
|
||||
return Some(ViCmd {
|
||||
register,
|
||||
@@ -283,8 +301,13 @@ impl ViVisual {
|
||||
});
|
||||
}
|
||||
'y' => {
|
||||
chars = chars_clone;
|
||||
break 'verb_parse Some(VerbCmd(count, Verb::Yank));
|
||||
return Some(ViCmd {
|
||||
register,
|
||||
verb: Some(VerbCmd(count, Verb::Yank)),
|
||||
motion: None,
|
||||
raw_seq: self.take_cmd(),
|
||||
flags: CmdFlags::empty(),
|
||||
});
|
||||
}
|
||||
'd' => {
|
||||
chars = chars_clone;
|
||||
@@ -335,7 +358,7 @@ impl ViVisual {
|
||||
'g' => {
|
||||
chars_clone.next();
|
||||
chars = chars_clone;
|
||||
break 'motion_parse Some(MotionCmd(count, Motion::BeginningOfBuffer));
|
||||
break 'motion_parse Some(MotionCmd(count, Motion::StartOfBuffer));
|
||||
}
|
||||
'e' => {
|
||||
chars_clone.next();
|
||||
|
||||
Reference in New Issue
Block a user