Compare commits

...

1 commit

Author SHA1 Message Date
b909cd4559
WIP: InputMode::{Normal, Input}
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
2023-04-21 12:50:15 +02:00
2 changed files with 43 additions and 1 deletions

View file

@ -9,14 +9,26 @@ use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
// TODO: add punctuation. // TODO: add punctuation.
const SEPARATORS: [char; 3] = [' ', '\t', '\n']; const SEPARATORS: [char; 3] = [' ', '\t', '\n'];
#[derive(Debug, PartialEq)]
pub enum InputMode {
/// Insert mode. For inserting new text.
Insert,
/// Normal mode. For navigation and manipulation of text. Use Escape to come back to Normal
/// mode from any other mode.
Normal,
}
#[derive(Debug)] #[derive(Debug)]
pub enum InputEvent { pub enum InputEvent {
None, None,
Exit, Exit,
Text(String), Text(String),
Mode(InputMode),
} }
pub struct Input<W: Write> { pub struct Input<W: Write> {
mode: InputMode,
stdout: W, stdout: W,
string: Vec<char>, string: Vec<char>,
clipboard: Vec<char>, clipboard: Vec<char>,
@ -27,6 +39,7 @@ pub struct Input<W: Write> {
impl<W: Write> Input<W> { impl<W: Write> Input<W> {
pub fn new(stdout: W) -> Input<W> { pub fn new(stdout: W) -> Input<W> {
Input { Input {
mode: InputMode::Insert,
stdout, stdout,
string: Vec::new(), string: Vec::new(),
clipboard: Vec::new(), clipboard: Vec::new(),
@ -35,10 +48,15 @@ impl<W: Write> Input<W> {
} }
} }
pub fn with_mode(&mut self, mode: InputMode) {
self.mode = mode
}
#[cfg(test)] #[cfg(test)]
fn from(stdout: W, input: &str) -> Input<W> { fn from(stdout: W, input: &str) -> Input<W> {
let string: Vec<char> = input.chars().collect(); let string: Vec<char> = input.chars().collect();
Input { Input {
mode: InputMode::Insert,
stdout, stdout,
cursor: string.len(), cursor: string.len(),
string, string,
@ -73,8 +91,19 @@ impl<W: Write> Input<W> {
} }
pub fn handle_key(&mut self, code: KeyCode, modifiers: KeyModifiers) -> Result<InputEvent> { pub fn handle_key(&mut self, code: KeyCode, modifiers: KeyModifiers) -> Result<InputEvent> {
// Escape always changes input mode back to Normal.
if let KeyCode::Esc = code {
return Ok(InputEvent::Mode(InputMode::Normal));
}
match self.mode {
InputMode::Insert => self.handle_key_mode_input(code, modifiers),
_ => Ok(InputEvent::None)
}
}
pub fn handle_key_mode_input(&mut self, code: KeyCode, modifiers: KeyModifiers) -> Result<InputEvent> {
match (code, modifiers) { match (code, modifiers) {
(KeyCode::Esc, _) => return Ok(InputEvent::Exit),
(KeyCode::Char('d'), KeyModifiers::CONTROL) => return Ok(InputEvent::Exit), (KeyCode::Char('d'), KeyModifiers::CONTROL) => return Ok(InputEvent::Exit),
(KeyCode::Char('l'), KeyModifiers::CONTROL) => { (KeyCode::Char('l'), KeyModifiers::CONTROL) => {
self.stdout self.stdout
@ -325,4 +354,16 @@ mod test {
} }
Ok(()) Ok(())
} }
#[test]
fn mode_change_normal() -> Result<()> {
let mut stdout = Vec::new();
let mut input = Input::new(&mut stdout);
let event = input.handle_key(KeyCode::Esc, KeyModifiers::NONE)?;
match event {
InputEvent::Mode(mode) => assert_eq!(mode, InputMode::Normal),
evt => panic!("Wrong event: {evt:?}"),
}
Ok(())
}
} }

View file

@ -149,6 +149,7 @@ impl<'a> ChatTab<'a> {
Event::Key(event) => { Event::Key(event) => {
match self.input.handle_key(event.code, event.modifiers) { match self.input.handle_key(event.code, event.modifiers) {
Ok(InputEvent::Exit) => break, Ok(InputEvent::Exit) => break,
Ok(InputEvent::Mode(mode)) => self.input.with_mode(mode),
Ok(InputEvent::Text(message)) => { Ok(InputEvent::Text(message)) => {
/* /*
let item = logger::Item::Message(logger::LogMessage { let item = logger::Item::Message(logger::LogMessage {