From 5c9315b201beb4660f727dcc8045ec375ab56f70 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Wed, 6 Dec 2023 19:28:52 +0200 Subject: [PATCH] * lisp/dired-aux.el (dired-do-open): New command (bug#18132). * lisp/dired.el (dired-context-menu): Bind 'dired-do-open' to "Open". * lisp/dired-aux.el (shell-command-guess-xdg): Use 'shell-quote-argument'. --- etc/NEWS | 4 ++++ lisp/dired-aux.el | 36 +++++++++++++++++++++++++++++++++++- lisp/dired.el | 6 ++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/etc/NEWS b/etc/NEWS index 29f4e5c0b66..c55719416d3 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -511,6 +511,10 @@ based on marked files in Dired. Possible backends are and a universal command such as "open" or "start" that delegates to the OS. +*** New command 'dired-do-open'. +Bound to the context menu "Open", delegates opening the marked files +to the OS. + ** Ediff --- diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 1a17ed749e8..0998e76c410 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -1367,7 +1367,8 @@ after adding own commands to the composite list." (let* ((xdg-mime (when (executable-find "xdg-mime") (string-trim-right (shell-command-to-string - (concat "xdg-mime query filetype " (car files)))))) + (concat "xdg-mime query filetype " + (shell-quote-argument (car files))))))) (xdg-mime-apps (unless (string-empty-p xdg-mime) (xdg-mime-apps xdg-mime))) (xdg-commands @@ -1401,6 +1402,39 @@ after adding own commands to the composite list." "Populate COMMANDS by the `open' command." (append (ensure-list shell-command-guess-open) commands)) +(declare-function w32-shell-execute "w32fns.c") + +(defun dired-do-open (&optional arg) + "Open the marked files or a file at click/point externally. +If files are marked, run the command from `shell-command-guess-open' +on each of marked files. Otherwise, run it on the file where +the mouse is clicked, or on the file at point." + (interactive "P" dired-mode) + (let ((files (if (mouse-event-p last-nonmenu-event) + (save-excursion + (mouse-set-point last-nonmenu-event) + (dired-get-marked-files nil arg)) + (dired-get-marked-files nil arg))) + (command shell-command-guess-open)) + (when (and (memq system-type '(windows-nt)) + (equal command "start")) + (setq command "open")) + (when command + (dolist (file files) + (cond + ((memq system-type '(gnu/linux)) + (call-process command nil 0 nil file)) + ((memq system-type '(ms-dos)) + (shell-command (concat command " " (shell-quote-argument file)))) + ((memq system-type '(windows-nt)) + (w32-shell-execute command (convert-standard-filename file))) + ((memq system-type '(cygwin)) + (call-process command nil nil nil file)) + ((memq system-type '(darwin)) + (start-process (concat command " " file) nil command file)) + (t + (error "Open not supported on this system"))))))) + ;;; Commands that delete or redisplay part of the dired buffer diff --git a/lisp/dired.el b/lisp/dired.el index 97645c731c8..7f4b96353ee 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -2591,6 +2591,9 @@ Do so according to the former subdir alist OLD-SUBDIR-ALIST." ["Delete Image Tag..." image-dired-delete-tag :help "Delete image tag from current or marked files"])) +(declare-function shell-command-guess "dired-aux" (files)) +(defvar shell-command-guess-open) + (defun dired-context-menu (menu click) "Populate MENU with Dired mode commands at CLICK." (when (mouse-posn-property (event-start click) 'dired-filename) @@ -2606,6 +2609,9 @@ Do so according to the former subdir alist OLD-SUBDIR-ALIST." :help "Edit file at mouse click"] ["Find in Other Window" dired-mouse-find-file-other-window :help "Edit file at mouse click in other window"] + ,@(when shell-command-guess-open + '(["Open" dired-do-open + :help "Open externally"])) ,@(when commands (list (cons "Open With" (append -- 2.39.2