Subject: bug#14110: 24.3.50; Add command to open files outside of Emacs (use xdg-open, open etc)

From: Jambunathan K <[email-masked]>
Date: Mon, 01 Apr 2013 12:27:58 +0530

Add support for opening files outside of Emacs (use xdg-open, open etc).
This is something that I sorely missed or continue to miss.

Here is an (initial) patch...

=== modified file 'lisp/ChangeLog'
--- lisp/ChangeLog	2013-03-31 15:19:19 +0000
+++ lisp/ChangeLog	2013-04-01 06:50:35 +0000
@@ -1,3 +1,13 @@
+2013-04-01  Jambunathan K  <[email-masked]>
+
+	* files.el (open-file-command): New user option.
+	(open-file): New command.
+	(ctl-x-map): Bind it to `C-S-f'.
+
+	* dired-aux.el (dired-do-open): New command
+
+	* dired.el (dired-mode-map): Bind it to `C-S-f'.
+
 2013-03-31  Roland Winkler  <[email-masked]>
 
 	* emacs-lisp/crm.el (completing-read-multiple): Doc fix.

=== modified file 'lisp/dired-aux.el'
--- lisp/dired-aux.el	2013-02-28 21:51:11 +0000
+++ lisp/dired-aux.el	2013-04-01 05:44:57 +0000
@@ -426,6 +426,18 @@ Uses the shell command coming from varia
 		   'print arg file-list)))
     (dired-run-shell-command (dired-shell-stuff-it command file-list nil))))
 
+;;;###autoload
+(defun dired-do-open (&optional arg)
+  "Open the marked (or next ARG) files (presumably) outside of Emacs.
+Use shell command coming from variable `open-file-command' to
+open the file."
+  (interactive "P")
+  (let* ((file-list (dired-get-marked-files t arg))
+	 (command (dired-mark-read-string "Open %s with: " 
+					  (eval (cadr (assq system-type open-file-command)))
+					  t arg file-list)))
+    (dired-run-shell-command (dired-shell-stuff-it command file-list t))))
+
 (defun dired-mark-read-string (prompt initial op-symbol arg files
 			       &optional default-value collection)
   "Read args for a Dired marked-files command, prompting with PROMPT.

=== modified file 'lisp/dired.el'
--- lisp/dired.el	2013-02-28 21:51:11 +0000
+++ lisp/dired.el	2013-04-01 06:52:10 +0000
@@ -1426,6 +1426,7 @@ Do so according to the former subdir ali
     (define-key map "C" 'dired-do-copy)
     (define-key map "B" 'dired-do-byte-compile)
     (define-key map "D" 'dired-do-delete)
+    (define-key map [33554438] 'dired-do-open) ; C-S-f
     (define-key map "G" 'dired-do-chgrp)
     (define-key map "H" 'dired-do-hardlink)
     (define-key map "L" 'dired-do-load)
@@ -3958,6 +3959,13 @@ Uses the shell command coming from varia
 
 \(fn &optional ARG)" t nil)
 
+(autoload 'dired-do-open "dired-aux" "\
+Open the marked (or next ARG) files (presumably) outside of Emacs.
+Use shell command coming from variable `open-file-command' to
+open the file.
+
+\(fn &optional ARG)" t nil)
+
 (autoload 'dired-clean-directory "dired-aux" "\
 Flag numerical backups for deletion.
 Spares `dired-kept-versions' latest versions, and `kept-old-versions' oldest.

=== modified file 'lisp/files.el'
--- lisp/files.el	2013-03-24 06:42:25 +0000
+++ lisp/files.el	2013-04-01 06:05:45 +0000
@@ -6805,6 +6805,54 @@ Otherwise, trash FILENAME using the free
 		   (rename-file fn new-fn)))))))))
 
 
+;; Open files outside of Emacs
+(defcustom open-file-command '((gnu "xdg-open *")
+			       (gnu/linux "xdg-open *")
+			       (gnu/kfreebsd "xdg-open *")
+			       (darwin "open *")
+			       (windows-nt "open *")
+			       (cygwin "open *")
+			       (ms-dos nil))
+  "Shell commands for opening files generically.
+
+Each element of this list looks like
+
+    (SYSTEM-TYPE COMMAND...)
+
+SYSTEM-TYPE is one of `system-type's.
+
+COMMAND can either be a string or a Lisp expression that
+evaluates to a string.  It follows the same semantics as the
+COMMAND param of `dired-do-shell-command'."
+	    :type '(alist :key-type symbol :value-type (group sexp)
+			  :options ((gnu "xdg-open &")
+				    (gnu/linux "xdg-open &")
+				    (gnu/kfreebsd "xdg-open &")
+				    (darwin "open &")
+				    (windows-nt "open &")
+				    (cygwin "open &")
+				    (ms-dos nil)))
+	    :version "24.4"
+	    :group 'file)
+
+(eval-when-compile
+  (require 'dired-aux))
+
+(defun open-file (filename)
+  "Open FILENAME (presumably) outside of Emacs.
+Use shell command from `open-file-command' to open the file."
+  (interactive "fOpen file:")
+  (require 'dired-aux)
+  (let* ((default-directory (file-name-directory filename))
+	 (filename (file-name-nondirectory filename))
+	 (command (or (eval (cadr (assq system-type open-file-command)))
+		      (read-shell-command (format "Open %s with: " filename) nil 
+					  'dired-shell-command-history))))
+    (when (and command (string-match "\\S-" command))
+      (dired-run-shell-command (dired-shell-stuff-it command (list filename) t)))))
+
+
+(define-key ctl-x-map [33554438] 'open-file) ; C-x C-S-f
 (define-key ctl-x-map "\C-f" 'find-file)
 (define-key ctl-x-map "\C-r" 'find-file-read-only)
 (define-key ctl-x-map "\C-v" 'find-alternate-file)

In GNU Emacs 24.3.50.7 (i686-pc-linux-gnu, GTK+ Version 2.20.1)
 of 2013-04-01 on debian-6.05
Bzr revision: 112204 [email-masked]
Windowing system distributor `The X.Org Foundation', version 11.0.10707000
Important settings:
  value of $LANG: en_IN
  locale-coding-system: iso-latin-1-unix
  default enable-multibyte-characters: t