Skip to main content

vtcode_core/terminal_setup/features/
copy_paste.rs

1//! Copy/paste integration feature configuration generator.
2//!
3//! Generates terminal-specific configuration for enhanced copy/paste features:
4//! - Copy-on-select (automatically copy selected text)
5//! - Bracketed paste mode (safe paste with escape sequences)
6//! - Middle-click paste integration
7
8use crate::terminal_setup::detector::TerminalType;
9use anyhow::Result;
10
11/// Generate copy/paste configuration for the specified terminal
12pub fn generate_config(terminal: TerminalType) -> Result<String> {
13    let config = match terminal {
14        TerminalType::Ghostty => r#"# Copy on select
15copy-on-select = true
16
17# Clipboard integration
18clipboard-read = allow
19clipboard-write = allow
20"#
21        .to_string(),
22
23        TerminalType::Kitty => r#"# Enhanced copy/paste
24enable_bracketed_paste yes
25copy_on_select clipboard
26
27# Clipboard integration
28clipboard_control write-clipboard write-primary read-clipboard read-primary
29"#
30        .to_string(),
31
32        TerminalType::Alacritty => r#"[selection]
33save_to_clipboard = true
34
35[mouse]
36# Middle-click paste
37bindings = [
38    { mouse = "Middle", action = "PasteSelection" }
39]
40"#
41        .to_string(),
42
43        TerminalType::WezTerm => r#"-- WezTerm copy/paste is built-in.
44-- Optional:
45--   enable_kitty_keyboard = true
46"#
47        .to_string(),
48
49        TerminalType::TerminalApp => r#"Terminal.app copy/paste is built-in.
50Configure profile behavior in Terminal → Settings.
51"#
52        .to_string(),
53
54        TerminalType::Xterm => r#"xterm copy/paste behavior is controlled via X resources and selection settings.
55"#
56        .to_string(),
57
58        TerminalType::Zed => r#"// Copy/paste is built into Zed
59// No additional configuration needed
60"#
61        .to_string(),
62
63        TerminalType::Warp => {
64            "# Warp has built-in copy/paste support\n# No additional configuration needed\n".to_string()
65        }
66
67        TerminalType::WindowsTerminal => r#"{
68  "copyOnSelect": true,
69  "copyFormatting": "none",
70  "actions": [
71    {
72      "command": { "action": "copy", "singleLine": false },
73      "keys": "ctrl+c"
74    },
75    {
76      "command": "paste",
77      "keys": "ctrl+v"
78    }
79  ]
80}
81"#
82        .to_string(),
83
84        TerminalType::Hyper => r#"config: {
85  copyOnSelect: true,
86  quickEdit: true,
87}
88"#
89        .to_string(),
90
91        TerminalType::Tabby => r#"terminal:
92  copyOnSelect: true
93  pasteOnMiddleClick: true
94  rightClick: menu
95"#
96        .to_string(),
97
98        TerminalType::ITerm2 => r#"Manual iTerm2 Copy/Paste Setup:
99
1001. Open iTerm2 Preferences (Cmd+,)
1012. Go to General → Selection
1023. Enable "Copy to pasteboard on selection"
1034. Go to Pointer tab
1045. Set middle-click action to "Paste from Clipboard"
1056. Under Advanced, search for "paste" to customize paste behavior
106"#
107        .to_string(),
108
109        TerminalType::VSCode => r#"VS Code Copy/Paste Configuration:
110
111Copy/paste is built-in to VS Code terminal.
112No additional configuration needed.
113
114Default shortcuts:
115  - Copy: Cmd+C (macOS) / Ctrl+C (Windows/Linux)
116  - Paste: Cmd+V (macOS) / Ctrl+V (Windows/Linux)
117
118To customize, edit settings.json:
119  "terminal.integrated.copyOnSelection": true
120"#
121        .to_string(),
122
123        TerminalType::Unknown => {
124            anyhow::bail!("Cannot generate copy/paste config for unknown terminal type");
125        }
126    };
127
128    Ok(config)
129}
130
131#[cfg(test)]
132mod tests {
133    use super::*;
134
135    #[test]
136    fn test_generate_ghostty_config() {
137        let config = generate_config(TerminalType::Ghostty).unwrap();
138        assert!(config.contains("copy-on-select"));
139        assert!(config.contains("clipboard"));
140    }
141
142    #[test]
143    fn test_generate_kitty_config() {
144        let config = generate_config(TerminalType::Kitty).unwrap();
145        assert!(config.contains("copy_on_select"));
146        assert!(config.contains("bracketed_paste"));
147    }
148
149    #[test]
150    fn test_generate_alacritty_config() {
151        let config = generate_config(TerminalType::Alacritty).unwrap();
152        assert!(config.contains("save_to_clipboard"));
153        assert!(config.contains("PasteSelection"));
154    }
155
156    #[test]
157    fn test_generate_windows_terminal_config() {
158        let config = generate_config(TerminalType::WindowsTerminal).unwrap();
159        assert!(config.contains("copyOnSelect"));
160        assert!(config.contains("paste"));
161    }
162
163    #[test]
164    fn test_generate_iterm2_instructions() {
165        let config = generate_config(TerminalType::ITerm2).unwrap();
166        assert!(config.contains("iTerm2"));
167        assert!(config.contains("Preferences"));
168    }
169
170    #[test]
171    fn test_generate_vscode_instructions() {
172        let config = generate_config(TerminalType::VSCode).unwrap();
173        assert!(config.contains("VS Code"));
174        assert!(config.contains("copyOnSelection"));
175    }
176
177    #[test]
178    fn test_unknown_terminal_error() {
179        let result = generate_config(TerminalType::Unknown);
180        result.unwrap_err();
181    }
182
183    #[test]
184    fn test_generate_config() {
185        // This test exists for backward compatibility with the stub
186        generate_config(TerminalType::Kitty).unwrap();
187    }
188}