summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/editor.rs10
-rw-r--r--src/main.rs1
-rw-r--r--src/render.rs3
-rw-r--r--src/repl.rs31
-rw-r--r--src/utils.rs19
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}"))
+}