Просмотр исходного кода

feat(tui): shift+tab to cycle modes backward (#1049)

Adi Yeroslav 7 месяцев назад
Родитель
Сommit
57d1a60efc

+ 2 - 1
packages/opencode/src/config/config.ts

@@ -81,7 +81,8 @@ export namespace Config {
     .object({
       leader: z.string().optional().default("ctrl+x").describe("Leader key for keybind combinations"),
       app_help: z.string().optional().default("<leader>h").describe("Show help dialog"),
-      switch_mode: z.string().optional().default("tab").describe("Switch mode"),
+      switch_mode: z.string().optional().default("tab").describe("Next mode"),
+      switch_mode_reverse: z.string().optional().default("shift+tab").describe("Previous Mode"),
       editor_open: z.string().optional().default("<leader>e").describe("Open external editor"),
       session_export: z.string().optional().default("<leader>x").describe("Export session to editor"),
       session_new: z.string().optional().default("<leader>n").describe("Create a new session"),

BIN
packages/tui/cmd/opencode/opencode


+ 19 - 4
packages/tui/internal/app/app.go

@@ -205,10 +205,17 @@ func (a *App) SetClipboard(text string) tea.Cmd {
 	return tea.Sequence(cmds...)
 }
 
-func (a *App) SwitchMode() (*App, tea.Cmd) {
-	a.ModeIndex++
-	if a.ModeIndex >= len(a.Modes) {
-		a.ModeIndex = 0
+func (a *App) cycleMode(forward bool) (*App, tea.Cmd) {
+	if forward {
+		a.ModeIndex++
+		if a.ModeIndex >= len(a.Modes) {
+			a.ModeIndex = 0
+		}
+	} else {
+		a.ModeIndex--
+		if a.ModeIndex < 0 {
+			a.ModeIndex = len(a.Modes) - 1
+		}
 	}
 	a.Mode = &a.Modes[a.ModeIndex]
 
@@ -244,6 +251,14 @@ func (a *App) SwitchMode() (*App, tea.Cmd) {
 	}
 }
 
+func (a *App) SwitchMode() (*App, tea.Cmd) {
+	return a.cycleMode(true)
+}
+
+func (a *App) SwitchModeReverse() (*App, tea.Cmd) {
+	return a.cycleMode(false)
+}
+
 func (a *App) InitializeProvider() tea.Cmd {
 	providersResponse, err := a.Client.Config.Providers(context.Background())
 	if err != nil {

+ 7 - 1
packages/tui/internal/commands/command.go

@@ -87,6 +87,7 @@ func (r CommandRegistry) Matches(msg tea.KeyPressMsg, leader bool) []Command {
 const (
 	AppHelpCommand              CommandName = "app_help"
 	SwitchModeCommand           CommandName = "switch_mode"
+	SwitchModeReverseCommand    CommandName = "switch_mode_reverse"
 	EditorOpenCommand           CommandName = "editor_open"
 	SessionNewCommand           CommandName = "session_new"
 	SessionListCommand          CommandName = "session_list"
@@ -156,9 +157,14 @@ func LoadFromConfig(config *opencode.Config) CommandRegistry {
 		},
 		{
 			Name:        SwitchModeCommand,
-			Description: "switch mode",
+			Description: "next mode",
 			Keybindings: parseBindings("tab"),
 		},
+		{
+			Name:        SwitchModeReverseCommand,
+			Description: "previous mode",
+			Keybindings: parseBindings("shift+tab"),
+		},
 		{
 			Name:        EditorOpenCommand,
 			Description: "open editor",

+ 4 - 0
packages/tui/internal/tui/tui.go

@@ -810,6 +810,10 @@ func (a appModel) executeCommand(command commands.Command) (tea.Model, tea.Cmd)
 		updated, cmd := a.app.SwitchMode()
 		a.app = updated
 		cmds = append(cmds, cmd)
+	case commands.SwitchModeReverseCommand:
+		updated, cmd := a.app.SwitchModeReverse()
+		a.app = updated
+		cmds = append(cmds, cmd)
 	case commands.EditorOpenCommand:
 		if a.app.IsBusy() {
 			// status.Warn("Agent is working, please wait...")

+ 3 - 0
packages/tui/sdk/config.go

@@ -560,6 +560,8 @@ type Keybinds struct {
 	SessionUnshare string `json:"session_unshare,required"`
 	// Switch mode
 	SwitchMode string `json:"switch_mode,required"`
+	// Switch mode reverse
+	SwitchModeReverse string `json:"switch_mode_reverse,required"`
 	// List available themes
 	ThemeList string `json:"theme_list,required"`
 	// Toggle tool details
@@ -601,6 +603,7 @@ type keybindsJSON struct {
 	SessionShare         apijson.Field
 	SessionUnshare       apijson.Field
 	SwitchMode           apijson.Field
+	SwitchModeReverse    apijson.Field
 	ThemeList            apijson.Field
 	ToolDetails          apijson.Field
 	raw                  string