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 => {
55            r#"xterm copy/paste behavior is controlled via X resources and selection settings.
56"#
57            .to_string()
58        }
59
60        TerminalType::Zed => r#"// Copy/paste is built into Zed
61// No additional configuration needed
62"#
63        .to_string(),
64
65        TerminalType::Warp => {
66            "# Warp has built-in copy/paste support\n# No additional configuration needed\n"
67                .to_string()
68        }
69
70        TerminalType::WindowsTerminal => r#"{
71  "copyOnSelect": true,
72  "copyFormatting": "none",
73  "actions": [
74    {
75      "command": { "action": "copy", "singleLine": false },
76      "keys": "ctrl+c"
77    },
78    {
79      "command": "paste",
80      "keys": "ctrl+v"
81    }
82  ]
83}
84"#
85        .to_string(),
86
87        TerminalType::Hyper => r#"config: {
88  copyOnSelect: true,
89  quickEdit: true,
90}
91"#
92        .to_string(),
93
94        TerminalType::Tabby => r#"terminal:
95  copyOnSelect: true
96  pasteOnMiddleClick: true
97  rightClick: menu
98"#
99        .to_string(),
100
101        TerminalType::ITerm2 => r#"Manual iTerm2 Copy/Paste Setup:
102
1031. Open iTerm2 Preferences (Cmd+,)
1042. Go to General → Selection
1053. Enable "Copy to pasteboard on selection"
1064. Go to Pointer tab
1075. Set middle-click action to "Paste from Clipboard"
1086. Under Advanced, search for "paste" to customize paste behavior
109"#
110        .to_string(),
111
112        TerminalType::VSCode => r#"VS Code Copy/Paste Configuration:
113
114Copy/paste is built-in to VS Code terminal.
115No additional configuration needed.
116
117Default shortcuts:
118  - Copy: Cmd+C (macOS) / Ctrl+C (Windows/Linux)
119  - Paste: Cmd+V (macOS) / Ctrl+V (Windows/Linux)
120
121To customize, edit settings.json:
122  "terminal.integrated.copyOnSelection": true
123"#
124        .to_string(),
125
126        TerminalType::Unknown => {
127            anyhow::bail!("Cannot generate copy/paste config for unknown terminal type");
128        }
129    };
130
131    Ok(config)
132}
133
134#[cfg(test)]
135mod tests {
136    use super::*;
137
138    #[test]
139    fn test_generate_ghostty_config() {
140        let config = generate_config(TerminalType::Ghostty).unwrap();
141        assert!(config.contains("copy-on-select"));
142        assert!(config.contains("clipboard"));
143    }
144
145    #[test]
146    fn test_generate_kitty_config() {
147        let config = generate_config(TerminalType::Kitty).unwrap();
148        assert!(config.contains("copy_on_select"));
149        assert!(config.contains("bracketed_paste"));
150    }
151
152    #[test]
153    fn test_generate_alacritty_config() {
154        let config = generate_config(TerminalType::Alacritty).unwrap();
155        assert!(config.contains("save_to_clipboard"));
156        assert!(config.contains("PasteSelection"));
157    }
158
159    #[test]
160    fn test_generate_windows_terminal_config() {
161        let config = generate_config(TerminalType::WindowsTerminal).unwrap();
162        assert!(config.contains("copyOnSelect"));
163        assert!(config.contains("paste"));
164    }
165
166    #[test]
167    fn test_generate_iterm2_instructions() {
168        let config = generate_config(TerminalType::ITerm2).unwrap();
169        assert!(config.contains("iTerm2"));
170        assert!(config.contains("Preferences"));
171    }
172
173    #[test]
174    fn test_generate_vscode_instructions() {
175        let config = generate_config(TerminalType::VSCode).unwrap();
176        assert!(config.contains("VS Code"));
177        assert!(config.contains("copyOnSelection"));
178    }
179
180    #[test]
181    fn test_unknown_terminal_error() {
182        let result = generate_config(TerminalType::Unknown);
183        result.unwrap_err();
184    }
185
186    #[test]
187    fn test_generate_config() {
188        // This test exists for backward compatibility with the stub
189        generate_config(TerminalType::Kitty).unwrap();
190    }
191}