Default exotic image formats (like .webp) to image-mode

* doc/lispref/errors.texi (Standard Errors): Mention the new error.

* lisp/files.el (auto-mode-alist): Add a bunch of image suffixes
to the list (bug#37972) based on the output from "gm convert -list
format" (i.e., graphicsmagick).

* lisp/image-mode.el (image-mode): Rewrite to possibly notify the
user about image-use-external-converter.
(image-mode--setup-mode): Factor out into own function and don't
run under `condition-case' as there's nothing here that should
error.

* lisp/image.el (unknown-image-type): New error.
(image-type): Signal that error so that image-mode can offer
sensible feedback to the user.
This commit is contained in:
Lars Ingebrigtsen 2019-10-29 21:42:33 +01:00
parent 1997e3b80f
commit 19c98f7620
5 changed files with 128 additions and 69 deletions

View file

@ -215,6 +215,9 @@ The message is @samp{Wrong number of arguments}. @xref{Argument List}.
@item wrong-type-argument
The message is @samp{Wrong type argument}. @xref{Type Predicates}.
@item unknown-image-type
The message is @samp{Cannot determine image type}. @xref{Images}.
@end table
@ignore The following seem to be unused now.

View file

@ -2933,6 +2933,9 @@ data about creation times and orientation and the like.
'exif-parse-file' and 'exif-parse-buffer' are the main interface
functions.
*** 'image-mode' now uses this library to automatically rotate images
according to the orientation in the Exif data, if any.
*** New library image-converter.
If you need to view exotic image formats for which Emacs doesn't have
native support, customize the new user option
@ -2940,8 +2943,9 @@ native support, customize the new user option
GraphicsMagick, ImageMagick or 'ffmpeg' installed, they will then be
used to convert images automatically before displaying them.
*** 'image-mode' now uses this library to automatically rotate images
according to the orientation in the Exif data, if any.
*** 'auto-mode-alist' now includes many of the types typically
supported by the external image converters, like WEPB, BMP and ICO.
These now default to using 'image-mode'.
*** 'imagemagick-types-inhibit' disables using ImageMagick by default.
'image-mode' started using ImageMagick by default for all images

View file

@ -2847,7 +2847,51 @@ ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|CBR\\|7Z\\)\\'" . archive-mo
;; The following should come after the ChangeLog pattern
;; for the sake of ChangeLog.1, etc.
;; and after the .scm.[0-9] and CVS' <file>.<rev> patterns too.
("\\.[1-9]\\'" . nroff-mode)))
("\\.[1-9]\\'" . nroff-mode)
;; Image file types probably supported by `image-convert'.
("\\.art\\'" . image-mode)
("\\.avs\\'" . image-mode)
("\\.bmp\\'" . image-mode)
("\\.cmyk\\'" . image-mode)
("\\.cmyka\\'" . image-mode)
("\\.crw\\'" . image-mode)
("\\.dcr\\'" . image-mode)
("\\.dcx\\'" . image-mode)
("\\.dng\\'" . image-mode)
("\\.dpx\\'" . image-mode)
("\\.fax\\'" . image-mode)
("\\.hrz\\'" . image-mode)
("\\.icb\\'" . image-mode)
("\\.icc\\'" . image-mode)
("\\.icm\\'" . image-mode)
("\\.ico\\'" . image-mode)
("\\.icon\\'" . image-mode)
("\\.jbg\\'" . image-mode)
("\\.jbig\\'" . image-mode)
("\\.jng\\'" . image-mode)
("\\.jnx\\'" . image-mode)
("\\.miff\\'" . image-mode)
("\\.mng\\'" . image-mode)
("\\.mvg\\'" . image-mode)
("\\.otb\\'" . image-mode)
("\\.p7\\'" . image-mode)
("\\.pcx\\'" . image-mode)
("\\.pdb\\'" . image-mode)
("\\.pfa\\'" . image-mode)
("\\.pfb\\'" . image-mode)
("\\.picon\\'" . image-mode)
("\\.pict\\'" . image-mode)
("\\.rgb\\'" . image-mode)
("\\.rgba\\'" . image-mode)
("\\.tga\\'" . image-mode)
("\\.wbmp\\'" . image-mode)
("\\.webp\\'" . image-mode)
("\\.wmf\\'" . image-mode)
("\\.wpg\\'" . image-mode)
("\\.xcf\\'" . image-mode)
("\\.xmp\\'" . image-mode)
("\\.xwd\\'" . image-mode)
("\\.yuv\\'" . image-mode)))
"Alist of filename patterns vs corresponding major mode functions.
Each element looks like (REGEXP . FUNCTION) or (REGEXP FUNCTION NON-NIL).
\(NON-NIL stands for anything that is not nil; the value does not matter.)

View file

