diff --git a/src/app.rs b/src/app.rs index c0f8e95..4ea4c2b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -184,8 +184,11 @@ impl App { } } KeyCode::Backspace => { - self.data.input_cursor = self.data.input_cursor.saturating_sub(1); - self.data.input.pop(); + if self.data.input_cursor > 0 { + let idx = self.data.input_cursor - 1; + self.data.input.remove(idx); + self.data.input_cursor = idx; + } } _ => {} } @@ -244,7 +247,7 @@ impl App { } pub fn on_right(&mut self) { - if self.data.input_cursor < self.data.input.width() { + if self.data.input_cursor < self.data.input.len() { self.data.input_cursor += 1; } } diff --git a/src/ui.rs b/src/ui.rs index 4892793..6a61aa0 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -66,15 +66,25 @@ fn draw_chat(f: &mut Frame, app: &mut App, area: Rect) { lines.push(String::new()); } match c { - '\n' => lines.push(String::new()), + '\n' => { + lines.last_mut().unwrap().push('\n'); + lines.push(String::new()) + } _ => lines.last_mut().unwrap().push(c), } lines }); - let chars_since_newline = match lines.last() { - Some(last) => last.len(), - None => 0, - }; + // chars since newline on `cursor_y` line + let mut cursor_x = app.data.input_cursor; + // line selected by `app.data.input_cursor` + let mut cursor_y = 0; + for string in &lines { + cursor_y += 1; + match string.len().cmp(&cursor_x) { + std::cmp::Ordering::Less => cursor_x -= string.len(), + _ => break, + }; + } let num_input_lines = lines.len().max(1); let input: Vec = lines.into_iter().map(Spans::from).collect(); let extra_cursor_line = if app.data.input_cursor > 0 && app.data.input_cursor % text_width == 0 @@ -83,7 +93,6 @@ fn draw_chat(f: &mut Frame, app: &mut App, area: Rect) { } else { 0 }; - let chunks = Layout::default() .constraints( [ @@ -102,9 +111,9 @@ fn draw_chat(f: &mut Frame, app: &mut App, area: Rect) { f.render_widget(input, chunks[1]); f.set_cursor( // Put cursor past the end of the input text - chunks[1].x + ((chars_since_newline as u16) % text_width as u16) + 1, + chunks[1].x + ((cursor_x as u16) % text_width as u16) + 1, // Move one line down, from the border to the input line - chunks[1].y + (chars_since_newline as u16 / (text_width as u16)) + num_input_lines as u16, + chunks[1].y + (cursor_x as u16 / (text_width as u16)) + cursor_y.max(1) as u16, ); }