diff --git a/kittens/choose_files/image_preview.go b/kittens/choose_files/image_preview.go new file mode 100644 index 000000000..821461b02 --- /dev/null +++ b/kittens/choose_files/image_preview.go @@ -0,0 +1,50 @@ +package choose_files + +import ( + "fmt" + "io/fs" + "path/filepath" + "sync" + "sync/atomic" + + "github.com/kovidgoyal/kitty/tools/disk_cache" + "github.com/kovidgoyal/kitty/tools/utils" +) + +var _ = fmt.Print + +var dc_size atomic.Int64 + +var preview_cache = sync.OnceValues(func() (*disk_cache.DiskCache, error) { + cdir := utils.CacheDir() + cdir = filepath.Join(cdir, "choose-files") + return disk_cache.NewDiskCache(cdir, dc_size.Load()) +}) + +type ImagePreview struct { + abspath, cache_key string + disk_cache *disk_cache.DiskCache +} + +func (p ImagePreview) IsValidForColorScheme(bool) bool { return true } + +func (p ImagePreview) Render(h *Handler, x, y, width, height int) { + offset := 0 + offset += h.render_wrapped_text_in_region("Rendering image, please wait...", x, y, width, height, true) +} + +func NewImagePreview(abspath string, metadata fs.FileInfo, opts Settings) (Preview, error) { + dc_size.Store(opts.DiskCacheSize()) + ans := &ImagePreview{abspath: abspath} + if dc, err := preview_cache(); err != nil { + return nil, err + } else { + ans.disk_cache = dc + } + if key, err := disk_cache.KeyForPath(abspath); err != nil { + return nil, err + } else { + ans.cache_key = key + } + return ans, nil +} diff --git a/kittens/choose_files/main.go b/kittens/choose_files/main.go index 555a07162..57525654f 100644 --- a/kittens/choose_files/main.go +++ b/kittens/choose_files/main.go @@ -123,6 +123,7 @@ type State struct { display_title bool pygments_style, dark_pygments_style string syntax_aliases map[string]string + max_disk_cache_size int64 selections []string current_idx CollectionIndex @@ -131,6 +132,7 @@ type State struct { redraw_needed bool } +func (s State) DiskCacheSize() int64 { return s.max_disk_cache_size } func (s State) HighlightStyles() (string, string) { return s.pygments_style, s.dark_pygments_style } func (s State) SyntaxAliases() map[string]string { return s.syntax_aliases } func (s State) DisplayTitle() bool { return s.display_title } @@ -718,6 +720,7 @@ func (h *Handler) set_state_from_config(conf *Config, opts *Options) (err error) h.state.pygments_style = conf.Pygments_style h.state.dark_pygments_style = conf.Dark_pygments_style h.state.syntax_aliases = conf.Syntax_aliases + h.state.max_disk_cache_size = int64(conf.Cache_size * (1024 * 1024 * 1024)) return } diff --git a/kittens/choose_files/main.py b/kittens/choose_files/main.py index 84e0a33de..416908503 100644 --- a/kittens/choose_files/main.py +++ b/kittens/choose_files/main.py @@ -61,6 +61,11 @@ builtin styles ` for a list of schemes. This sets the colors used for dark color schemes, use :opt:`pygments_style` to change the colors for light color schemes.''') +opt('cache_size', '0.5', option_type='positive_float', long_text=''' +The maximum size of the disk cache, in gigabytes, used for previews. Zero or negative values +mean no limit. +''') + opt('syntax_aliases', 'pyj:py pyi:py recipe:py', ctype='strdict_ _:', option_type='syntax_aliases', long_text=''' File extension aliases for syntax highlight. For example, to syntax highlight diff --git a/kittens/choose_files/preview.go b/kittens/choose_files/preview.go index 606aa5814..a42a43708 100644 --- a/kittens/choose_files/preview.go +++ b/kittens/choose_files/preview.go @@ -297,6 +297,13 @@ func (pm *PreviewManager) preview_for(abspath string, ftype fs.FileMode) (ans Pr pm.highlight_file_async(abspath, ch) return NewTextFilePreview(abspath, s, ch, pm.highlighter.Sanitize) } + if strings.HasPrefix(mt, "image/") { + ans, err := NewImagePreview(abspath, s, pm.settings) + if err != nil { + return NewErrorPreview(err) + } + return ans + } return NewFileMetadataPreview(abspath, s) } diff --git a/kittens/choose_files/scan.go b/kittens/choose_files/scan.go index 4d44ce025..5cc8582c9 100644 --- a/kittens/choose_files/scan.go +++ b/kittens/choose_files/scan.go @@ -634,6 +634,7 @@ type Settings interface { GlobalIgnores() ignorefiles.IgnoreFile HighlightStyles() (string, string) SyntaxAliases() map[string]string + DiskCacheSize() int64 } type ResultManager struct { diff --git a/kitty/conf/generate.py b/kitty/conf/generate.py index e6ca5c706..6f94a0246 100644 --- a/kitty/conf/generate.py +++ b/kitty/conf/generate.py @@ -491,7 +491,7 @@ def go_type_data(parser_func: ParserFuncType, ctype: str, is_multiple: bool = Fa if p == 'positive_int': return 'uint64', 'strconv.ParseUint(val, 10, 64)' if p == 'positive_float': - return 'float64', 'config.PositiveFloat(val, 10, 64)' + return 'float64', 'config.PositiveFloat(val)' if p == 'unit_float': return 'float64', 'config.UnitFloat(val)' if p == 'python_string':