@ -552,76 +552,82 @@ to toggle between display as an image and display as text or hex.
Key bindings:
\\{image-mode-map}"
(interactive)
(condition-case err
(unless (display-images-p)
(error "Display does not support images"))
(major-mode-suspend)
(setq major-mode 'image-mode)
(if (not (image-get-display-property))
(progn
(unless (display-images-p)
(error "Display does not support images"))
(when (condition-case err
(progn
(image-toggle-display-image)
t)
(unknown-image-type
(image-mode-as-text)
(funcall
(if (called-interactively-p 'any) 'error 'message)
"Unknown image type; consider switching `image-use-external-converter' on")
nil)
(error
(image-mode-as-text)
(funcall
(if (called-interactively-p 'any) 'error 'message)
"Cannot display image: %s" (cdr err))
nil))
;; If attempt to display the image fails.
(if (not (image-get-display-property))
(error "Invalid image"))
(image-mode--setup-mode)))
;; Set next vars when image is already displayed but local
;; variables were cleared by kill-all-local-variables
(setq cursor-type nil truncate-lines t
image-type (plist-get (cdr (image-get-display-property)) :type))
(image-mode--setup-mode)))
(major-mode-suspend)
(setq major-mode 'image-mode)
(defun image-mode--setup-mode ()
(setq mode-name (if image-type (format "Image[%s]" image-type) "Image"))
(use-local-map image-mode-map)
(if (not (image-get-display-property))
(progn
(image-toggle-display-image)
;; If attempt to display the image fails.
(if (not (image-get-display-property))
(error "Invalid image")))
;; Set next vars when image is already displayed but local
;; variables were cleared by kill-all-local-variables
(setq cursor-type nil truncate-lines t
image-type (plist-get (cdr (image-get-display-property)) :type)))
;; Use our own bookmarking function for images.
(setq-local bookmark-make-record-function
#'image-bookmark-make-record)
(setq mode-name (if image-type (format "Image[%s]" image-type) "Image"))
(use-local-map image-mode-map)
;; Keep track of [vh]scroll when switching buffers
(image-mode-setup-winprops)
;; Use our own bookmarking function for images.
(setq-local bookmark-make-record-function
#'image-bookmark-make-record)
;; Keep track of [vh]scroll when switching buffers
(image-mode-setup-winprops)
(add-hook 'change-major-mode-hook #'image-toggle-display-text nil t)
(add-hook 'after-revert-hook #'image-after-revert-hook nil t)
(run-mode-hooks 'image-mode-hook)
(let ((image (image-get-display-property))
(msg1 (substitute-command-keys
"Type \\[image-toggle-display] or \\[image-toggle-hex-display] to view the image as "))
animated)
(cond
((null image)
(message "%s" (concat msg1 "an image.")))
((setq animated (image-multi-frame-p image))
(setq image-multi-frame t
mode-line-process
`(:eval
(concat " "
(propertize
(format "[%s/%s]"
(1+ (image-current-frame ',image))
,(car animated))
'help-echo "Frames
mouse-1: Next frame
mouse-3: Previous frame"
'mouse-face 'mode-line-highlight
'local-map
'(keymap
(mode-line
keymap
(down-mouse-1 . image-next-frame)
(down-mouse-3 . image-previous-frame)))))))
(message "%s"
(concat msg1 "text. This image has multiple frames.")))
;;; (substitute-command-keys
;;; "\\[image-toggle-animation] to animate."))))
(t
(message "%s" (concat msg1 "text or hex."))))))
(error
(image-mode-as-text)
(funcall
(if (called-interactively-p 'any) 'error 'message)
"Cannot display image: %s" (cdr err)))))
(add-hook 'change-major-mode-hook #'image-toggle-display-text nil t)
(add-hook 'after-revert-hook #'image-after-revert-hook nil t)
(run-mode-hooks 'image-mode-hook)
(let ((image (image-get-display-property))
(msg1 (substitute-command-keys
"Type \\[image-toggle-display] or \\[image-toggle-hex-display] to view the image as "))
animated)
(cond
((null image)
(message "%s" (concat msg1 "an image.")))
((setq animated (image-multi-frame-p image))
(setq image-multi-frame t
mode-line-process
`(:eval
(concat " "
(propertize
(format "[%s/%s]"
(1+ (image-current-frame ',image))
,(car animated))
'help-echo "Frames\nmouse-1: Next frame\nmouse-3: Previous frame"
'mouse-face 'mode-line-highlight
'local-map
'(keymap
(mode-line
keymap
(down-mouse-1 . image-next-frame)
(down-mouse-3 . image-previous-frame)))))))
(message "%s"
(concat msg1 "text. This image has multiple frames.")))
(t
(message "%s" (concat msg1 "text or hex."))))))
;;;###autoload
(define-minor-mode image-minor-mode

View file

@ -151,6 +151,8 @@ or \"ffmpeg\") is installed."
:type 'boolean
:version "27.1")
(define-error 'unknown-image-type "Unknown image type")
;; Map put into text properties on images.
(defvar image-map
(let ((map (make-sparse-keymap)))
@ -391,7 +393,7 @@ Optional DATA-P non-nil means SOURCE is a string containing image data."
(require 'image-converter)
(image-convert-p source))))))
(unless type
(error "Cannot determine image type")))
(signal 'unknown-image-type "Cannot determine image type")))
(when (and (not (eq type 'image-convert))
(not (memq type (and (boundp 'image-types) image-types))))
(error "Invalid image type `%s'" type))