Skip to content

Instantly share code, notes, and snippets.

@myuhe
Last active December 20, 2015 14:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save myuhe/6146483 to your computer and use it in GitHub Desktop.
Save myuhe/6146483 to your computer and use it in GitHub Desktop.
(defun image-mode ()
"Major mode for image files.
You can use \\<image-mode-map>\\[image-toggle-display]
to toggle between display as an image and display as text."
(interactive)
(condition-case err
(progn
(unless (display-images-p)
(error "Display does not support images"))
(kill-all-local-variables)
(setq major-mode 'image-mode)
(setq image-transform-resize 'fit-height)
(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)))
(setq mode-name (if image-type (format "Image[%s]" image-type) "Image"))
(use-local-map image-mode-map)
;; 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] 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."))))))
(error
(image-mode-as-text)
(funcall
(if (called-interactively-p 'any) 'error 'message)
"Cannot display image: %s" (cdr err)))))
(defun image-toggle-display-image ()
"Show the image of the image file.
Turn the image data into a real image, but only if the whole file
was inserted."
(unless (derived-mode-p 'image-mode)
(error "The buffer is not in Image mode"))
(let* ((filename (buffer-file-name))
(data-p (not (and filename
(file-readable-p filename)
(not (file-remote-p filename))
(not (buffer-modified-p))
(not (and (boundp 'archive-superior-buffer)
archive-superior-buffer))
(not (and (boundp 'tar-superior-buffer)
tar-superior-buffer)))))
(file-or-data (if data-p
(string-make-unibyte
(buffer-substring-no-properties (point-min) (point-max)))
filename))
(type (image-type file-or-data nil data-p))
(image (create-image file-or-data 'imagemagick data-p))
(inhibit-read-only t)
(buffer-undo-list t)
(modified (buffer-modified-p))
props)
;; Discard any stale image data before looking it up again.
(image-flush image)
(setq image (append image (image-transform-properties image)))
(setq props
`(display ,image
;; intangible ,image
rear-nonsticky (display) ;; intangible
read-only t front-sticky (read-only)))
(let ((buffer-file-truename nil)) ; avoid changing dir mtime by lock_file
(add-text-properties (point-min) (point-max) props)
(restore-buffer-modified-p modified))
;; Inhibit the cursor when the buffer contains only an image,
;; because cursors look very strange on top of images.
(setq cursor-type nil)
;; This just makes the arrow displayed in the right fringe
;; area look correct when the image is wider than the window.
(setq truncate-lines t)
;; Disable adding a newline at the end of the image file when it
;; is written with, e.g., C-x C-w.
(if (coding-system-equal (coding-system-base buffer-file-coding-system)
'no-conversion)
(setq-local find-file-literally t))
;; Allow navigation of large images.
(setq-local auto-hscroll-mode nil)
(setq image-type type)
(if (eq major-mode 'image-mode)
(setq mode-name (format "Image[%s]" type)))
(image-transform-check-size)
(if (called-interactively-p 'any)
(message "Repeat this command to go back to displaying the file as text"))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment