Skip to content

Commit

Permalink
feat: show image size and dimensions in preview
Browse files Browse the repository at this point in the history
  • Loading branch information
sentriz committed Apr 7, 2023
1 parent 11e1475 commit dd3c5f0
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 28 deletions.
41 changes: 19 additions & 22 deletions cliphist.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"flag"
"fmt"
"image"
"io"
"os"
"path/filepath"
Expand All @@ -14,13 +15,19 @@ import (
"time"

_ "embed"
_ "image/gif"
_ "image/jpeg"
_ "image/png"

"github.com/dustin/go-humanize"
bolt "go.etcd.io/bbolt"
)

//go:embed version.txt
var version string

const fieldSep = "\t"

// allow us to test main
func main() { os.Exit(main_()) }
func main_() int {
Expand Down Expand Up @@ -172,7 +179,7 @@ func list(out io.Writer) error {
}

func extractID(input []byte) (uint64, error) {
idStr, _, found := strings.Cut(string(input), "\t")
idStr, _, found := strings.Cut(string(input), fieldSep)
if !found {
return 0, fmt.Errorf("input not prefixed with id")
}
Expand Down Expand Up @@ -206,7 +213,7 @@ func decode(in io.Reader, out io.Writer) error {
defer tx.Rollback() //nolint:errcheck

b := tx.Bucket([]byte(bucketKey))
v := b.Get(itob(uint64(id)))
v := b.Get(itob(id))
if _, err := out.Write(v); err != nil {
return fmt.Errorf("writing out: %w", err)
}
Expand Down Expand Up @@ -267,7 +274,7 @@ func delete(in io.Reader) error {
defer tx.Rollback() //nolint:errcheck

b := tx.Bucket([]byte(bucketKey))
if err := b.Delete(itob(uint64(id))); err != nil {
if err := b.Delete(itob(id)); err != nil {
return fmt.Errorf("delete key: %w", err)
}

Expand Down Expand Up @@ -346,28 +353,14 @@ func initDBOption(ro bool) (*bolt.DB, error) {
}

func preview(index uint64, data []byte) string {
data = data[:min(len(data), 100)]
if mime := mime(data); mime != "" {
return fmt.Sprintf("%d\tbinary data %s", index, mime)
if config, format, err := image.DecodeConfig(bytes.NewReader(data)); err == nil {
return fmt.Sprintf("%d%s[[ binary data %s %s %dx%d ]]",
index, fieldSep, sizeStr(len(data)), format, config.Width, config.Height)
}
data = data[:min(len(data), 100)]
data = bytes.TrimSpace(data)
data = bytes.Join(bytes.Fields(data), []byte(" "))
return fmt.Sprintf("%d\t%s", index, data)
}

func mime(data []byte) string {
switch {
case bytes.HasPrefix(data, []byte("\x89PNG\x0D\x0A\x1A\x0A")):
return "image/png"
case bytes.HasPrefix(data, []byte("\xFF\xD8\xFF")):
return "image/jpeg"
case bytes.HasPrefix(data, []byte("GIF87a")):
return "image/gif"
case bytes.HasPrefix(data, []byte("GIF89a")):
return "image/gif"
default:
return ""
}
return fmt.Sprintf("%d%s%s", index, fieldSep, data)
}

func min(a, b int) int {
Expand All @@ -386,3 +379,7 @@ func itob(v uint64) []byte {
func btoi(v []byte) uint64 {
return binary.BigEndian.Uint64(v)
}

func sizeStr(s int) string {
return strings.ReplaceAll(humanize.Bytes(uint64(s)), " ", "")
}
2 changes: 1 addition & 1 deletion contrib/cliphist-fzf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
case "$1" in
preview)
# show preview if non-binary data
echo "$2" | grep -q '^[[:digit:]]*\. binary data' || echo "$2" | cliphist decode
echo "$2" | grep -q '[\[ binary data .* \]\]' || echo "$2" | cliphist decode
;;
*)
exec cliphist list |
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ module go.senan.xyz/cliphist
go 1.19

require (
github.com/dustin/go-humanize v1.0.1
github.com/rogpeppe/go-internal v1.10.0
go.etcd.io/bbolt v1.3.7
)

require golang.org/x/sys v0.6.0 // indirect
require golang.org/x/sys v0.7.0 // indirect
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
2 changes: 1 addition & 1 deletion testdata/test-image-and-preview-jpg.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ exec cliphist store

# check we render preview
exec cliphist list
stdout 'binary data image/jpeg$'
stdout '[[ binary data .*? jpeg 20x20 ]]'

stdin query
exec cliphist decode
Expand Down
2 changes: 1 addition & 1 deletion testdata/test-image-and-preview-png.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ exec cliphist store

# check we render preview
exec cliphist list
stdout 'binary data image/png$'
stdout '[[ binary data .*? png 20x20 ]]'

stdin query
exec cliphist decode
Expand Down

0 comments on commit dd3c5f0

Please sign in to comment.