From 2bdbbd909cbe93b32d6269e8c51ce21bb5347cb1 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 20 Jul 2025 13:43:59 +0530 Subject: [PATCH] Handle color scheme changes in choose-files kitten --- kittens/choose_files/main.go | 12 ++++++++++++ kittens/choose_files/preview.go | 10 ++++++++++ tools/tui/loop/api.go | 4 ++++ tools/tui/loop/capabilities.go | 11 +++++++++++ 4 files changed, 37 insertions(+) diff --git a/kittens/choose_files/main.go b/kittens/choose_files/main.go index 459de19b2..ced324e14 100644 --- a/kittens/choose_files/main.go +++ b/kittens/choose_files/main.go @@ -713,6 +713,7 @@ func (h *Handler) set_state_from_config(conf *Config, opts *Options) (err error) } var default_cwd string +var use_light_colors bool func main(_ *cli.Command, opts *Options, args []string) (rc int, err error) { write_output := func(selections []string, interrupted bool, current_filter string) { @@ -763,6 +764,7 @@ func main(_ *cli.Command, opts *Options, args []string) (rc int, err error) { return 1, err } lp.MouseTrackingMode(loop.FULL_MOUSE_TRACKING) + lp.ColorSchemeChangeNotifications() handler := Handler{lp: lp, err_chan: make(chan error, 8), msg_printer: message.NewPrinter(utils.LanguageTag()), spinner: tui.NewSpinner("dots")} handler.rl = readline.New(lp, readline.RlInit{ Prompt: "> ", ContinuationPrompt: ". ", Completer: handler.complete_save_prompt, @@ -796,12 +798,22 @@ func main(_ *cli.Command, opts *Options, args []string) (rc int, err error) { if opts.Title != "" { lp.SetWindowTitle(opts.Title) } + lp.RequestCurrentColorScheme() return handler.OnInitialize() } lp.OnResize = func(old, new_size loop.ScreenSize) (err error) { handler.init_sizes(new_size) return handler.draw_screen() } + lp.OnColorSchemeChange = func(p loop.ColorPreference) (err error) { + new_val := p == loop.LIGHT_COLOR_PREFERENCE + if new_val != use_light_colors { + use_light_colors = new_val + handler.preview_manager.invalidate_color_scheme_based_cached_items() + return handler.draw_screen() + } + return + } lp.OnKeyEvent = handler.OnKeyEvent lp.OnText = handler.OnText lp.OnMouseEvent = handler.OnMouseEvent diff --git a/kittens/choose_files/preview.go b/kittens/choose_files/preview.go index 3b90cc3db..0ef7aae68 100644 --- a/kittens/choose_files/preview.go +++ b/kittens/choose_files/preview.go @@ -3,6 +3,7 @@ package choose_files import ( "fmt" "io/fs" + "maps" "os" "path/filepath" "slices" @@ -20,6 +21,7 @@ var _ = fmt.Print type Preview interface { Render(h *Handler, x, y, width, height int) + IsValidForColorScheme(light bool) bool } type PreviewManager struct { @@ -71,6 +73,8 @@ type MessagePreview struct { trailers []string } +func (p MessagePreview) IsValidForColorScheme(bool) bool { return true } + func (p MessagePreview) Render(h *Handler, x, y, width, height int) { offset := 0 if p.title != "" { @@ -163,6 +167,12 @@ func NewFileMetadataPreview(abspath string, metadata fs.FileInfo) Preview { return &MessagePreview{title: title, msg: h, trailers: t} } +func (pm *PreviewManager) invalidate_color_scheme_based_cached_items() { + pm.lock.Lock() + defer pm.lock.Unlock() + maps.DeleteFunc(pm.cache, func(key string, p Preview) bool { return !p.IsValidForColorScheme(use_light_colors) }) +} + func (pm *PreviewManager) preview_for(abspath string, ftype fs.FileMode) (ans Preview) { if ans = pm.cached_preview(abspath); ans != nil { return ans diff --git a/tools/tui/loop/api.go b/tools/tui/loop/api.go index d4b1fe222..9512fb03e 100644 --- a/tools/tui/loop/api.go +++ b/tools/tui/loop/api.go @@ -218,6 +218,10 @@ func NoFocusTracking(self *Loop) { self.terminal_options.focus_tracking = false } +func (self *Loop) RequestCurrentColorScheme() { + self.QueueWriteString("\x1b[?996n") +} + func (self *Loop) ColorSchemeChangeNotifications() *Loop { self.terminal_options.color_scheme_change_notification = true return self diff --git a/tools/tui/loop/capabilities.go b/tools/tui/loop/capabilities.go index 03145ca07..da9cdd0b6 100644 --- a/tools/tui/loop/capabilities.go +++ b/tools/tui/loop/capabilities.go @@ -14,6 +14,17 @@ const ( LIGHT_COLOR_PREFERENCE ) +func (c ColorPreference) String() string { + switch c { + case DARK_COLOR_PREFERENCE: + return "dark" + case LIGHT_COLOR_PREFERENCE: + return "light" + default: + return "no-preference" + } +} + type TerminalCapabilities struct { KeyboardProtocol bool KeyboardProtocolResponseReceived bool