Skip to content

Commit c99ded1

Browse files
sinelawclaude
andcommitted
Add terminal paste support (Ctrl+V)
Intercept paste keybinding when terminal is focused and send clipboard contents to the terminal as a single batch instead of forwarding individual key events. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 4c4b365 commit c99ded1

File tree

4 files changed

+22
-1
lines changed

4 files changed

+22
-1
lines changed

keymaps/default.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,6 +1518,14 @@
15181518
"action": "toggle_keyboard_capture",
15191519
"args": {},
15201520
"when": "terminal"
1521+
},
1522+
{
1523+
"comment": "Terminal context - Paste clipboard contents (Ctrl+V)",
1524+
"key": "v",
1525+
"modifiers": ["ctrl"],
1526+
"action": "terminal_paste",
1527+
"args": {},
1528+
"when": "terminal"
15211529
}
15221530
]
15231531
}

src/app/input.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,6 +1608,14 @@ impl Editor {
16081608
}
16091609
}
16101610
}
1611+
Action::TerminalPaste => {
1612+
// Paste clipboard contents into terminal as a single batch
1613+
if self.terminal_mode {
1614+
if let Some(text) = self.clipboard.paste() {
1615+
self.send_terminal_input(text.as_bytes());
1616+
}
1617+
}
1618+
}
16111619
Action::PromptConfirm => {
16121620
// Handle prompt confirmation (same logic as in handle_key)
16131621
if let Some((input, prompt_type, selected_index)) = self.confirm_prompt() {

src/input/actions.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1743,7 +1743,8 @@ pub fn action_to_events(
17431743
| Action::CloseTerminal
17441744
| Action::FocusTerminal
17451745
| Action::TerminalEscape
1746-
| Action::ToggleKeyboardCapture => return None,
1746+
| Action::ToggleKeyboardCapture
1747+
| Action::TerminalPaste => return None,
17471748

17481749
// Block/rectangular selection actions
17491750
Action::BlockSelectLeft => {

src/input/keybindings.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ pub enum Action {
472472
FocusTerminal, // Focus the terminal buffer (if viewing terminal, focus input)
473473
TerminalEscape, // Escape from terminal mode back to editor
474474
ToggleKeyboardCapture, // Toggle keyboard capture mode (all keys go to terminal)
475+
TerminalPaste, // Paste clipboard contents into terminal as a single batch
475476

476477
// No-op
477478
None,
@@ -755,6 +756,7 @@ impl Action {
755756
"focus_terminal" => Some(Action::FocusTerminal),
756757
"terminal_escape" => Some(Action::TerminalEscape),
757758
"toggle_keyboard_capture" => Some(Action::ToggleKeyboardCapture),
759+
"terminal_paste" => Some(Action::TerminalPaste),
758760

759761
_ => None,
760762
}
@@ -994,6 +996,7 @@ impl KeybindingResolver {
994996
| Action::ToggleKeyboardCapture
995997
| Action::OpenTerminal
996998
| Action::CloseTerminal
999+
| Action::TerminalPaste
9971000
// File explorer
9981001
| Action::ToggleFileExplorer
9991002
)
@@ -1657,6 +1660,7 @@ impl KeybindingResolver {
16571660
Action::FocusTerminal => "Focus terminal".to_string(),
16581661
Action::TerminalEscape => "Exit terminal mode".to_string(),
16591662
Action::ToggleKeyboardCapture => "Toggle keyboard capture (terminal)".to_string(),
1663+
Action::TerminalPaste => "Paste into terminal".to_string(),
16601664
Action::None => "No action".to_string(),
16611665
}
16621666
}

0 commit comments

Comments
 (0)