;;;; alt-dired-view.el --- alternative 'view' command for dired ;;; This file replaces Dired Mode's 'dired-view-file' command (bound ;;; to 'v') with a function that checks the filename against an alist ;;; of regular expressions to find special handler functions for ;;; certain types of files, and falls back to view-mode if no alist ;;; element applies. (require 'dired) ;;; Make sure Dired defined the function we're going to override. (if (not (fboundp 'dired-view-file)) (error "alt-dired-view: dired did not define 'dired-view-file'")) (defvar dired-view-handler-alist '(("\\.pdf$" . dired-view-pdf)) "An alist mapping regular expressions to 'dired-view-file' handlers. This is a list of (REGEXP . FUNCTION) pairs, where REGEXP is the regular expression, and FUNCTION is the symbol naming the function to apply to the filename to view the file, if it matches REGEXP.") (defvar dired-view-pdf-command "evince" "The program to run to view Adobe Portable Document Format (PDF) files. We search the directories given in PATH for this program.") (defvar dired-view-pdf-switches nil "Switches to pass to `dired-view-pdf-command'.") (defvar dired-view-pdf-x-display-switch "--display" "Switch to pass to `dired-view-pdf-command' to select an X display.") (defun dired-view-file () "In dired, examine a file in view mode, returning to dired when done. When file is a directory, show it in this buffer if it is inserted; otherwise, display it in another buffer. If the name of the file matches an entry in `dired-view-handler-alist', then apply the corresponding function to the current filename, instead of viewing the file in view mode." (interactive) (let ((filename (dired-get-filename)) handler-pair) (cond ((file-directory-p filename) (or (and (cdr dired-subdir-alist) (dired-goto-subdir filename)) (dired filename))) ((setq handler-pair (alt-dired-filename-assoc filename dired-view-handler-alist)) (funcall (cdr handler-pair) filename)) (t (view-file (dired-get-filename)))))) (defun alt-dired-filename-assoc (filename alist) "Return the first pair in ALIST whose car matches FILENAME. Matching is done as appropriate for filenames: we remove backup suffixes, and ignore case on VAX/VMS and Windows NT." ;; Remove backup-suffixes from file name. (setq filename (file-name-sans-versions filename)) (let ((case-fold-search (memq system-type '(vax-vms windows-nt))) match) (while (and (not match) alist) (if (string-match (car (car alist)) filename) (setq match (car alist))) (setq alist (cdr alist))) match)) (defun dired-view-pdf (filename) "Start up an Adobe Portable Document Format (PDF) viewer on FILENAME. The variable `dired-view-pdf-command' is the command to run, and `dired-view-pdf-switches' are the switches to pass to it. The filename is passed as the last argument." (or (file-exists-p filename) (error "dired-view-pdf: file does not exist: %s" filename)) (or (file-readable-p filename) (error "dired-view-pdf: cannot read file: %s" filename)) (message "Running %S..." (append (list dired-view-pdf-command) dired-view-pdf-switches (list filename))) (apply 'call-process dired-view-pdf-command nil 0 nil (append dired-view-pdf-switches (let ((display (frame-parameter nil 'display))) (if display (list dired-view-pdf-x-display-switch display))) ;; If we're running on an X frame, make sure the ;; viewer runs on the same screen as the current ;; frame. (list filename)))) (provide 'alt-dired-view)