Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,35 @@ export function Prompt(props: PromptProps) {
}
// If no image, let the default paste behavior continue
}
// Handle copy (Ctrl+Shift+C) - copy selected text to clipboard
if (keybind.match("input_copy", e)) {
if (input.hasSelection()) {
const selectedText = input.getSelectedText()
if (selectedText) {
await Clipboard.copy(selectedText).catch((error) => {
console.error(`Failed to copy selected text to clipboard: ${error}`)
})
e.preventDefault()
}
}
return
}
// Handle cut (Ctrl+Shift+X) - copy selected text and delete it
if (keybind.match("input_cut", e)) {
if (input.hasSelection()) {
const selectedText = input.getSelectedText()
if (selectedText) {
await Clipboard.copy(selectedText).catch((error) => {
console.error(`Failed to copy selected text to clipboard: ${error}`)
})
// Delete the selected text using the public deleteChar() method
// which internally calls deleteSelectedText() when there's a selection
input.deleteChar()
e.preventDefault()
}
}
return
}
if (keybind.match("input_clear", e) && store.prompt.input !== "") {
input.clear()
input.extmarks.clear()
Expand Down
2 changes: 2 additions & 0 deletions packages/opencode/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,8 @@ export namespace Config {
variant_cycle: z.string().optional().default("ctrl+t").describe("Cycle model variants"),
input_clear: z.string().optional().default("ctrl+c").describe("Clear input field"),
input_paste: z.string().optional().default("ctrl+v").describe("Paste from clipboard"),
input_copy: z.string().optional().default("ctrl+insert").describe("Copy selected text from input"),
input_cut: z.string().optional().default("shift+delete").describe("Cut selected text from input"),
input_submit: z.string().optional().default("return").describe("Submit input"),
input_newline: z
.string()
Expand Down
8 changes: 8 additions & 0 deletions packages/sdk/js/src/v2/gen/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,14 @@ export type KeybindsConfig = {
* Paste from clipboard
*/
input_paste?: string
/**
* Copy selected text from input
*/
input_copy?: string
/**
* Cut selected text from input
*/
input_cut?: string
/**
* Submit input
*/
Expand Down
10 changes: 10 additions & 0 deletions packages/sdk/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -8305,6 +8305,16 @@
"default": "ctrl+v",
"type": "string"
},
"input_copy": {
"description": "Copy selected text from input",
"default": "ctrl+insert",
"type": "string"
},
"input_cut": {
"description": "Cut selected text from input",
"default": "shift+delete",
"type": "string"
},
"input_submit": {
"description": "Submit input",
"default": "return",
Expand Down