1

I'm running emacs on WSL.

The following function launches the binary file marked in dired:

(defun wsl/execute ()
  "execute file at point in dired"
  (interactive)
  (dired-do-shell-command
   "cmd.exe /c start \"\""
   current-prefix-arg
   (dired-get-marked-files t current-prefix-arg)))

I would like to use dired-get-file-for-visit instead of dired-get-marked-files to skip the marking.

My attempt at this does not work:

(defun wsl/execute ()
  "execute file at point in dired"
  (interactive)
  (dired-do-shell-command
   "cmd.exe /c start \"\""
   current-prefix-arg
   (list (dired-get-file-for-visit))))

With the latter and /e/Downloads/AnyDesk.exe I get Invalid switch - "/e".^M

What am I missing from the second implementation?

UPDATE

For posterity, here are the final functions I'm using

(defun wsl/execute ()
  "execute file at point in dired"
  (interactive)
  (dired-do-shell-command
   "cmd.exe /c start \"\""
   current-prefix-arg
   (dired-get-marked-files t t)))

Enter on file to launch it or open it:

(defun wsl-p ()
  "Is the system WSL?"
  (and (eq system-type 'gnu/linux)
       (string-match
        "Linux.*Microsoft.*Linux"
        (shell-command-to-string "uname -a"))))

(defun dired-find-file-or-execute (orig-fun &rest args)
  "Wrapper for dired-find-file that, on WSL, launches binaries instead of opening them"
  (interactive)
  (let ((file (dired-get-marked-files t t)))
    (if
        (and
         (wsl-p)
         (or (string-match-p "\.exe\\'" (first file))
             (string-match-p "\.bat\\'" (first file))
             (string-match-p "\.com\\'" (first file))))
        (dired-do-shell-command "cmd.exe /c start \"\"" current-prefix-arg (dired-get-marked-files t t))
      (apply orig-fun args))))

(advice-add 'dired-find-file :around #'dired-find-file-or-execute)
2
  • 1
    What does "does not work" actually mean?
    – phils
    Jun 1, 2022 at 5:08
  • Updated with failure case
    – eatloaf
    Jun 1, 2022 at 14:35

1 Answer 1

1

Not sure what you're asking, but I think you're asking how to have dired-get-marked-files pick up only the file named on the current line, instead of the files that are marked.

If so, the answer is to just use a prefix argument (C-u 1, M-1, or C-1, to tell it to use the next one file, or even just C-u, to tell it to use the file named on the current line). The doc of the function tells you this:

dired-get-marked-files is a compiled Lisp function in dired.el.

(dired-get-marked-files &optional LOCALP ARG FILTER DISTINGUISH-ONE-MARKED ERROR)

Return the marked files’ names as list of strings.

The list is in the same order as the buffer, that is, the car is the first marked file.

Values returned are normally absolute file names.

Optional arg LOCALP as in dired-get-filename.

Optional second argument ARG, if non-nil, specifies files near point instead of marked files. It usually comes from the prefix argument.

  • If ARG is an integer, use the next ARG files.
  • If ARG is any other non-nil value, return the current file name.
  • If no files are marked, and ARG is nil, also return the current file name.

Optional third argument FILTER, if non-nil, is a function to select some of the files--those for which (funcall FILTER FILENAME) is non-nil.

If DISTINGUISH-ONE-MARKED is non-nil, then if we find just one marked file, return (t FILENAME) instead of (FILENAME). Don’t use that together with FILTER.

If ERROR is non-nil, signal an error when the list of found files is empty. ERROR can be a string with the error message.

Your (first) command passes the prefix arg, so it's likely OK as is. If not, you can explicitly pass a non-nil value as ARG in the call to dired-get-marked-files.

1
  • 1
    I thought I needed to use get-file-for-visit for the file at point but apparently not. Thanks!
    – eatloaf
    Jun 1, 2022 at 18:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.