Skip to content

Commit

Permalink
feat: input - add support for ctrl+w and ctrl-u (#27)
Browse files Browse the repository at this point in the history
* feat: input - add support for ctrl+w and ctrl-u
* fix: linting errors
* fix: use constants for chars, handle punctuation
  • Loading branch information
roele authored Jan 24, 2024
1 parent e09e9e8 commit f41992b
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub struct Input<'a> {
term: Term,
}

const CTRL_U: char = '\u{15}';
const CTRL_W: char = '\u{17}';

impl<'a> Input<'a> {
/// Creates a new input with the given title.
pub fn new<S: Into<String>>(title: S) -> Self {
Expand Down Expand Up @@ -114,6 +117,8 @@ impl<'a> Input<'a> {
self.set_cursor()?;

match self.term.read_key()? {
Key::Char(CTRL_U) => self.handle_ctrl_u()?,
Key::Char(CTRL_W) => self.handle_ctrl_w()?,
Key::Char(c) => self.handle_key(c)?,
Key::Backspace => self.handle_backspace()?,
Key::ArrowLeft => self.handle_arrow_left()?,
Expand All @@ -134,6 +139,34 @@ impl<'a> Input<'a> {
Ok(())
}

fn handle_ctrl_u(&mut self) -> io::Result<()> {
self.input.replace_range(..self.cursor, "");
self.cursor = 0;
Ok(())
}

fn handle_ctrl_w(&mut self) -> io::Result<()> {
let slice = &self.input[0..self.cursor]
.trim_end_matches(|c: char| c.is_ascii_punctuation() || c.is_ascii_whitespace());
let offset = slice
.char_indices()
.rfind(|&(_, x)| x.is_ascii_punctuation() || x.is_ascii_whitespace())
.map(|(i, _)| i)
.unwrap_or(0);

let from = match offset > 0 {
true => offset + 1,
false => offset,
};
self.input.replace_range(from..self.cursor, "");

match offset > 0 {
true => self.cursor = self.cursor - (self.cursor - from),
false => self.cursor = 0,
}
Ok(())
}

fn handle_backspace(&mut self) -> io::Result<()> {
let chars_count = self.input.chars().count();
if chars_count > 0 && self.cursor > 0 {
Expand Down

0 comments on commit f41992b

Please sign in to comment.