summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsigoden <sigoden@gmail.com>2023-05-04 22:42:50 +0800
committerGitHub <noreply@github.com>2023-05-04 22:42:50 +0800
commit00ce1575715329a21726a506b13c0c2aef7f3f82 (patch)
tree766da2bf873b8f37936e1f5a385fc19d191bc193
parentcf03952c7bd44a3ad94a675b846cdfafb2af1c75 (diff)
downloadaichat-00ce1575715329a21726a506b13c0c2aef7f3f82.tar.gz
feat: add `.copy` command (#119)
-rw-r--r--Cargo.lock228
-rw-r--r--Cargo.toml2
-rw-r--r--src/config/mod.rs17
-rw-r--r--src/repl/handler.rs10
-rw-r--r--src/repl/mod.rs6
-rw-r--r--src/utils/mod.rs6
6 files changed, 61 insertions, 208 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 077bdb5..ae935a0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -22,6 +22,7 @@ name = "aichat"
version = "0.8.0"
dependencies = [
"anyhow",
+ "arboard",
"atty",
"base64",
"bincode",
@@ -29,7 +30,6 @@ dependencies = [
"bytes",
"chrono",
"clap",
- "copypasta",
"crossbeam",
"crossterm 0.26.1",
"ctrlc",
@@ -118,6 +118,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
[[package]]
+name = "arboard"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6041616acea41d67c4a984709ddab1587fd0b10efe5cc563fee954d2f011854"
+dependencies = [
+ "clipboard-win",
+ "log",
+ "objc",
+ "objc-foundation",
+ "objc_id",
+ "once_cell",
+ "parking_lot",
+ "thiserror",
+ "winapi",
+ "x11rb",
+]
+
+[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -277,11 +295,12 @@ checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1"
[[package]]
name = "clipboard-win"
-version = "3.1.1"
+version = "4.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fdf5e01086b6be750428ba4a40619f847eb2e95756eee84b18e06e5f0b50342"
+checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362"
dependencies = [
- "lazy-bytes-cast",
+ "error-code",
+ "str-buf",
"winapi",
]
@@ -302,20 +321,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
-name = "copypasta"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "133fc8675ee3a4ec9aa513584deda9aa0faeda3586b87f7f0f2ba082c66fb172"
-dependencies = [
- "clipboard-win",
- "objc",
- "objc-foundation",
- "objc_id",
- "smithay-clipboard",
- "x11-clipboard",
-]
-
-[[package]]
name = "core-foundation"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -524,21 +529,6 @@ dependencies = [
]
[[package]]
-name = "dlib"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794"
-dependencies = [
- "libloading",
-]
-
-[[package]]
-name = "downcast-rs"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
-
-[[package]]
name = "dyn-clone"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -581,6 +571,16 @@ dependencies = [
]
[[package]]
+name = "error-code"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21"
+dependencies = [
+ "libc",
+ "str-buf",
+]
+
+[[package]]
name = "eventsource-stream"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -959,12 +959,6 @@ dependencies = [
]
[[package]]
-name = "lazy-bytes-cast"
-version = "5.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10257499f089cd156ad82d0a9cd57d9501fa2c989068992a97eb3c27836f206b"
-
-[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -977,16 +971,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317"
[[package]]
-name = "libloading"
-version = "0.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
-dependencies = [
- "cfg-if",
- "winapi",
-]
-
-[[package]]
name = "link-cplusplus"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1036,15 +1020,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
-name = "memmap2"
-version = "0.5.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327"
-dependencies = [
- "libc",
-]
-
-[[package]]
name = "memoffset"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1514,12 +1489,6 @@ dependencies = [
]
[[package]]
-name = "scoped-tls"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
-
-[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1666,34 +1635,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
-name = "smithay-client-toolkit"
-version = "0.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f307c47d32d2715eb2e0ece5589057820e0e5e70d07c247d1063e844e107f454"
-dependencies = [
- "bitflags",
- "dlib",
- "lazy_static",
- "log",
- "memmap2",
- "nix 0.24.3",
- "pkg-config",
- "wayland-client",
- "wayland-cursor",
- "wayland-protocols",
-]
-
-[[package]]
-name = "smithay-clipboard"
-version = "0.6.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8"
-dependencies = [
- "smithay-client-toolkit",
- "wayland-client",
-]
-
-[[package]]
name = "socket2"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1716,6 +1657,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
+name = "str-buf"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0"
+
+[[package]]
name = "strip-ansi-escapes"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2140,79 +2087,6 @@ dependencies = [
]
[[package]]
-name = "wayland-client"
-version = "0.29.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715"
-dependencies = [
- "bitflags",
- "downcast-rs",
- "libc",
- "nix 0.24.3",
- "scoped-tls",
- "wayland-commons",
- "wayland-scanner",
- "wayland-sys",
-]
-
-[[package]]
-name = "wayland-commons"
-version = "0.29.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902"
-dependencies = [
- "nix 0.24.3",
- "once_cell",
- "smallvec",
- "wayland-sys",
-]
-
-[[package]]
-name = "wayland-cursor"
-version = "0.29.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661"
-dependencies = [
- "nix 0.24.3",
- "wayland-client",
- "xcursor",
-]
-
-[[package]]
-name = "wayland-protocols"
-version = "0.29.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6"
-dependencies = [
- "bitflags",
- "wayland-client",
- "wayland-commons",
- "wayland-scanner",
-]
-
-[[package]]
-name = "wayland-scanner"
-version = "0.29.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53"
-dependencies = [
- "proc-macro2",
- "quote",
- "xml-rs",
-]
-
-[[package]]
-name = "wayland-sys"
-version = "0.29.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4"
-dependencies = [
- "dlib",
- "lazy_static",
- "pkg-config",
-]
-
-[[package]]
name = "web-sys"
version = "0.3.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2447,15 +2321,6 @@ dependencies = [
]
[[package]]
-name = "x11-clipboard"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "980b9aa9226c3b7de8e2adb11bf20124327c054e0e5812d2aac0b5b5a87e7464"
-dependencies = [
- "x11rb",
-]
-
-[[package]]
name = "x11rb"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2476,18 +2341,3 @@ checksum = "56b245751c0ac9db0e006dc812031482784e434630205a93c73cfefcaabeac67"
dependencies = [
"nix 0.24.3",
]
-
-[[package]]
-name = "xcursor"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7"
-dependencies = [
- "nom",
-]
-
-[[package]]
-name = "xml-rs"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "374b609fb36c36ce3501094dc0548f7df5d8d102224b65bc59812e4a5425d571"
diff --git a/Cargo.toml b/Cargo.toml
index 834b485..7c1ee7b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -38,7 +38,7 @@ base64 = "0.21.0"
rustc-hash = "1.1.0"
bstr = "1.3.0"
nu-ansi-term = "0.47.0"
-copypasta = "0.8.2"
+arboard = { version = "3.2.0", default-features = false }
[dependencies.reqwest]
version = "0.11.14"
diff --git a/src/config/mod.rs b/src/config/mod.rs
index 021d2c1..900f129 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -10,7 +10,6 @@ use crate::config::message::num_tokens_from_messages;
use crate::utils::{mask_text, now};
use anyhow::{anyhow, bail, Context, Result};
-use copypasta::{ClipboardContext, ClipboardProvider};
use inquire::{Confirm, Text};
use parking_lot::RwLock;
use serde::Deserialize;
@@ -71,7 +70,7 @@ pub struct Config {
pub light_theme: bool,
/// Set a timeout in seconds for connect to gpt
pub connect_timeout: usize,
- /// Automatically copy the last message output to the clipboard
+ /// Automatically copy the last output to the clipboard
pub auto_copy: bool,
/// Predefined roles
#[serde(skip)]
@@ -173,20 +172,6 @@ impl Config {
Ok(path)
}
- pub fn copy_message(&self, output: &str) -> Result<()> {
- if self.auto_copy {
- match ClipboardContext::new() {
- Ok(mut ctx) => {
- ctx.set_contents(output.to_string()).map_err(|err| {
- anyhow!("Error: Unable to the last message output to clipboard, {err}")
- })?;
- }
- Err(_) => bail!("Error: Unable to access clipboard context."),
- }
- }
- Ok(())
- }
-
pub fn save_message(&self, input: &str, output: &str) -> Result<()> {
if !self.save {
return Ok(());
diff --git a/src/repl/handler.rs b/src/repl/handler.rs
index c38f607..495413c 100644
--- a/src/repl/handler.rs
+++ b/src/repl/handler.rs
@@ -2,6 +2,7 @@ use crate::client::ChatGptClient;
use crate::config::SharedConfig;
use crate::print_now;
use crate::render::render_stream;
+use crate::utils::copy;
use super::abort::SharedAbortSignal;
@@ -20,6 +21,7 @@ pub enum ReplCmd {
ViewInfo,
StartConversation,
EndConversatoin,
+ Copy,
}
pub struct ReplCmdHandler {
@@ -64,7 +66,9 @@ impl ReplCmdHandler {
wg.wait();
let buffer = ret?;
self.config.read().save_message(&input, &buffer)?;
- let _ = self.config.read().copy_message(&buffer);
+ if self.config.read().auto_copy {
+ let _ = copy(&buffer);
+ }
self.config.write().save_conversation(&input, &buffer)?;
*self.reply.borrow_mut() = buffer;
}
@@ -100,6 +104,10 @@ impl ReplCmdHandler {
self.config.write().end_conversation();
print_now!("\n");
}
+ ReplCmd::Copy => {
+ copy(&self.reply.borrow()).with_context(|| "Failed to copy the last output")?;
+ print_now!("\n");
+ }
}
Ok(())
}
diff --git a/src/repl/mod.rs b/src/repl/mod.rs
index 6bedfa3..8f3d184 100644
--- a/src/repl/mod.rs
+++ b/src/repl/mod.rs
@@ -19,7 +19,7 @@ use reedline::Signal;
use std::borrow::Cow;
use std::sync::Arc;
-pub const REPL_COMMANDS: [(&str, &str); 12] = [
+pub const REPL_COMMANDS: [(&str, &str); 13] = [
(".info", "Print system-wide information"),
(".set", "Modify the configuration temporarily"),
(".model", "Choose a model"),
@@ -28,6 +28,7 @@ pub const REPL_COMMANDS: [(&str, &str); 12] = [
(".clear role", "Clear the currently selected role"),
(".conversation", "Start a conversation."),
(".clear conversation", "End current conversation."),
+ (".copy", "Copy the last output to the clipboard"),
(".history", "Print the history"),
(".clear history", "Clear the history"),
(".help", "Print this help message"),
@@ -138,6 +139,9 @@ impl Repl {
".conversation" => {
handler.handle(ReplCmd::StartConversation)?;
}
+ ".copy" => {
+ handler.handle(ReplCmd::Copy)?;
+ }
_ => dump_unknown_command(),
},
None => {
diff --git a/src/utils/mod.rs b/src/utils/mod.rs
index 64fc01c..ec57fed 100644
--- a/src/utils/mod.rs
+++ b/src/utils/mod.rs
@@ -2,6 +2,7 @@ mod tiktoken;
pub use self::tiktoken::{cl100k_base_singleton, count_tokens, text_to_tokens, tokens_to_text};
+use arboard::Clipboard;
use chrono::prelude::*;
use crossterm::style::{Color, Stylize};
use std::io::{stdout, Write};
@@ -35,6 +36,11 @@ pub fn mask_text(text: &str, head: usize, tail: usize) -> String {
format!("{}...{}", &text[0..head], &text[text.len() - tail..])
}
+pub fn copy(src: &str) -> Result<(), arboard::Error> {
+ let mut clipboard = Clipboard::new()?;
+ clipboard.set_text(src)
+}
+
#[cfg(test)]
mod tests {
use super::*;