1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub struct BufferPosition {
5 pub row: usize,
6 pub column: usize,
7}
8
9impl BufferPosition {
10 pub fn new(row: usize, column: usize) -> Self {
11 Self { row, column }
12 }
13
14 pub fn zero() -> Self {
15 Self { row: 0, column: 0 }
16 }
17}
18
19#[derive(Clone)]
20pub struct EditorState {
21 pub lines: Vec<String>,
23 pub cursor: BufferPosition,
25 pub selection_anchor: Option<BufferPosition>,
27 pub font_size: f32,
29}
30
31impl EditorState {
32 pub fn new() -> Self {
33 Self {
34 lines: vec![String::new()],
35 cursor: BufferPosition::zero(),
36 selection_anchor: None,
37 font_size: 48.0,
38 }
39 }
40
41 pub fn clone_for_undo(&self) -> Self {
42 Self {
43 lines: self.lines.clone(),
44 cursor: self.cursor,
45 selection_anchor: self.selection_anchor,
46 font_size: self.font_size,
47 }
48 }
49
50 pub fn to_string(&self) -> String {
52 self.lines.join("\n")
53 }
54
55 pub fn from_string(content: String) -> Self {
57 let lines: Vec<String> = if content.is_empty() {
58 vec![String::new()]
59 } else {
60 content.split('\n').map(|s| s.to_string()).collect()
61 };
62
63 Self {
64 lines,
65 cursor: BufferPosition::zero(),
66 selection_anchor: None,
67 font_size: 48.0,
68 }
69 }
70
71 pub fn line_count(&self) -> usize {
72 self.lines.len()
73 }
74
75 pub fn line(&self, row: usize) -> Option<&str> {
76 self.lines.get(row).map(|s| s.as_str())
77 }
78
79 pub fn line_len(&self, row: usize) -> usize {
80 self.lines.get(row).map(|s| s.len()).unwrap_or(0)
81 }
82}