diff --git a/kittens/dnd/drop.go b/kittens/dnd/drop.go index 13ed2bf6f..e85efab1d 100644 --- a/kittens/dnd/drop.go +++ b/kittens/dnd/drop.go @@ -4,7 +4,6 @@ import ( "bytes" "container/list" "context" - "encoding/base64" "errors" "fmt" "io" @@ -16,6 +15,8 @@ import ( "strconv" "strings" + "github.com/emmansun/base64" + "github.com/kovidgoyal/go-parallel" "github.com/kovidgoyal/kitty/tools/utils" "github.com/kovidgoyal/kitty/tools/utils/streaming_base64" @@ -376,40 +377,10 @@ type parsed_uri struct { // ext_for_mime returns a file extension (with leading dot) for a MIME type. func ext_for_mime(mime string) string { - switch mime { - case "image/jpeg": - return ".jpg" - case "image/png": - return ".png" - case "image/gif": - return ".gif" - case "image/webp": - return ".webp" - case "image/svg+xml": - return ".svg" - case "text/plain": - return ".txt" - case "text/html": - return ".html" - case "text/css": - return ".css" - case "application/pdf": - return ".pdf" - case "application/json": - return ".json" - case "application/zip": - return ".zip" - default: - if _, subtype, found := strings.Cut(mime, "/"); found && subtype != "" { - subtype, _, _ = strings.Cut(subtype, "+") - subtype, _, _ = strings.Cut(subtype, ";") - subtype = strings.TrimSpace(subtype) - if subtype != "" { - return "." + subtype - } - } - return "" + for _, x := range utils.GuessFileExtensions(mime) { + return x } + return "" } // parse_data_uri decodes a data: URI and returns the MIME type and raw data. diff --git a/tools/utils/mimetypes.go b/tools/utils/mimetypes.go index 6fd8415b4..c63d85c7e 100644 --- a/tools/utils/mimetypes.go +++ b/tools/utils/mimetypes.go @@ -117,3 +117,32 @@ func GuessMimeTypeWithFileSystemAccess(filename string) string { } return mt } + +func GuessFileExtensions(mime_type string) (ans []string) { + mime_type, _, err := mime.ParseMediaType(mime_type) + if err != nil { + return + } + seen := NewSet[string](8) + add := func(x string) { + if !seen.Has(x) { + seen.Add(x) + ans = append(ans, x) + } + } + for ext, q := range UserMimeMap() { + if ext != "" && q == mime_type { + add(ext) + } + } + // Go stdlib returns [".asc", ".text", ".txt"] for this + if mime_type == "text/plain" { + add(".txt") + } + if std, err := mime.ExtensionsByType(mime_type); err == nil { + for _, x := range std { + add(x) + } + } + return +}