;;; w32-browser.el --- Run Windows application associated with a file. ;; ;; Filename: w32-browser.el ;; Description: Run Windows application associated with a file. ;; Author: Emacs Wiki, Drew Adams ;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com") ;; Copyright (C) 2004-2018, Drew Adams, all rights reserved. ;; Created: Thu Mar 11 13:40:52 2004 ;; Version: 0 ;; Package-Requires: () ;; Last-Updated: Mon Jan 1 16:19:17 2018 (-0800) ;; By: dradams ;; Update #: 246 ;; URL: https://www.emacswiki.org/emacs/download/w32-browser.el ;; Doc URL: https://emacswiki.org/emacs/MsShellExecute ;; Keywords: mouse, dired, w32, explorer ;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x, 24.x, 25.x, 26.x ;; ;; Features that might be required by this library: ;; ;; None ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Commentary: ;; ;; Run Windows application associated with a file. ;; ;; Functions `w32-browser' & `dired-w32-browser' were originally from ;; code posted on EmacsWiki (author unknown). ;; ;; Modified `w32-browser' to invoke `find-file' if it cannot use ;; `w32-shell-execute'. Modified `dired-multiple-w32-browser' to use ;; `w32-browser-wait-time'. Wrote `dired-mouse-w32-browser', ;; `w32explore', `dired-w32explore', and `dired-mouse-w32explore'. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Change Log: ;; ;; 2016/08/14 dadams ;; dired-mouse-w32-browser*: No-op if event is not in a window. ;; 2012/03/10 dadams ;; dired-w32-browse(-reuse-dir-buffer), w32explore: ;; Use subst-char-in-string, not dired-replace-in-string or substitute. ;; 2010/01/21 dadams ;; Added: dired(-mouse)-w32-browser-reuse-dir-buffer. ;; 2010/01/12 dadams ;; dired-mouse-w32-browser, dired-mouse-w32explore: ;; save-excursion + set-buffer -> with-current-buffer. ;; 2008/09/22 dadams ;; dired(-mouse)-w32(-browser|explore): Use t as 2nd arg for dired-get-filename. ;; 2008/07/18 dadams ;; Added: (dired-(mouse-))w32explore. ;; No longer require dired+.el - do it the other way around. ;; No longer make any bindings here. Do it only in dired+.el. ;; Made w32-browser interactive. ;; 2006/01/02 dadams ;; Added: w32-browser-wait-time, soft require of dired+.el. ;; Uncommented and updated dired-multiple-w32-browser and its binding. ;; Thanks to Mathias Dahl for recognizing this actually works. ;; Conditionalized dired+ vs standard dired in bindings. ;; 2005/11/05 dadams ;; Renamed menu-bar-dired-immediate-menu to diredp-menu-bar-immediate-menu. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth ;; Floor, Boston, MA 02110-1301, USA. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Code: ;;;;;;;;;;;;;;;;;;;;;; (when (eq system-type 'windows-nt) (defcustom w32-browser-wait-time 0.1 "*Delay to wait between `w32-browser' in `dired-multiple-w32-browser'. On at least some Windows systems, this delay is needed between calls to `w32-browser' within command `dired-multiple-w32-browser'. Depending on your system, you might be able to set this to 0, meaning no wait." :type 'integer :group 'convenience) (defun w32-browser (file) "Run default Windows application associated with FILE. If no associated application, then `find-file' FILE." (interactive "fFile: ") (or (condition-case nil (w32-shell-execute nil file) ; Use Windows file association (error nil)) (find-file file))) ; E.g. no Windows file association (defun dired-w32-browser () "Run default Windows application associated with current line's file. If file is a directory, then `dired-find-file' instead. If no application is associated with file, then `find-file'." (interactive) (let ((file (dired-get-filename nil t))) (if (file-directory-p file) (dired-find-file) (w32-browser (subst-char-in-string ?/ ?\\ file))))) (defun dired-mouse-w32-browser (event) "Run default Windows application associated with file under mouse. If file is a directory or no application is associated with file, then `find-file' instead." (interactive "e") (let ((win (posn-window (event-end event))) file) (when (windowp win) ; E.g. press but move mouse out of any window. (with-current-buffer (window-buffer win) (save-excursion (goto-char (posn-point (event-end event))) (setq file (dired-get-filename nil t)))) (select-window (posn-window (event-end event))) (if (file-directory-p file) (find-file (file-name-sans-versions file t)) (w32-browser (file-name-sans-versions file t)))))) (defun dired-w32-browser-reuse-dir-buffer () "Like `dired-w32-browser', but reuse Dired buffers." (interactive) (let ((file (dired-get-filename nil t))) (if (file-directory-p file) (find-alternate-file file) (w32-browser (subst-char-in-string ?/ ?\\ file))))) (defun dired-mouse-w32-browser-reuse-dir-buffer (event) "Like `dired-mouse-w32-browser', but reuse Dired buffers." (interactive "e") (let ((win (posn-window (event-end event))) file) (when (windowp win) ; E.g. press but move mouse out of any window. (with-current-buffer (window-buffer win) (save-excursion (goto-char (posn-point (event-end event))) (setq file (dired-get-filename nil t)))) (select-window (posn-window (event-end event))) (if (file-directory-p file) (find-alternate-file (file-name-sans-versions file t)) (w32-browser (file-name-sans-versions file t)))))) (defun dired-multiple-w32-browser () "Run default Windows applications associated with marked files." (interactive) (let ((files (dired-get-marked-files))) (while files (w32-browser (car files)) (sleep-for w32-browser-wait-time) (setq files (cdr files))))) (defun w32explore (file) "Open Windows Explorer to FILE (a file or a folder)." (interactive "fFile: ") (let ((w32file (subst-char-in-string ?/ ?\\ (expand-file-name file)))) (if (file-directory-p w32file) (w32-shell-execute "explore" w32file "/e,/select,") (w32-shell-execute "open" "explorer" (concat "/e,/select," w32file))))) (defun dired-w32explore () "Open Windows Explorer to current file or folder." (interactive) (w32explore (dired-get-filename nil t))) (defun dired-mouse-w32explore (event) "Open Windows Explorer to file or folder under mouse." (interactive "e") (let (file) (with-current-buffer (window-buffer (posn-window (event-end event))) (save-excursion (goto-char (posn-point (event-end event))) (setq file (dired-get-filename nil t)))) (select-window (posn-window (event-end event))) (w32explore file))) ;;; This doesn't work, nor do other variants. ;;; Apparently, /select can specify only one file, and only one /select can be used. ;;; (defun dired-multiple-w32explore () ;;; "Open Windows Explorer to current directory, with marked files selected." ;;; (interactive) ;;; (let ((files (dired-get-marked-files))) ;;; (w32-shell-execute ;;; "open" "explorer" ;;; (concat "/e,/select," (mapconcat (lambda (f) ;;; (substitute ?\\ ?/ (expand-file-name f))) ;;; files ","))))) ;;; No longer make any bindings here. Do it only in `dired+.el'. ;;; (if (boundp 'diredp-menu-bar-immediate-menu) ; Use Dired+ if loaded. ;;; (eval-after-load "dired+" ;;; '(progn ;;; (define-key dired-mode-map [f3] 'dired-w32-browser) ;;; (define-key dired-mode-map [f4] 'dired-w32explore) ;;; (define-key diredp-menu-bar-immediate-menu [dired-w32-browser] ;;; '("Open Associated Application" . dired-w32-browser)) ;;; (define-key diredp-menu-bar-immediate-menu [dired-w32explore] ;;; '("Open in Windows Explorer" . dired-w32explore)) ;;; (define-key dired-mode-map [mouse-2] 'dired-mouse-w32-browser) ;;; (define-key diredp-menu-bar-operate-menu [dired-w32-browser] ;;; '("Open Associated Applications" . dired-multiple-w32-browser)))) ;;; (eval-after-load "dired" ;;; '(progn ;;; (define-key dired-mode-map [f3] 'dired-w32-browser) ;;; (define-key dired-mode-map [f4] 'dired-w32explore) ;;; (define-key dired-mode-map [menu-bar immediate dired-w32-browser] ;;; '("Open Associated Application" . dired-w32-browser)) ;;; (define-key diredp-menu-bar-immediate-menu [dired-w32explore] ;;; '("Windows Explorer" . dired-w32explore)) ;;; (define-key dired-mode-map [mouse-2] 'dired-mouse-w32-browser) ;;; (define-key dired-mode-map [menu-bar immediate dired-w32-browser] ;;; '("Open Associated Applications" . dired-multiple-w32-browser))))) ) ;;;;;;;; (provide 'w32-browser) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; w32-browser.el ends here