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
1 change: 1 addition & 0 deletions packages/opencode/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ export namespace Config {
agent_cycle: z.string().optional().default("tab").describe("Next agent"),
agent_cycle_reverse: z.string().optional().default("shift+tab").describe("Previous agent"),
input_clear: z.string().optional().default("ctrl+c").describe("Clear input field"),
input_copy: z.string().optional().default("ctrl+shift+c").describe("Copy input to clipboard"),
input_paste: z.string().optional().default("ctrl+v").describe("Paste from clipboard"),
input_submit: z.string().optional().default("enter").describe("Submit input"),
input_newline: z.string().optional().default("shift+enter,ctrl+j").describe("Insert newline in input"),
Expand Down
3 changes: 3 additions & 0 deletions packages/sdk/go/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -1702,6 +1702,8 @@ type KeybindsConfig struct {
FileSearch string `json:"file_search,required"`
// Clear input field
InputClear string `json:"input_clear,required"`
// Copy input to clipboard
InputCopy string `json:"input_copy,required"`
// Insert newline in input
InputNewline string `json:"input_newline,required"`
// Paste from clipboard
Expand Down Expand Up @@ -1792,6 +1794,7 @@ type keybindsConfigJSON struct {
FileList apijson.Field
FileSearch apijson.Field
InputClear apijson.Field
InputCopy apijson.Field
InputNewline apijson.Field
InputPaste apijson.Field
InputSubmit apijson.Field
Expand Down
4 changes: 4 additions & 0 deletions packages/sdk/js/src/gen/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,10 @@ export type KeybindsConfig = {
* Clear input field
*/
input_clear: string
/**
* Copy input to clipboard
*/
input_copy: string
/**
* Paste from clipboard
*/
Expand Down
6 changes: 6 additions & 0 deletions packages/tui/internal/commands/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ const (
FileDiffToggleCommand CommandName = "file_diff_toggle"
ProjectInitCommand CommandName = "project_init"
InputClearCommand CommandName = "input_clear"
InputCopyCommand CommandName = "input_copy"
InputPasteCommand CommandName = "input_paste"
InputSubmitCommand CommandName = "input_submit"
InputNewlineCommand CommandName = "input_newline"
Expand Down Expand Up @@ -313,6 +314,11 @@ func LoadFromConfig(config *opencode.Config) CommandRegistry {
Description: "clear input",
Keybindings: parseBindings("ctrl+c"),
},
{
Name: InputCopyCommand,
Description: "copy input",
Keybindings: parseBindings("ctrl+shift+c"),
},
{
Name: InputPasteCommand,
Description: "paste content",
Expand Down
13 changes: 13 additions & 0 deletions packages/tui/internal/components/chat/editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type EditorComponent interface {
Submit() (tea.Model, tea.Cmd)
SubmitBash() (tea.Model, tea.Cmd)
Clear() (tea.Model, tea.Cmd)
Copy() (tea.Model, tea.Cmd)
Paste() (tea.Model, tea.Cmd)
Newline() (tea.Model, tea.Cmd)
SetValue(value string)
Expand Down Expand Up @@ -553,6 +554,18 @@ func (m *editorComponent) Paste() (tea.Model, tea.Cmd) {
return m, tea.ReadClipboard
}

func (m *editorComponent) Copy() (tea.Model, tea.Cmd) {
content := m.textarea.Value()
if content == "" {
return m, nil
}

var cmds []tea.Cmd
cmds = append(cmds, app.SetClipboard(content))
cmds = append(cmds, toast.NewSuccessToast("Input copied to clipboard"))
return m, tea.Batch(cmds...)
}

func (m *editorComponent) Newline() (tea.Model, tea.Cmd) {
m.textarea.Newline()
return m, nil
Expand Down
4 changes: 4 additions & 0 deletions packages/tui/internal/tui/tui.go
Original file line number Diff line number Diff line change
Expand Up @@ -1396,6 +1396,10 @@ func (a Model) executeCommand(command commands.Command) (tea.Model, tea.Cmd) {
updated, cmd := a.editor.Clear()
a.editor = updated.(chat.EditorComponent)
cmds = append(cmds, cmd)
case commands.InputCopyCommand:
updated, cmd := a.editor.Copy()
a.editor = updated.(chat.EditorComponent)
cmds = append(cmds, cmd)
case commands.InputPasteCommand:
updated, cmd := a.editor.Paste()
a.editor = updated.(chat.EditorComponent)
Expand Down
1 change: 1 addition & 0 deletions packages/web/src/content/docs/docs/keybinds.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ opencode has a list of keybinds that you can customize through the opencode conf
"agent_cycle": "tab",
"agent_cycle_reverse": "shift+tab",
"input_clear": "ctrl+c",
"input_copy": "ctrl+shift+c",
"input_paste": "ctrl+v",
"input_submit": "enter",
"input_newline": "shift+enter,ctrl+j"
Expand Down