WIP: InputMode::{Normal, Input}
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
parent
48c4e7b4a7
commit
b909cd4559
2 changed files with 43 additions and 1 deletions
43
src/input.rs
43
src/input.rs
|
@ -9,14 +9,26 @@ use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
|
|||
// TODO: add punctuation.
|
||||
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)]
|
||||
pub enum InputEvent {
|
||||
None,
|
||||
Exit,
|
||||
Text(String),
|
||||
Mode(InputMode),
|
||||
}
|
||||
|
||||
pub struct Input<W: Write> {
|
||||
mode: InputMode,
|
||||
stdout: W,
|
||||
string: Vec<char>,
|
||||
clipboard: Vec<char>,
|
||||
|
@ -27,6 +39,7 @@ pub struct Input<W: Write> {
|
|||
impl<W: Write> Input<W> {
|
||||
pub fn new(stdout: W) -> Input<W> {
|
||||
Input {
|
||||
mode: InputMode::Insert,
|
||||
stdout,
|
||||
string: 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)]
|
||||
fn from(stdout: W, input: &str) -> Input<W> {
|
||||
let string: Vec<char> = input.chars().collect();
|
||||
Input {
|
||||
mode: InputMode::Insert,
|
||||
stdout,
|
||||
cursor: string.len(),
|
||||
string,
|
||||
|
@ -73,8 +91,19 @@ impl<W: Write> Input<W> {
|
|||
}
|
||||
|
||||
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) {
|
||||
(KeyCode::Esc, _) => return Ok(InputEvent::Exit),
|
||||
(KeyCode::Char('d'), KeyModifiers::CONTROL) => return Ok(InputEvent::Exit),
|
||||
(KeyCode::Char('l'), KeyModifiers::CONTROL) => {
|
||||
self.stdout
|
||||
|
@ -325,4 +354,16 @@ mod test {
|
|||
}
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,6 +149,7 @@ impl<'a> ChatTab<'a> {
|
|||
Event::Key(event) => {
|
||||
match self.input.handle_key(event.code, event.modifiers) {
|
||||
Ok(InputEvent::Exit) => break,
|
||||
Ok(InputEvent::Mode(mode)) => self.input.with_mode(mode),
|
||||
Ok(InputEvent::Text(message)) => {
|
||||
/*
|
||||
let item = logger::Item::Message(logger::LogMessage {
|
||||
|
|
Loading…
Reference in a new issue