reovim_kernel/core/direction.rs
1//! Direction and boundary types for motion calculations.
2//!
3//! This module provides the foundational enums used by both
4//! motion calculations and text object handling.
5
6/// Direction of cursor movement.
7///
8/// Used by character, line, word, paragraph, and find-char motions.
9///
10/// # Example
11///
12/// ```
13/// use reovim_kernel::api::v1::*;
14///
15/// let forward = Direction::Forward; // h, j, w, }, f
16/// let backward = Direction::Backward; // l, k, b, {, F
17/// ```
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19pub enum Direction {
20 /// Move forward (right for chars, down for lines)
21 Forward,
22 /// Move backward (left for chars, up for lines)
23 Backward,
24}
25
26impl Direction {
27 /// Check if direction is forward.
28 #[must_use]
29 pub const fn is_forward(&self) -> bool {
30 matches!(self, Self::Forward)
31 }
32
33 /// Check if direction is backward.
34 #[must_use]
35 pub const fn is_backward(&self) -> bool {
36 matches!(self, Self::Backward)
37 }
38
39 /// Get the opposite direction.
40 #[must_use]
41 pub const fn opposite(&self) -> Self {
42 match self {
43 Self::Forward => Self::Backward,
44 Self::Backward => Self::Forward,
45 }
46 }
47}
48
49/// Word boundary type for word motions.
50///
51/// Vim distinguishes between "words" and "WORDS":
52/// - **Word**: Sequences of alphanumeric characters or underscores,
53/// separated by other non-whitespace characters or whitespace.
54/// - **`BigWord` (WORD)**: Sequences of non-whitespace characters,
55/// separated only by whitespace.
56///
57/// # Example
58///
59/// ```
60/// use reovim_kernel::api::v1::*;
61///
62/// // Given text: "hello-world foo"
63/// // Word boundaries: hello | - | world | foo
64/// // BigWord boundaries: hello-world | foo
65///
66/// let word = WordBoundary::Word; // w, b, e, ge
67/// let big_word = WordBoundary::BigWord; // W, B, E, gE
68/// ```
69#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
70pub enum WordBoundary {
71 /// Word: alphanumeric + underscore sequences (w/b/e)
72 Word,
73 /// WORD: non-whitespace sequences (W/B/E)
74 BigWord,
75}
76
77impl WordBoundary {
78 /// Check if a character is a word character for this boundary type.
79 #[must_use]
80 pub fn is_word_char(&self, c: char) -> bool {
81 match self {
82 Self::Word => c.is_alphanumeric() || c == '_',
83 Self::BigWord => !c.is_whitespace(),
84 }
85 }
86}
87
88/// Line position types for line-based motions.
89///
90/// These correspond to vim's 0, ^, $, and g_ commands.
91///
92/// # Example
93///
94/// ```
95/// use reovim_kernel::api::v1::*;
96///
97/// // Given line: " hello world "
98/// // ^ ^ ^ ^
99/// // | | | |
100/// // | FirstNonBlank|
101/// // Start End
102/// // LastNonBlank
103///
104/// let start = LinePosition::Start; // 0
105/// let first = LinePosition::FirstNonBlank; // ^
106/// let end = LinePosition::End; // $
107/// let last = LinePosition::LastNonBlank; // g_
108/// ```
109#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
110pub enum LinePosition {
111 /// Start of line, column 0 (vim: 0)
112 Start,
113 /// First non-blank character (vim: ^)
114 FirstNonBlank,
115 /// End of line, last character (vim: $)
116 End,
117 /// Last non-blank character (vim: g_)
118 LastNonBlank,
119}