viewing images inside emacs

Emacs has an image-mode that you can use to view images fairly easily, providing they've already been scaled down (e.g. for web use): it doesn't have the automatic rescaling features of something like gthumb, so in practice I end up switching back and forth between the two of them as convenient.

The nice thing about image-mode is that it comes up faster -- when things are working well. Myself, I live inside of emacs, so for me dired is the primary way I want to view a directory full of image files, and of course, I need to frequently jump from there to some sort of image viewer.

The caveat about "when things are working well" is there because I find that when my emacs has been up for a long time (and myself, I leave them up for weeks on end on my workstation) image-mode starts bogging down. Until I understand that problem better, I just try to remember to use a fresh emacs for these purposes.

There are enough small inconviencies about this though, that I've begun work on my own emacs lisp packages to fix them: image-dired.el and dired-external-apps.el.

image-dired.el

Just quoting the internal documentation for image-dired.el:

This package adds some commands to the image-mode keymap to simplify working with image files from a dired buffer. With version 22 of GNU emacs, an image display feature was added so that inside of dired you can hit the return key on an image file name, it will display the image inside of emacs in image-mode. The image-dired package adds some features, so that once an image is displayed, you can step forward or back through the other images in the directory by hitting space or backspace (or if you prefer 'n' and 'p' or 'C-n' and 'C-p').

Hitting return again will then exit you out of image-mode, returning to dired, with the cursor positioned on the name of the last displayed image file.

Additionally, the dired commands to mark files or to flag files for deletion are supported while the image is displayed, bound to the usual 'm'/'u' and 'd' keys

If you have the dired-external-apps package installed, and you have enabled the feature to save the file name and path to some user registers and to the kill-ring, you will find that with the image-dired feature these features are also automatically supported.

Usage:

Put the file image-dired.el into your load-path and the following into your ~/.emacs:

  (require 'image-dired)
  (image-dired-standard-keymap-changes)
If you want the dired-external-apps features, you should also do this:
  (require 'dired-external-apps)
  (setq dired-external-apps-save-to-registers-flag t)

dired-external-apps.el

Just quoting the internal documentation for the dired-external-apps package:

This package provides functions to do multiple asynchronous launches of external applications, and to simplify launching applications from dired, particularly in the case where there's no single association between an application and a file extension.

Synopsis of usage:

Put the file dired-external-apps.el in one of your load-path locations, and add the following to your ~/.emacs:

   (require 'dired-external-apps)
Add any applications/wrapper scripts you might want to use from dired that aren't already included:
  (setq dired-external-apps-list (cons "xw3m" dired-external-apps-list ))
  (setq dired-external-apps-list (cons "xlynx" dired-external-apps-list ))
  (dired-external-apps-generate-wrapper-functions-for-apps) ;; reinitialize after changes
To enable the side-effect of saving file information:
  (setq dired-external-apps-save-to-registers-flag t)
Most likely you will also want to add some keybindings, for example:
  (add-hook 'dired-mode-hook
    '(lambda ()
     (define-key dired-mode-map
       "o"
       'dired-external-apps-open-with-gthumb)
     (define-key dired-mode-map
       [return]
       'dired-external-apps-open-with-emacs) ; i.e. inside of emacs in image-mode
     (define-key dired-mode-map
       "\\C-o"
       'dired-external-apps-open-with-gthumb)
     (define-key dired-mode-map
       "\\-"
       'dired-external-apps-open-with-gimp)
     ))

A brief tutorial:

With the above suggested set-up, working in dired with image files can be simplified. Typically, one might want to view, rotate or crop a jpeg, but each of these operations is probably best handled by a different program. Hitting the "o" key will launch gthumb opening the current file, hitting the "-" will launch gimp, and if you hit RETURN the image will be opened inside of emacs in an image-mode buffer.

(Note: for improvements in working with image-mode, see the related package image-mode-dired.el)

As a side-effect, opening a file with one of these commands also places the file information in some user registers, and on to the kill-ring (though only if dired-external-apps-save-to-registers-flag has been set). The register "n" will have the file name, the register "p" will have the path to the file, and the kill-ring will have the file name (sans path) pushed on to it.

This greatly simplifies doing other operations on the file after viewing the image: for example, if you rename it with dired-do-rename (bound by default to "R"), you can begin by yanking the current file name (C-y) to have a starting point to edit. Other uses include manual operations in a shell, emailing the file name, or just making notes about it. For hints about using emacs registers with this package see dired-external-apps-documentation-appendix-registers.

All of these external application launches are done in a special sub-shell named: \{dired-external-apps-shell-buffer}, so if there seems to be a problem with them, you should look in that buffer for any relevant error messages.

Emacs has a series of "registers" with single-character names available for use, primarily by the user. As a convenience, some routines here places some information in these registers for later use (though only if dired-external-apps-save-to-registers-flag has been set). The path of the last file accessed goes in register "p", and the file name goes in "n".

By default, the register commands all use the same "C-x r" prefix. To insert the contents of register "p", you would do a "C-x r i p". You can simplify that operation by re-binding this to the otherwise underused "insert" key with this in your .emacs file:

   (global-set-key [insert] 'insert-register)
If you dislike the choices of registers "p" and "n", you can change them by modifying dired-external-apps-path-register and/or dired-external-apps-name-register. For example, to use uppercase "P" instead of "p", add this to your .emacs file:
   (setq dired-external-apps-path-register ?P)


Joseph Brenner, 26 Jun 2009