diff --git a/popups.go b/popups.go index db314e4..26457b5 100644 --- a/popups.go +++ b/popups.go @@ -387,3 +387,81 @@ func showFileCompletionPopup(filter string) { pages.AddPage("fileCompletionPopup", modal(widget, 80, 20), true, true) app.SetFocus(widget) } + +// showColorschemeSelectionPopup creates a modal popup to select a colorscheme +func showColorschemeSelectionPopup() { + // Get the list of available colorschemes + schemeNames := make([]string, 0, len(colorschemes)) + for name := range colorschemes { + schemeNames = append(schemeNames, name) + } + slices.Sort(schemeNames) + // Check for empty options list + if len(schemeNames) == 0 { + logger.Warn("no colorschemes available for selection") + message := "No colorschemes available." + if err := notifyUser("Empty list", message); err != nil { + logger.Error("failed to send notification", "error", err) + } + return + } + // Create a list primitive + schemeListWidget := tview.NewList().ShowSecondaryText(false). + SetSelectedBackgroundColor(tcell.ColorGray) + schemeListWidget.SetTitle("Select Colorscheme").SetBorder(true) + + currentScheme := "default" + for name := range colorschemes { + if tview.Styles == colorschemes[name] { + currentScheme = name + break + } + } + currentSchemeIndex := -1 + for i, scheme := range schemeNames { + if scheme == currentScheme { + currentSchemeIndex = i + } + schemeListWidget.AddItem(scheme, "", 0, nil) + } + // Set the current selection if found + if currentSchemeIndex != -1 { + schemeListWidget.SetCurrentItem(currentSchemeIndex) + } + schemeListWidget.SetSelectedFunc(func(index int, mainText string, secondaryText string, shortcut rune) { + // Update the colorscheme + if theme, ok := colorschemes[mainText]; ok { + // Refresh the UI to apply the new theme + go func() { + app.QueueUpdateDraw(func() { + tview.Styles = theme + }) + }() + } + // Remove the popup page + pages.RemovePage("colorschemeSelectionPopup") + }) + schemeListWidget.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { + if event.Key() == tcell.KeyEscape { + pages.RemovePage("colorschemeSelectionPopup") + return nil + } + if event.Key() == tcell.KeyRune && event.Rune() == 'x' { + pages.RemovePage("colorschemeSelectionPopup") + return nil + } + return event + }) + modal := func(p tview.Primitive, width, height int) tview.Primitive { + return tview.NewFlex(). + AddItem(nil, 0, 1, false). + AddItem(tview.NewFlex().SetDirection(tview.FlexRow). + AddItem(nil, 0, 1, false). + AddItem(p, height, 1, true). + AddItem(nil, 0, 1, false), width, 1, true). + AddItem(nil, 0, 1, false) + } + // Add modal page and make it visible + pages.AddPage("colorschemeSelectionPopup", modal(schemeListWidget, 40, len(schemeNames)+2), true, true) + app.SetFocus(schemeListWidget) +} diff --git a/tui.go b/tui.go index 0d2cd92..9a10890 100644 --- a/tui.go +++ b/tui.go @@ -96,6 +96,7 @@ var ( [yellow]Alt+8[white]: show char img or last picked img [yellow]Alt+9[white]: warm up (load) selected llama.cpp model [yellow]Alt+t[white]: toggle thinking blocks visibility (collapse/expand blocks) +[yellow]Alt+c[white]: show colorscheme selection popup === scrolling chat window (some keys similar to vim) === [yellow]arrows up/down and j/k[white]: scroll up and down @@ -560,6 +561,10 @@ func init() { } return nil } + if event.Key() == tcell.KeyRune && event.Rune() == 'i' && event.Modifiers()&tcell.ModAlt != 0 { + showColorschemeSelectionPopup() + return nil + } if event.Key() == tcell.KeyF1 { // chatList, err := loadHistoryChats() chatList, err := store.GetChatByChar(cfg.AssistantRole)