diff options
| -rw-r--r-- | src/editor.rs | 10 | ||||
| -rw-r--r-- | src/main.rs | 1 | ||||
| -rw-r--r-- | src/render.rs | 3 | ||||
| -rw-r--r-- | src/repl.rs | 31 | ||||
| -rw-r--r-- | src/utils.rs | 19 |
5 files changed, 44 insertions, 20 deletions
diff --git a/src/editor.rs b/src/editor.rs index 8355c01..1da71a1 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -1,7 +1,6 @@ use std::io::{self, Stdout, Write}; -use anyhow::{anyhow, Result}; -use copypasta::{ClipboardContext, ClipboardProvider}; +use anyhow::Result; use crossterm::{ cursor, @@ -10,6 +9,8 @@ use crossterm::{ terminal::{self, disable_raw_mode, enable_raw_mode}, }; +use crate::utils::paste; + pub fn edit() -> Result<String> { enable_raw_mode()?; let mut stdout = io::stdout(); @@ -107,8 +108,3 @@ impl<'a, T: Write> Session<'a, T> { Ok(()) } } - -fn paste() -> Result<String> { - let mut ctx = ClipboardContext::new().map_err(|err| anyhow!("{err}"))?; - ctx.get_contents().map_err(|err| anyhow!("{err}")) -} diff --git a/src/main.rs b/src/main.rs index add1487..9cb360d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ mod config; mod editor; mod render; mod repl; +mod utils; use std::sync::Arc; use std::{io::stdout, process::exit}; diff --git a/src/render.rs b/src/render.rs index b049051..f44283c 100644 --- a/src/render.rs +++ b/src/render.rs @@ -1,3 +1,4 @@ +use crate::{repl::RenderStreamEvent, utils::dump}; use anyhow::Result; use crossbeam::channel::Receiver; use mdcat::{ @@ -12,8 +13,6 @@ use std::sync::{ }; use syntect::parsing::SyntaxSet; -use crate::repl::{dump, RenderStreamEvent}; - pub fn render_stream( rx: Receiver<RenderStreamEvent>, ctrlc: Arc<AtomicBool>, diff --git a/src/repl.rs b/src/repl.rs index 127ec72..81a5474 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -2,6 +2,7 @@ use crate::client::ChatGptClient; use crate::config::{Config, Role}; use crate::editor; use crate::render::{self, MarkdownRender}; +use crate::utils::{copy, dump}; use anyhow::{anyhow, Result}; use crossbeam::channel::{unbounded, Sender}; use crossbeam::sync::WaitGroup; @@ -12,15 +13,15 @@ use reedline::{ }; use std::cell::RefCell; use std::fs::File; -use std::io::{stdout, Write}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::thread::spawn; -const REPL_COMMANDS: [(&str, &str); 8] = [ +const REPL_COMMANDS: [(&str, &str); 9] = [ (".clear", "Clear the screen"), (".clear-history", "Clear the history"), (".clear-role", "Clear the role status"), + (".copy", "Copy last reply message"), (".editor", "Enter multiline editor"), (".exit", "Exit the REPL"), (".help", "Print this help message"), @@ -140,6 +141,15 @@ impl Repl { dump("", 1); handler.handle(ReplCmd::Input(content))?; } + ".copy" => { + let reply = handler.get_reply(); + if reply.is_empty() { + dump("No reply messages that can be copied", 1) + } else { + copy(&reply)?; + dump("Pasted", 1); + } + } _ => dump_unknown_command(), } } else { @@ -200,7 +210,7 @@ pub struct ReplCmdHandler { struct ReplCmdHandlerState { prompt: String, - output: String, + reply: String, save_file: Option<File>, } @@ -217,7 +227,7 @@ impl ReplCmdHandler { let state = RefCell::new(ReplCmdHandlerState { prompt, save_file, - output: String::new(), + reply: String::new(), }); Ok(Self { client, @@ -231,7 +241,7 @@ impl ReplCmdHandler { match cmd { ReplCmd::Input(input) => { if input.is_empty() { - self.state.borrow_mut().output.clear(); + self.state.borrow_mut().reply.clear(); return Ok(()); } let prompt = self.state.borrow().prompt.to_string(); @@ -261,7 +271,7 @@ impl ReplCmdHandler { &receiver.output, ); wg.wait(); - self.state.borrow_mut().output = receiver.output; + self.state.borrow_mut().reply = receiver.output; } ReplCmd::SetRole(name) => match self.config.find_role(&name) { Some(v) => { @@ -278,6 +288,10 @@ impl ReplCmdHandler { } Ok(()) } + + fn get_reply(&self) -> String { + self.state.borrow().reply.to_string() + } } pub struct ReplyReceiver { @@ -322,11 +336,6 @@ pub enum RenderStreamEvent { Done, } -pub fn dump<T: ToString>(text: T, newlines: usize) { - print!("{}{}", text.to_string(), "\n".repeat(newlines)); - let _ = stdout().flush(); -} - enum ReplCmd { UnsetRole, Input(String), diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..cb5d1f9 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,19 @@ +use anyhow::{anyhow, Result}; +use copypasta::{ClipboardContext, ClipboardProvider}; +use std::io::{stdout, Write}; + +pub fn dump<T: ToString>(text: T, newlines: usize) { + print!("{}{}", text.to_string(), "\n".repeat(newlines)); + let _ = stdout().flush(); +} + +pub fn copy(src: &str) -> Result<()> { + let mut ctx = ClipboardContext::new().map_err(|err| anyhow!("{err}"))?; + ctx.set_contents(src.to_string()) + .map_err(|err| anyhow!("{err}")) +} + +pub fn paste() -> Result<String> { + let mut ctx = ClipboardContext::new().map_err(|err| anyhow!("{err}"))?; + ctx.get_contents().map_err(|err| anyhow!("{err}")) +} |
