(eval-when-compile (require 'cl))
(defvar extview-application-associations nil
"List of (REGEXP . HANDLER) descriptors which are tested for the
file name to be opened. The first matching handler is used to open
the file. If no handler matches then an attempt is made to use
mailcap to open the file.
If no handler is found normal `find-file' is executed.
If HANDLER is nil then the file is opened normally regardless if
it has a mailcap entry.
If HANDLER is the symbol `ask' then the user has to decide whether the
file is to be opened in emacs or with an external viewer.
This variable is normally used to override mailcap handlers.")
(defadvice find-file (around extview-find-file
(filename &optional wildcards) activate)
"Around advice for find-file which checks if the file should be
opened with an external viewer instead of Emacs."
(interactive "FFind file: \np")
(let ((handler (some (lambda (descriptor)
(if (string-match (car descriptor) filename)
(if (and handler
(not (and (eq 'ask (cdr handler))
(y-or-n-p "Open with external viewer? "))))
(if (eq (cdr handler) 'ask)
(setq handler nil)
(setq handler (cdr handler)))
(let* ((ext (file-name-extension filename))
(mime (if ext
(setq handler (mailcap-mime-info mime)))
(unless (stringp handler)
(setq handler nil))))
(let* ((logbuffer "*extview log*")
(components (split-string handler))
(app (car components))
(args (mapcar (lambda (arg)
(if (or (equal "%s" arg)
(equal "'%s'" arg))
(insert (format "Opening file %s with handler: %s"
(apply 'start-process "extview-process" logbuffer app args)
(message (concat "File is opened with an external viewer. "
"See buffer %s for status messages.")