feat: add cmd for editing config.json via $EDITOR

This commit is contained in:
John Henry Rudden 2025-07-05 16:18:42 -05:00
parent 969ad80ed2
commit bff60e332d
5 changed files with 49 additions and 3 deletions

View file

@ -72,6 +72,7 @@ export namespace Config {
.describe("Leader key for keybind combinations"),
help: z.string().optional().describe("Show help dialog"),
editor_open: z.string().optional().describe("Open external editor"),
config: z.string().optional().describe("Edit configuration file"),
session_new: z.string().optional().describe("Create a new session"),
session_list: z.string().optional().describe("List all sessions"),
session_share: z.string().optional().describe("Share current session"),

View file

@ -101,6 +101,7 @@ const (
MessagesLayoutToggleCommand CommandName = "messages_layout_toggle"
MessagesCopyCommand CommandName = "messages_copy"
MessagesRevertCommand CommandName = "messages_revert"
ConfigCommand CommandName = "config"
AppExitCommand CommandName = "app_exit"
)
@ -298,6 +299,12 @@ func LoadFromConfig(config *opencode.Config) CommandRegistry {
Description: "revert message",
Keybindings: parseBindings("<leader>r"),
},
{
Name: ConfigCommand,
Description: "edit config",
Keybindings: parseBindings("<leader>o"),
Trigger: "config",
},
{
Name: AppExitCommand,
Description: "exit the app",

View file

@ -5,6 +5,7 @@ import (
"log/slog"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
@ -968,6 +969,28 @@ func (a appModel) executeCommand(command commands.Command) (tea.Model, tea.Cmd)
cmds = append(cmds, cmd)
}
case commands.MessagesRevertCommand:
case commands.ConfigCommand:
if a.app.IsBusy() {
return a, nil
}
editor := os.Getenv("EDITOR")
if editor == "" {
return a, toast.NewErrorToast("No EDITOR set, can't open config")
}
configPath := filepath.Join(a.app.Info.Path.Config, "config.json")
c := exec.Command(editor, configPath) //nolint:gosec
c.Stdin = os.Stdin
c.Stdout = os.Stdout
c.Stderr = os.Stderr
cmd := tea.ExecProcess(c, func(err error) tea.Msg {
if err != nil {
slog.Error("Failed to open config", "error", err)
return toast.NewErrorToast("Failed to open config")()
}
return tea.QuitMsg{}
})
cmds = append(cmds, cmd)
case commands.AppExitCommand:
return a, tea.Quit
}

View file

@ -397,6 +397,8 @@ func (r configProviderModelsLimitJSON) RawJSON() string {
type Keybinds struct {
// Exit the application
AppExit string `json:"app_exit"`
// Edit configuration file
Config string `json:"config"`
// Open external editor
EditorOpen string `json:"editor_open"`
// Show help dialog
@ -455,6 +457,7 @@ type Keybinds struct {
// keybindsJSON contains the JSON metadata for the struct [Keybinds]
type keybindsJSON struct {
AppExit apijson.Field
Config apijson.Field
EditorOpen apijson.Field
Help apijson.Field
HistoryNext apijson.Field

View file

@ -22,6 +22,17 @@ In most cases, you'll want to use the global config for things like themes, prov
When opencode starts up, it looks for a config file in the current directory or traverse up to the nearest Git directory.
## Quick Access
You can quickly open your global config file for editing using the `/config` command in opencode. This will open `~/.config/opencode/config.json` in your default editor (set via the `$EDITOR` environment variable).
- **Command**: `/config`
- **Keybinding**: `<leader>o` (where leader is typically `Ctrl+X`)
This is the fastest way to modify your global configuration without leaving the opencode interface.
You can customize the keybinding by setting the `config` field in your keybinds configuration. See the [keybinds documentation](/docs/keybinds) for more details.
---
## Schema
@ -39,7 +50,7 @@ You can configure the providers and models you want to use in your opencode conf
```json title="opencode.json"
{
"$schema": "https://opencode.ai/config.json",
"provider": { },
"provider": {},
"model": ""
}
```
@ -70,7 +81,7 @@ You can customize your keybinds through the `keybinds` option.
```json title="opencode.json"
{
"$schema": "https://opencode.ai/config.json",
"keybinds": { }
"keybinds": {}
}
```
@ -85,7 +96,7 @@ You can configure MCP servers you want to use through the `mcp` option.
```json title="opencode.json"
{
"$schema": "https://opencode.ai/config.json",
"mcp": { }
"mcp": {}
}
```
@ -105,6 +116,7 @@ You can disable providers that are loaded automatically through the `disabled_pr
```
The `disabled_providers` option accepts an array of provider IDs. When a provider is disabled:
- It won't be loaded even if environment variables are set
- It won't be loaded even if API keys are configured through `opencode auth login`
- The provider's models won't appear in the model selection list