Skip to main content

limit_cli/tui/commands/
copy.rs

1//! Copy command - copies output to clipboard
2//!
3//! Provides the /copy command for copying the last AI output to system clipboard.
4
5use super::{Command, CommandContext, CommandResult};
6use crate::clipboard_text;
7use crate::error::CliError;
8
9/// Copy command - copies last output to clipboard
10pub 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        // Get last AI output from messages
31        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); // Release lock before clipboard operation
41
42        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}