Skip to content

Commit 8a6b663

Browse files
author
Noam Lewis
committed
WIP
1 parent a079360 commit 8a6b663

File tree

1 file changed

+88
-8
lines changed

1 file changed

+88
-8
lines changed

src/main.rs

Lines changed: 88 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
extern crate crossterm;
22
extern crate ratatui;
3-
use std::io;
3+
use std::{io, iter::FromIterator};
44

55
use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyModifiers};
6-
use ratatui::{DefaultTerminal, Frame};
6+
use ratatui::{
7+
layout::Position,
8+
text::{Line, Span, Text},
9+
DefaultTerminal, Frame,
10+
};
711

812
struct State {
9-
text: Vec<char>,
13+
lines: Vec<Vec<char>>,
14+
cursor: Position,
1015
}
1116

1217
impl State {
@@ -26,29 +31,104 @@ impl State {
2631
modifiers: KeyModifiers::NONE,
2732
..
2833
}) => self.insert_char(c),
34+
Event::Key(KeyEvent {
35+
code: KeyCode::Backspace,
36+
modifiers: KeyModifiers::NONE,
37+
..
38+
}) => self.delete_prev_char(),
2939
Event::Key(KeyEvent {
3040
code: KeyCode::Enter,
3141
modifiers: KeyModifiers::NONE,
3242
..
33-
}) => self.insert_char('\n'),
43+
}) => self.insert_line(),
44+
Event::Key(KeyEvent {
45+
code: KeyCode::Left,
46+
modifiers: KeyModifiers::NONE,
47+
..
48+
}) => self.move_left(),
49+
Event::Key(KeyEvent {
50+
code: KeyCode::Right,
51+
modifiers: KeyModifiers::NONE,
52+
..
53+
}) => self.move_right(),
54+
3455
_ => {}
3556
}
3657
}
3758
}
3859

3960
fn insert_char(&mut self, c: char) {
40-
self.text.push(c);
61+
let line = self.lines.get_mut(self.cursor.y as usize);
62+
match line {
63+
None => {}
64+
Some(v) => {
65+
v.insert(self.cursor.x as usize, c);
66+
self.cursor.x += 1;
67+
}
68+
}
69+
}
70+
71+
fn delete_prev_char(&mut self) {
72+
if self.cursor.x > 0 {
73+
self.cursor.x -= 1;
74+
let line = self.lines.get_mut(self.cursor.y as usize).unwrap();
75+
line.remove(self.cursor.x as usize);
76+
} else if self.cursor.y > 0 {
77+
self.cursor.y -= 1;
78+
let line = self.lines.remove((self.cursor.y + 1) as usize);
79+
let prev_line = self.lines.get_mut(self.cursor.y as usize).unwrap();
80+
self.cursor.x = prev_line.len() as u16;
81+
prev_line.extend(line);
82+
} else {
83+
return;
84+
}
85+
}
86+
87+
fn insert_line(&mut self) {
88+
self.cursor.y += 1;
89+
self.cursor.x = 0;
90+
self.lines.insert(self.cursor.y as usize, vec![]);
4191
}
4292

4393
fn render(&self, frame: &mut Frame) {
44-
let s: String = self.text.iter().collect();
45-
frame.render_widget(s, frame.area());
94+
fn to_line(l: &Vec<char>) -> Line<'_> {
95+
let content = l.iter().collect::<String>();
96+
Line::from(Span::raw(content))
97+
}
98+
frame.render_widget(
99+
Text::from_iter(self.lines.iter().map(to_line)),
100+
frame.area(),
101+
);
102+
frame.set_cursor_position(self.cursor);
103+
}
104+
105+
fn move_left(&mut self) {
106+
if self.cursor.x > 0 {
107+
self.cursor.x -= 1;
108+
} else if self.cursor.y > 0 {
109+
self.cursor.y -= 1;
110+
let prev_line = self.lines.get(self.cursor.y as usize).unwrap();
111+
self.cursor.x = prev_line.len() as u16;
112+
}
113+
}
114+
115+
fn move_right(&mut self) {
116+
let line = self.lines.get(self.cursor.y as usize).unwrap();
117+
if self.cursor.x < line.len() as u16 {
118+
self.cursor.x += 1;
119+
} else if self.cursor.y + 1 < self.lines.len() as u16 {
120+
self.cursor.y += 1;
121+
self.cursor.x = 0;
122+
}
46123
}
47124
}
48125

49126
fn main() -> io::Result<()> {
50127
let terminal = ratatui::init();
51-
let mut state: State = State { text: Vec::new() };
128+
let mut state: State = State {
129+
lines: vec![vec![]],
130+
cursor: Position::new(0, 0),
131+
};
52132
let result = state.run(terminal);
53133
ratatui::restore();
54134
result

0 commit comments

Comments
 (0)