limit_cli/tui/commands/
copy.rs1use super::{Command, CommandContext, CommandResult};
6use crate::clipboard_text;
7use crate::error::CliError;
8
9pub struct CopyCommand;
11
12impl Command for CopyCommand {
13 fn name(&self) -> &str {
14 "copy"
15 }
16
17 fn aliases(&self) -> Vec<&str> {
18 vec!["cp"]
19 }
20
21 fn description(&self) -> &str {
22 "Copy the last AI output to clipboard"
23 }
24
25 fn usage(&self) -> Vec<&str> {
26 vec!["/copy"]
27 }
28
29 fn execute(&self, _args: &str, ctx: &mut CommandContext) -> Result<CommandResult, CliError> {
30 let messages = ctx.messages.lock().unwrap();
32 let last_assistant_message = messages.iter().rev().find_map(|msg| {
33 if msg.role == limit_llm::Role::Assistant {
34 msg.content.clone()
35 } else {
36 None
37 }
38 });
39
40 drop(messages); match last_assistant_message {
43 Some(text) => match clipboard_text::copy_text_to_clipboard(&text.to_text()) {
44 Ok(()) => {
45 ctx.add_system_message("Copied latest output to clipboard.".to_string());
46 }
47 Err(err) => {
48 ctx.add_system_message(format!("Failed to copy to clipboard: {err}"));
49 }
50 },
51 None => {
52 ctx.add_system_message(
53 "`/copy` is unavailable before the first output.".to_string(),
54 );
55 }
56 }
57
58 Ok(CommandResult::Continue)
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn test_copy_command() {
68 assert_eq!(CopyCommand.name(), "copy");
69 assert!(CopyCommand.aliases().contains(&"cp"));
70 }
71}