feat(tui): support cycling recent models in reverse (#1953)

This commit is contained in:
Yihui Khuu
2025-08-15 21:20:07 +10:00
committed by GitHub
parent 17a7c824b8
commit 92d4366a20
3 changed files with 68 additions and 44 deletions

View File

@@ -290,7 +290,7 @@ func (a *App) SwitchAgentReverse() (*App, tea.Cmd) {
return a.cycleMode(false) return a.cycleMode(false)
} }
func (a *App) CycleRecentModel() (*App, tea.Cmd) { func (a *App) cycleRecentModel(forward bool) (*App, tea.Cmd) {
recentModels := a.State.RecentlyUsedModels recentModels := a.State.RecentlyUsedModels
if len(recentModels) > 5 { if len(recentModels) > 5 {
recentModels = recentModels[:5] recentModels = recentModels[:5]
@@ -299,15 +299,21 @@ func (a *App) CycleRecentModel() (*App, tea.Cmd) {
return a, toast.NewInfoToast("Need at least 2 recent models to cycle") return a, toast.NewInfoToast("Need at least 2 recent models to cycle")
} }
nextIndex := 0 nextIndex := 0
prevIndex := 0
for i, recentModel := range recentModels { for i, recentModel := range recentModels {
if a.Provider != nil && a.Model != nil && recentModel.ProviderID == a.Provider.ID && if a.Provider != nil && a.Model != nil && recentModel.ProviderID == a.Provider.ID &&
recentModel.ModelID == a.Model.ID { recentModel.ModelID == a.Model.ID {
nextIndex = (i + 1) % len(recentModels) nextIndex = (i + 1) % len(recentModels)
prevIndex = (i - 1 + len(recentModels)) % len(recentModels)
break break
} }
} }
targetIndex := nextIndex
if !forward {
targetIndex = prevIndex
}
for range recentModels { for range recentModels {
currentRecentModel := recentModels[nextIndex%len(recentModels)] currentRecentModel := recentModels[targetIndex%len(recentModels)]
provider, model := findModelByProviderAndModelID( provider, model := findModelByProviderAndModelID(
a.Providers, a.Providers,
currentRecentModel.ProviderID, currentRecentModel.ProviderID,
@@ -327,8 +333,8 @@ func (a *App) CycleRecentModel() (*App, tea.Cmd) {
) )
} }
recentModels = append( recentModels = append(
recentModels[:nextIndex%len(recentModels)], recentModels[:targetIndex%len(recentModels)],
recentModels[nextIndex%len(recentModels)+1:]...) recentModels[targetIndex%len(recentModels)+1:]...)
if len(recentModels) < 2 { if len(recentModels) < 2 {
a.State.RecentlyUsedModels = recentModels a.State.RecentlyUsedModels = recentModels
return a, tea.Sequence( return a, tea.Sequence(
@@ -341,6 +347,14 @@ func (a *App) CycleRecentModel() (*App, tea.Cmd) {
return a, toast.NewErrorToast("Recent model not found") return a, toast.NewErrorToast("Recent model not found")
} }
func (a *App) CycleRecentModel() (*App, tea.Cmd) {
return a.cycleRecentModel(true)
}
func (a *App) CycleRecentModelReverse() (*App, tea.Cmd) {
return a.cycleRecentModel(false)
}
func (a *App) SwitchToAgent(agentName string) (*App, tea.Cmd) { func (a *App) SwitchToAgent(agentName string) (*App, tea.Cmd) {
// Find the agent index by name // Find the agent index by name
for i, agent := range a.Agents { for i, agent := range a.Agents {

View File

@@ -123,6 +123,7 @@ const (
ModelListCommand CommandName = "model_list" ModelListCommand CommandName = "model_list"
AgentListCommand CommandName = "agent_list" AgentListCommand CommandName = "agent_list"
ModelCycleRecentCommand CommandName = "model_cycle_recent" ModelCycleRecentCommand CommandName = "model_cycle_recent"
ModelCycleRecentReverseCommand CommandName = "model_cycle_recent_reverse"
ThemeListCommand CommandName = "theme_list" ThemeListCommand CommandName = "theme_list"
FileListCommand CommandName = "file_list" FileListCommand CommandName = "file_list"
FileCloseCommand CommandName = "file_close" FileCloseCommand CommandName = "file_close"
@@ -266,9 +267,14 @@ func LoadFromConfig(config *opencode.Config) CommandRegistry {
}, },
{ {
Name: ModelCycleRecentCommand, Name: ModelCycleRecentCommand,
Description: "cycle recent models", Description: "next recent model",
Keybindings: parseBindings("f2"), Keybindings: parseBindings("f2"),
}, },
{
Name: ModelCycleRecentReverseCommand,
Description: "previous recent model",
Keybindings: parseBindings("shift+f2"),
},
{ {
Name: ThemeListCommand, Name: ThemeListCommand,
Description: "list themes", Description: "list themes",

View File

@@ -1190,6 +1190,10 @@ func (a Model) executeCommand(command commands.Command) (tea.Model, tea.Cmd) {
updated, cmd := a.app.CycleRecentModel() updated, cmd := a.app.CycleRecentModel()
a.app = updated a.app = updated
cmds = append(cmds, cmd) cmds = append(cmds, cmd)
case commands.ModelCycleRecentReverseCommand:
updated, cmd := a.app.CycleRecentModelReverse()
a.app = updated
cmds = append(cmds, cmd)
case commands.ThemeListCommand: case commands.ThemeListCommand:
themeDialog := dialog.NewThemeDialog() themeDialog := dialog.NewThemeDialog()
a.modal = themeDialog a.modal = themeDialog