I\'m trying to tweak the dired-find-file
function in emacs on Windows XP so that when I open (say) a pdf file from dired it fires up a copy of Acrobat Reader and op
Use Dired+ for this, along with w32-browser.el
C-RET opens the current-line's file using its Windows file-association application.
M-RET opens Windows Explorer to the file or folder
^, when in a root directory (e.g. C:\
), moves up to a Dired-like list of all Windows drives (local and remote).
The commands for the first two are available from w32-browser.el
. (Dired+ binds them to those keys.) The command for the third is from Dired+.
I have this in my .emacs:
(setq dired-guess-shell-alist-user
(list
(list "\\.*$" "cmd /k")
))
This will open the file using cmd.exe which will use whatever program is associated with the file extension. Tested to work on Windows 8 and GNU Emacs 24.2.1.
I found this terrific web page via google, which let me to a technique using RunDll that works. I'm putting it up here in case anyone else is curious.
Here is the key piece of code, which opens filename
using the appropriate application:
(shell-command (concat "rundll32 shell32,ShellExec_RunDLL " (shell-quote-argument filename)))
And here is my full solution. (Note that dired-find-file
is just a wrapper round find-file
which doesn't know the filename, so that you have to advise find-file
rather than dired-find-file
as in the question. If you don't want the behaviour for find-file
you will probably need to rewrite dired-find-file
or write more complicated advice.)
(defun open-externally (filename)
(shell-command (concat "rundll32 shell32,ShellExec_RunDLL " (shell-quote-argument filename))))
(defun is-file-type? (filename type)
(string= type (substring filename (- (length filename) (length type)))))
(defun should-open-externally? (filename)
(let ((file-types '(".pdf" ".doc" ".xls")))
(member t (mapcar #'(lambda (type) (is-file-type? filename type)) file-types))))
(defadvice find-file (around find-file-external-file-advice (filename &optional wildcards))
"Open non-emacs files with an appropriate external program"
(if (should-open-externally? filename)
(open-externally filename)
ad-do-it))
(ad-activate 'find-file)
org-open-file
is a system independent external opener. See org-file-apps
for how to customize it further.
With point on file, pressing F3 will open the file based on the windows extension.
(defun w32-browser (doc) (w32-shell-execute 1 doc))
(eval-after-load "dired" '(define-key dired-mode-map [f3] (lambda () (interactive) (w32-browser (dired-replace-in-string "/" "\\" (dired-get-filename))))))
I'd use (w32-shell-execute "open" file-name)
.
In fact, in my init file I have:
(defun open-externally (file-name)
(interactive "fOpen externally: ")
(let ((process-connection-type nil))
(start-process "open-externally" nil
"xdg-open" file-name)))
(when (eq window-system 'w32)
(defun open-externally (file-name)
(interactive "fOpen externally: ")
(w32-shell-execute "open" file-name)))
Which defines a command that (may be used interactively and) opens a file with the default application according to xdg-open
and then, if I'm actually on Windows, redefines that command appropriately.