Skip to content

Instantly share code, notes, and snippets.

@knu
Created July 27, 2026 03:36
Show Gist options
  • Select an option

  • Save knu/3c495877aa373b8a8f7fed065dcd9d16 to your computer and use it in GitHub Desktop.

Select an option

Save knu/3c495877aa373b8a8f7fed065dcd9d16 to your computer and use it in GitHub Desktop.
Start Dired from Finder or the current directory
;;; dired-start-dwim.el --- Start Dired intelligently -*- lexical-binding: t; -*-
;; Copyright (c) 2026 Akinori MUSHA
;; SPDX-License-Identifier: BSD-2-Clause
;; Author: Akinori MUSHA <knu@iDaemons.org>
;; Package-Requires: ((emacs "27.1"))
;; Keywords: files, mac
;;; Commentary:
;; `dired-start-dwim' opens the files selected in the frontmost macOS
;; Finder window. On other systems, or when Finder is unavailable, it
;; opens `default-directory'. When diredfd is installed, the resulting
;; buffer also follows Finder's sort order.
;;; Code:
(require 'cl-lib)
(require 'dired)
(require 'subr-x)
(declare-function diredfd-do-sort "diredfd" (sort-key sort-order))
(defun dired-start-dwim--osa-script (script)
"Run AppleScript SCRIPT and return its output."
(if (fboundp 'mac-osa-script)
(mac-osa-script script)
(let ((osascript (executable-find "osascript")))
(unless osascript
(error "Cannot find osascript"))
(with-temp-buffer
(unless (zerop (process-file
osascript nil t nil
"-ss" "-l" "AppleScript" "-e" script))
(error "AppleScript failed: %s" (string-trim (buffer-string))))
(string-trim-right (buffer-string))))))
(defun dired-start-dwim--finder-selected-files ()
"Return files selected in the frontmost Finder window."
(let* ((output
(car
(split-string-and-unquote
(dired-start-dwim--osa-script
"
tell application \"Finder\"
if (count windows) is 0
make new Finder window to path to Downloads folder
end if
set selected to selection
set current to POSIX path of ((target of front Finder window) as text)
end tell
set n to count selected
set output to \"\"
if n is 0 then
set output to current
else if n is 1 then
set output to POSIX path of (selected as string) & \"\\n\"
else
repeat with i from 1 to n
set output to output & (POSIX path of (item i of selected as string)) & \"\\n\"
end repeat
end if
if output is not \"\" then
return output
end if
"))))
(files (and output (split-string output "\n" t))))
files))
(defun dired-start-dwim--finder-sort-spec ()
"Return the sort key and order of the frontmost Finder window."
(when-let*
((output
(car
(split-string-and-unquote
(dired-start-dwim--osa-script
"
tell application \"Finder\"
tell list view options of front Finder window
set col to sort column
return (name of col as text) & \" \" & (sort direction of col as text)
end tell
end tell
"))))
((string-match "\\`\\(.+\\) column \\(normal\\|reversed\\)\\'" output)))
(cons
(pcase (match-string 1 output)
("name" 'filename)
("modification date" 'time)
("size" 'size)
("kind" 'extension)
(_ 'filename))
(if (string= (match-string 2 output) "reversed")
'desc
'asc))))
(defun dired-start-dwim--start (&optional file-or-files switches)
"Start Dired with FILE-OR-FILES selected.
FILE-OR-FILES may be a single file, a directory, or a list of
files and directories. Pass optional SWITCHES to `dired'."
(let ((files (if (stringp file-or-files)
(list file-or-files)
(or file-or-files (list default-directory)))))
(if (= (length files) 1)
(let* ((file (expand-file-name (or (car files) default-directory)))
(directory (if (file-directory-p file)
file
(file-name-directory file)))
(buffer (dired directory switches)))
(with-current-buffer buffer
(revert-buffer)
(dired-goto-file
(if (file-directory-p file)
(concat (file-name-as-directory file) "..")
file)))
(switch-to-buffer buffer))
(let* ((files (mapcar #'expand-file-name files))
(root
(file-name-directory
(cl-reduce #'fill-common-string-prefix files)))
(buffer (dired root switches)))
(with-current-buffer buffer
(revert-buffer)
(dolist (file files)
(let ((directory root))
(dolist
(component
(butlast
(split-string (file-relative-name file root) "/" t)))
(setq directory (expand-file-name component directory))
(when (file-directory-p directory)
(dired-maybe-insert-subdir directory)))
(when (dired-goto-file file)
(save-excursion (dired-mark 1))))))
(switch-to-buffer buffer)))
(when (and (bound-and-true-p hl-line-mode)
(fboundp 'hl-line-highlight))
(hl-line-highlight))))
;;;###autoload
(defun dired-start-dwim ()
"Start Dired from Finder selection or `default-directory'.
On macOS, use the files selected in the frontmost Finder window.
When diredfd is available, also follow Finder's sort order."
(interactive)
(let* ((use-finder (eq system-type 'darwin))
(files
(and use-finder
(ignore-errors
(dired-start-dwim--finder-selected-files))))
(sort-spec
(and files
(fboundp 'diredfd-do-sort)
(ignore-errors
(dired-start-dwim--finder-sort-spec)))))
(dired-start-dwim--start files)
(when sort-spec
(diredfd-do-sort (car sort-spec) (cdr sort-spec)))))
(provide 'dired-start-dwim)
;;; dired-start-dwim.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment