diff options
| author | sigoden <sigoden@gmail.com> | 2023-03-05 19:16:41 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-05 19:16:41 +0800 |
| commit | aadffb17a3cbbfc5e3c0dad4c8587eff79aaae9b (patch) | |
| tree | 9f892583dbca7ea8b10d0a1d305ad3b8920df61b /src/term.rs | |
| parent | 625f0343cbdc5a7bf11b649b98e239d9dcf53f6e (diff) | |
| download | aichat-aadffb17a3cbbfc5e3c0dad4c8587eff79aaae9b.tar.gz | |
feat: repl command replaces `.editor` with `.multiline` (#18)
You can use `.multiline` command to put multiline content
```
〉.multiline {
::: abc
::: cdf
::: }
```
It's much easier than `.editor`.
Diffstat (limited to 'src/term.rs')
| -rw-r--r-- | src/term.rs | 104 |
1 files changed, 1 insertions, 103 deletions
diff --git a/src/term.rs b/src/term.rs index 0d2780e..05eedde 100644 --- a/src/term.rs +++ b/src/term.rs @@ -3,112 +3,10 @@ use std::io::{self, Stdout, Write}; use anyhow::Result; use crossterm::{ - cursor, - event::{self, Event, KeyCode, KeyModifiers}, - queue, style, + cursor, queue, style, terminal::{self, disable_raw_mode, enable_raw_mode, ClearType}, }; -use crate::utils::paste; - -pub fn edit() -> Result<String> { - enable_raw_mode()?; - let mut stdout = io::stdout(); - - let ret = edit_inner(&mut stdout); - - // restore terminal - disable_raw_mode()?; - - ret -} - -fn edit_inner(writer: &mut Stdout) -> Result<String> { - let mut session = Session::new(writer); - - loop { - let evt = event::read()?; - if let Event::Key(key) = evt { - match key.code { - KeyCode::Char('c') if key.modifiers == KeyModifiers::CONTROL => { - // quit - return Ok(String::new()); - } - KeyCode::Char('d') if key.modifiers == KeyModifiers::CONTROL => { - // submit - return Ok(session.buffer); - } - KeyCode::Char('v') if key.modifiers == KeyModifiers::CONTROL => { - let content = paste()?; - session.push_str(&content)?; - } - KeyCode::Char(c) - if matches!(key.modifiers, KeyModifiers::NONE | KeyModifiers::SHIFT) => - { - session.push(c)?; - } - KeyCode::Enter => { - session.push('\n')?; - } - _ => {} - } - } - session.flush()?; - } -} - -struct Session<'a, T: Write> { - writer: &'a mut T, - buffer: String, - dirty: bool, -} - -impl<'a, T: Write> Session<'a, T> { - fn new<'b: 'a>(writer: &'b mut T) -> Self { - Self { - buffer: String::new(), - writer, - dirty: false, - } - } - fn push(&mut self, ch: char) -> io::Result<()> { - if ch == '\n' { - self.new_line()?; - } else { - queue!(self.writer, style::Print(ch))?; - } - self.buffer.push(ch); - self.dirty = true; - Ok(()) - } - fn push_str(&mut self, text: &str) -> io::Result<()> { - for line in text.lines() { - if !line.is_empty() { - queue!(self.writer, style::Print(line))?; - } - self.new_line()?; - } - - Ok(()) - } - fn new_line(&mut self) -> io::Result<()> { - let (_, y) = cursor::position()?; - let (_, h) = terminal::size()?; - if y == h - 1 { - queue!(self.writer, terminal::ScrollUp(1), cursor::MoveTo(0, y))?; - } else { - queue!(self.writer, cursor::MoveToNextLine(1))?; - } - Ok(()) - } - fn flush(&mut self) -> io::Result<()> { - if self.dirty { - return self.writer.flush(); - } - Ok(()) - } -} - pub fn clear_screen(keep_lines: u16) -> Result<()> { enable_raw_mode()?; let mut stdout = io::stdout(); |
