Skip to content

Commit 6a02b7f

Browse files
committed
feat: allow ctrl+d to exit the app
This adds support for ctrl+d to exit the app. It follows the unix convention of only requiring a single press of the command. Additionally, it updates the help menu to reflect the new keybind.
1 parent 76e080b commit 6a02b7f

File tree

4 files changed

+10
-5
lines changed

4 files changed

+10
-5
lines changed

packages/opencode/src/config/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ export namespace Config {
402402
.default("ctrl+x")
403403
.describe("Leader key for keybind combinations"),
404404
app_help: z.string().optional().default("<leader>h").describe("Show help dialog"),
405-
app_exit: z.string().optional().default("ctrl+c,<leader>q").describe("Exit the application"),
405+
app_exit: z.string().optional().default("ctrl+d,ctrl+c,<leader>q").describe("Exit the application"),
406406
editor_open: z.string().optional().default("<leader>e").describe("Open external editor"),
407407
theme_list: z.string().optional().default("<leader>t").describe("List available themes"),
408408
project_init: z.string().optional().default("<leader>i").describe("Create/update AGENTS.md"),

packages/sdk/python/src/opencode_ai/models/keybinds_config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class KeybindsConfig:
1515
Attributes:
1616
leader (Union[Unset, str]): Leader key for keybind combinations Default: 'ctrl+x'.
1717
app_help (Union[Unset, str]): Show help dialog Default: '<leader>h'.
18-
app_exit (Union[Unset, str]): Exit the application Default: 'ctrl+c,<leader>q'.
18+
app_exit (Union[Unset, str]): Exit the application Default: 'ctrl+d,ctrl+c,<leader>q'.
1919
editor_open (Union[Unset, str]): Open external editor Default: '<leader>e'.
2020
theme_list (Union[Unset, str]): List available themes Default: '<leader>t'.
2121
project_init (Union[Unset, str]): Create/update AGENTS.md Default: '<leader>i'.
@@ -67,7 +67,7 @@ class KeybindsConfig:
6767

6868
leader: Union[Unset, str] = "ctrl+x"
6969
app_help: Union[Unset, str] = "<leader>h"
70-
app_exit: Union[Unset, str] = "ctrl+c,<leader>q"
70+
app_exit: Union[Unset, str] = "ctrl+d,ctrl+c,<leader>q"
7171
editor_open: Union[Unset, str] = "<leader>e"
7272
theme_list: Union[Unset, str] = "<leader>t"
7373
project_init: Union[Unset, str] = "<leader>i"

packages/tui/internal/commands/command.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,6 @@ func LoadFromConfig(config *opencode.Config, customCommands []opencode.Command)
367367
Description: "last message",
368368
Keybindings: parseBindings("ctrl+alt+g"),
369369
},
370-
371370
{
372371
Name: MessagesCopyCommand,
373372
Description: "copy message",
@@ -388,7 +387,8 @@ func LoadFromConfig(config *opencode.Config, customCommands []opencode.Command)
388387
{
389388
Name: AppExitCommand,
390389
Description: "exit the app",
391-
Keybindings: parseBindings("ctrl+c", "<leader>q"),
390+
// NOTE: ctrl+c requires a double press to exit while ctrl+d requires a single press
391+
Keybindings: parseBindings("ctrl+c", "ctrl+d", "<leader>q"),
392392
Trigger: []string{"exit", "quit", "q"},
393393
},
394394
}

packages/tui/internal/tui/tui.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,11 @@ func (a Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
308308
// 8. Handle exit key debounce for app exit when using non-leader command
309309
exitCommand := a.app.Commands[commands.AppExitCommand]
310310
if exitCommand.Matches(msg, a.app.IsLeaderSequence) {
311+
// If the exit key is ctrl+d, exit immediately (inclusive of using after leader sequence initiated)
312+
if msg.String() == "ctrl+d" {
313+
return a, util.CmdHandler(commands.ExecuteCommandMsg(exitCommand))
314+
}
315+
// Else, either start debounce timer for ctrl+c or exit immediately (if within timeout or in leader sequence)
311316
switch a.exitKeyState {
312317
case ExitKeyIdle:
313318
// First exit key press - start debounce timer

0 commit comments

Comments
 (0)