use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
pub enum Motion {
Left,
Right,
Up,
Down,
WordStartNext,
WordEndNext,
WordStartPrev,
WordEndPrev,
BigWordStartNext,
BigWordEndNext,
BigWordStartPrev,
BigWordEndPrev,
LineStart,
LineFirstNonBlank,
LineLastNonBlank,
LineEnd,
Column(u32),
LineDownFirstNonBlank,
LineUpFirstNonBlank,
LinewiseDown,
DocStart,
DocEnd,
FindChar {
ch: char,
backward: bool,
till: bool,
},
RepeatFind {
reverse: bool,
},
MatchPair,
MarkExact(char),
MarkLine(char),
ParagraphNext,
ParagraphPrev,
SentenceNext,
SentencePrev,
ScreenTop,
ScreenMiddle,
ScreenBottom,
PageUp,
PageDown,
HalfPageUp,
HalfPageDown,
GotoLine(u32),
ForwardSexp,
BackwardSexp,
UpList,
DownList,
BeginningOfDefun,
EndOfDefun,
BeginningOfSexp,
EndOfSexp,
SearchNext,
SearchPrev,
}
impl Motion {
#[must_use]
pub const fn is_inclusive(self) -> bool {
match self {
Self::WordEndNext
| Self::BigWordEndNext
| Self::LineLastNonBlank
| Self::MatchPair
| Self::FindChar { backward: false, .. }
| Self::WordEndPrev
| Self::BigWordEndPrev => true,
Self::Left
| Self::Right
| Self::Up
| Self::Down
| Self::WordStartNext
| Self::WordStartPrev
| Self::BigWordStartNext
| Self::BigWordStartPrev
| Self::LineStart
| Self::LineFirstNonBlank
| Self::LineEnd
| Self::Column(_)
| Self::LineDownFirstNonBlank
| Self::LineUpFirstNonBlank
| Self::LinewiseDown
| Self::DocStart
| Self::DocEnd
| Self::GotoLine(_)
| Self::FindChar { backward: true, .. }
| Self::RepeatFind { .. }
| Self::MarkExact(_)
| Self::MarkLine(_)
| Self::ParagraphNext
| Self::ParagraphPrev
| Self::SentenceNext
| Self::SentencePrev
| Self::ScreenTop
| Self::ScreenMiddle
| Self::ScreenBottom
| Self::PageUp
| Self::PageDown
| Self::HalfPageUp
| Self::HalfPageDown
| Self::ForwardSexp
| Self::BackwardSexp
| Self::UpList
| Self::DownList
| Self::BeginningOfDefun
| Self::EndOfDefun
| Self::BeginningOfSexp
| Self::EndOfSexp
| Self::SearchNext
| Self::SearchPrev => false,
}
}
#[must_use]
pub const fn is_linewise(self) -> bool {
match self {
Self::Up
| Self::Down
| Self::DocStart
| Self::DocEnd
| Self::GotoLine(_)
| Self::ScreenTop
| Self::ScreenMiddle
| Self::ScreenBottom
| Self::LineDownFirstNonBlank
| Self::LineUpFirstNonBlank
| Self::LinewiseDown
| Self::MarkLine(_)
| Self::PageUp
| Self::PageDown
| Self::HalfPageUp
| Self::HalfPageDown => true,
Self::Left
| Self::Right
| Self::WordStartNext
| Self::WordEndNext
| Self::WordStartPrev
| Self::WordEndPrev
| Self::BigWordStartNext
| Self::BigWordEndNext
| Self::BigWordStartPrev
| Self::BigWordEndPrev
| Self::LineStart
| Self::LineFirstNonBlank
| Self::LineLastNonBlank
| Self::LineEnd
| Self::Column(_)
| Self::FindChar { .. }
| Self::RepeatFind { .. }
| Self::MatchPair
| Self::MarkExact(_)
| Self::ParagraphNext
| Self::ParagraphPrev
| Self::SentenceNext
| Self::SentencePrev
| Self::ForwardSexp
| Self::BackwardSexp
| Self::UpList
| Self::DownList
| Self::BeginningOfDefun
| Self::EndOfDefun
| Self::BeginningOfSexp
| Self::EndOfSexp
| Self::SearchNext
| Self::SearchPrev => false,
}
}
#[must_use]
pub const fn is_structural(self) -> bool {
matches!(
self,
Self::ForwardSexp
| Self::BackwardSexp
| Self::UpList
| Self::DownList
| Self::BeginningOfDefun
| Self::EndOfDefun
| Self::BeginningOfSexp
| Self::EndOfSexp,
)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
pub enum Operator {
Delete,
Yank,
Change,
Indent,
Dedent,
Filter,
Format,
SlurpForward,
SlurpBackward,
BarfForward,
BarfBackward,
Splice,
Wrap,
Raise,
}
impl Operator {
#[must_use]
pub const fn leaves_register(self) -> bool {
matches!(self, Self::Delete | Self::Yank | Self::Change)
}
#[must_use]
pub const fn is_structural(self) -> bool {
matches!(
self,
Self::SlurpForward
| Self::SlurpBackward
| Self::BarfForward
| Self::BarfBackward
| Self::Splice
| Self::Wrap
| Self::Raise,
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn register_emitting_ops() {
assert!(Operator::Delete.leaves_register());
assert!(Operator::Yank.leaves_register());
assert!(Operator::Change.leaves_register());
assert!(!Operator::Format.leaves_register());
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
pub enum TextObject {
NextMatch,
PrevMatch,
Line,
Word { around: bool },
Delimited {
open: char,
close: char,
around: bool,
},
}
impl TextObject {
#[must_use]
pub const fn register_kind(self) -> crate::register::RegisterKind {
use crate::register::RegisterKind as K;
match self {
Self::Line => K::Linewise,
Self::NextMatch | Self::PrevMatch | Self::Word { .. } | Self::Delimited { .. } => {
K::Charwise
}
}
}
}