Add terminal image preview via chafa and release v0.1.3 updates
This commit is contained in:
parent
6a518896b8
commit
6b23717572
4 changed files with 82 additions and 18 deletions
|
|
@ -9,6 +9,7 @@ import (
|
|||
_ "image/png"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
|
@ -65,6 +66,8 @@ type PreviewOptions struct {
|
|||
HumanReadableSize bool
|
||||
ThemeName string
|
||||
UseNerdIcons bool
|
||||
ImagePreviewWidth int
|
||||
ImagePreviewHeight int
|
||||
}
|
||||
|
||||
func BuildPreview(entry Entry, options PreviewOptions) Preview {
|
||||
|
|
@ -119,12 +122,12 @@ func BuildPreview(entry Entry, options PreviewOptions) Preview {
|
|||
preview.Kind = PreviewKindImage
|
||||
preview.Metadata.ImageFormat = format
|
||||
preview.Metadata.ImageSize = dimensions
|
||||
preview.Body = fmt.Sprintf(
|
||||
"Image preview is metadata-only for now.\n\nFormat: %s\nDimensions: %s\nPath: %s",
|
||||
format,
|
||||
dimensions,
|
||||
entry.Path,
|
||||
)
|
||||
inline := renderImageInlinePreview(entry.Path, options.ImagePreviewWidth, options.ImagePreviewHeight)
|
||||
if inline == "" {
|
||||
preview.Body = "Image preview unavailable.\n\nInstall `chafa` for inline preview in info pane."
|
||||
} else {
|
||||
preview.Body = inline
|
||||
}
|
||||
preview.PlainBody = preview.Body
|
||||
return preview
|
||||
}
|
||||
|
|
@ -377,6 +380,39 @@ func previewIcon(entry Entry, useNerdIcons bool) string {
|
|||
}
|
||||
}
|
||||
|
||||
func renderImageInlinePreview(path string, width int, height int) string {
|
||||
if width < 20 {
|
||||
width = 20
|
||||
}
|
||||
if height < 8 {
|
||||
height = 8
|
||||
}
|
||||
|
||||
if _, err := exec.LookPath("chafa"); err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
cmd := exec.Command(
|
||||
"chafa",
|
||||
"--format=symbols",
|
||||
"--symbols=vhalf",
|
||||
"--animate=off",
|
||||
"--fg-only",
|
||||
"--size", fmt.Sprintf("%dx%d", width, height),
|
||||
path,
|
||||
)
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
view := strings.TrimSpace(string(out))
|
||||
if view == "" {
|
||||
return ""
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
func detectImage(data []byte) (string, string, bool) {
|
||||
cfg, format, err := image.DecodeConfig(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -869,6 +869,12 @@ func (m Model) loadPreviewCmd() tea.Cmd {
|
|||
HumanReadableSize: m.cfg.Browser.HumanReadableSize,
|
||||
ThemeName: m.cfg.UI.Theme,
|
||||
UseNerdIcons: m.nerdIcons,
|
||||
ImagePreviewWidth: max(m.previewModel.Width-2, 20),
|
||||
ImagePreviewHeight: max(m.previewModel.Height-6, 8),
|
||||
}
|
||||
if m.viewMode {
|
||||
options.ImagePreviewWidth = max(m.width-8, 20)
|
||||
options.ImagePreviewHeight = max(m.bodyHeight()-8, 8)
|
||||
}
|
||||
|
||||
return func() tea.Msg {
|
||||
|
|
@ -970,6 +976,12 @@ func (m *Model) handleView() (tea.Model, tea.Cmd) {
|
|||
m.status = "Select a file to view"
|
||||
return m, nil
|
||||
}
|
||||
if selected.Category() == "image" {
|
||||
if _, err := exec.LookPath("chafa"); err != nil {
|
||||
m.status = "Install `chafa` to view images in terminal"
|
||||
return m, nil
|
||||
}
|
||||
}
|
||||
if m.viewMode {
|
||||
return m.exitViewMode()
|
||||
}
|
||||
|
|
@ -1287,7 +1299,7 @@ func (m *Model) openHelpModal() {
|
|||
"",
|
||||
"View and Panels",
|
||||
" F9 / i toggle preview/info pane",
|
||||
" F3 / v open read-only view mode",
|
||||
" F3 / v text view mode or fullscreen image viewer",
|
||||
" F3 / Esc / q close view mode",
|
||||
" Ctrl+t toggle text selection mode in text preview",
|
||||
" Space calculate selected directory size",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue