Emacs: Open File in External App ๐
Open File in External App
Here's a emacs command to open the current file or marked dired files in external app. (as if you double-clicked the file on desktop) It's useful for image files, PDF file, video, audio files.
Put this in your Emacs Init File:
(defun xah-open-in-external-app (&optional Fname) "Open the current file or dired marked files in external app. When called in emacs lisp, if Fname is given, open that. URL `http://xahlee.info/emacs/emacs/emacs_dired_open_file_in_ext_apps.html' Version: 2019-11-04 2021-07-21 2022-08-19 2023-02-28 2023-03-10" (interactive) (let (xfileList xdoIt) (setq xfileList (if Fname (list Fname) (if (string-equal major-mode "dired-mode") (dired-get-marked-files) (list buffer-file-name)))) (setq xdoIt (if (<= (length xfileList) 10) t (y-or-n-p "Open more than 10 files? "))) (when xdoIt (cond ((string-equal system-type "windows-nt") (let ((xoutBuf (get-buffer-create "*xah open in external app*")) (xcmdlist (list "PowerShell" "-Command" "Invoke-Item" "-LiteralPath"))) (mapc (lambda (x) (message "%s" x) (apply 'start-process (append (list "xah open in external app" xoutBuf) xcmdlist (list (format "'%s'" (if (string-match "'" x) (replace-match "`'" t t x) x))) nil))) xfileList) (switch-to-buffer-other-window xoutBuf)) ;; old code. calling shell. also have a bug if filename contain apostrophe ;; (mapc (lambda (xfpath) (shell-command (concat "PowerShell -Command \"Invoke-Item -LiteralPath\" " "'" (shell-quote-argument (expand-file-name xfpath)) "'"))) xfileList) ) ((string-equal system-type "darwin") (mapc (lambda (xfpath) (shell-command (concat "open " (shell-quote-argument xfpath)))) xfileList)) ((string-equal system-type "gnu/linux") (mapc (lambda (xfpath) (call-process shell-file-name nil nil nil shell-command-switch (format "%s %s" "xdg-open" (shell-quote-argument xfpath)))) xfileList)) ((string-equal system-type "berkeley-unix") (mapc (lambda (xfpath) (let ((process-connection-type nil)) (start-process "" nil "xdg-open" xfpath))) xfileList))))))
Show in Desktop
The following shows the file in desktop folder viewer. (Microsoft File Explorer, Mac's Finder, Linux's file manager.)
(defun xah-show-in-desktop () "Show current file in desktop. (Mac Finder, File Explorer, Linux file manager) This command can be called when in a file buffer or in `dired'. URL `http://xahlee.info/emacs/emacs/emacs_dired_open_file_in_ext_apps.html' Version: 2020-11-20 2022-04-20 2022-08-19" (interactive) (let (($path (if (eq major-mode 'dired-mode) (if (eq nil (dired-get-marked-files)) default-directory (car (dired-get-marked-files))) (if buffer-file-name buffer-file-name default-directory)))) (cond ((string-equal system-type "windows-nt") (shell-command (format "PowerShell -Command invoke-item '%s'" (expand-file-name default-directory ))) ;; (let (($cmd (format "Explorer /select,%s" ;; (replace-regexp-in-string "/" "\\" $path t t) ;; ;; (shell-quote-argument (replace-regexp-in-string "/" "\\" $path t t )) ;; ))) ;; (shell-command $cmd)) ) ((string-equal system-type "darwin") (shell-command (concat "open -R " (shell-quote-argument $path)))) ((string-equal system-type "gnu/linux") (call-process shell-file-name nil nil nil shell-command-switch (format "%s %s" "xdg-open" (file-name-directory $path))) ;; (shell-command "xdg-open .") ;; 2013-02-10 this sometimes froze emacs till the folder is closed. eg with nautilus ))))
You can give it a hotkey, see: Emacs: How to Define Keybinding.
Open in VSCode
(defun xah-open-in-vscode () "Open current file or dir in vscode. URL `http://xahlee.info/emacs/emacs/emacs_dired_open_file_in_ext_apps.html' Version: 2020-02-13 2021-01-18 2022-08-04" (interactive) (let (($path (if buffer-file-name buffer-file-name (expand-file-name default-directory)))) (message "path is %s" $path) (cond ((string-equal system-type "darwin") (shell-command (format "open -a Visual\\ Studio\\ Code.app %s" (shell-quote-argument $path)))) ((string-equal system-type "windows-nt") (shell-command (format "code.cmd %s" (shell-quote-argument $path)))) ((string-equal system-type "gnu/linux") (shell-command (format "code %s" (shell-quote-argument $path)))))))
Open in Terminal
Here's a command to open the current file's directory in terminal.
(defvar xah-fly-mswin-terminal nil "A string. Value should be one of: wt (for Windows Terminal) or pwsh (for PowerShell Core (cross-platform)) or powershell (for Microsoft PowerShell).") (setq xah-fly-mswin-terminal "wt") (defun xah-open-in-terminal () "Open the current dir in a new terminal window. On Microsoft Windows, which terminal it starts depends on `xah-fly-mswin-terminal'. URL `http://xahlee.info/emacs/emacs/emacs_dired_open_file_in_ext_apps.html' Version: 2020-11-21 2021-07-21 2022-08-04 2023-03-01" (interactive) (cond ((string-equal system-type "windows-nt") (cond ((string-equal xah-fly-mswin-terminal "wt") (shell-command (format "wt -d \"%s\"" default-directory))) ((string-equal xah-fly-mswin-terminal "pwsh") (shell-command (format "pwsh -Command Start-Process pwsh -WorkingDirectory '%s'" (shell-quote-argument default-directory)))) ((string-equal xah-fly-mswin-terminal "powershell") (shell-command (format "powershell -Command Start-Process powershell -WorkingDirectory '%s'" (shell-quote-argument default-directory)))) (t (error "Error 702919: value of `xah-fly-mswin-terminal' is not expected. Its value is %s" xah-fly-mswin-terminal)))) ((string-equal system-type "darwin") (shell-command (concat "open -a terminal " (shell-quote-argument (expand-file-name default-directory))))) ((string-equal system-type "gnu/linux") (let ((process-connection-type nil)) (start-process "" nil "x-terminal-emulator" (concat "--working-directory=" default-directory)))) ((string-equal system-type "berkeley-unix") (let ((process-connection-type nil)) (start-process "" nil "x-terminal-emulator" (concat "--working-directory=" default-directory))))))
Note: emacs has many shells and terminal emulators. [see Emacs: Run Shell in Emacs] But sometimes, it is necessary to run some command in dedicated terminal app.
[see Emacs: Difference between shell, term, eshell]
Open in TextEdit
This is Mac only.
this is great for spell checking! just open it in TextEdit, and you get all misspelled words highlighted automatically. In emacs, it's 10 times slower and doesn't work well.
(defun xah-dired-open-in-textedit () "Open the current file or `dired' marked files in Mac's TextEdit. This command is for macOS only. URL `http://xahlee.info/emacs/emacs/emacs_dired_open_file_in_ext_apps.html' Version: 2017-11-21 2021-02-07" (interactive) (when (not (string-equal system-type "darwin")) (user-error "Error: textedit only run in Mac")) (let* ( (xFList (if (string-equal major-mode "dired-mode") (dired-get-marked-files) (list buffer-file-name))) (xDoIt (if (<= (length xFList) 10) t (y-or-n-p "Open more than 10 files? ")))) (when xDoIt (mapc (lambda (x) (shell-command (format "open -a TextEdit.app \"%s\"" x))) xFList))))
Open in Google Chrome
(defun xah-html-open-in-chrome-browser () "Open the current file or `dired' marked files in Google Chrome browser. Work in Windows, macOS, linux. URL `http://xahlee.info/emacs/emacs/emacs_dired_open_file_in_ext_apps.html' Version 2019-11-10" (interactive) (let* ( ($file-list (if (string-equal major-mode "dired-mode") (dired-get-marked-files) (list (buffer-file-name)))) ($do-it-p (if (<= (length $file-list) 5) t (y-or-n-p "Open more than 5 files? ")))) (when $do-it-p (cond ((string-equal system-type "darwin") (mapc (lambda ($fpath) (shell-command (format "open -a /Applications/Google\\ Chrome.app \"%s\"" $fpath))) $file-list)) ((string-equal system-type "windows-nt") ;; "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" 2019-11-09 (let ((process-connection-type nil)) (mapc (lambda ($fpath) (start-process "" nil "powershell" "start-process" "chrome" $fpath )) $file-list))) ((string-equal system-type "gnu/linux") (mapc (lambda ($fpath) (shell-command (format "google-chrome-stable \"%s\"" $fpath))) $file-list))))))
(defun xah-html-open-link-in-chrome () "Open url under cursor in Google Chrome. Work in Windows, macOS, linux. Version 2019-11-10" (interactive) (let* (($inputStr (if (use-region-p) (buffer-substring-no-properties (region-beginning) (region-end)) (let ($p0 $p1 $p2 ($pathStops "^ ย \t\n\"`'โโโโ|[]{}ใใ<>ใใใใใใใใใใยซยปโนโบโฎโฏโฌโญใใยทใ\\")) (setq $p0 (point)) (skip-chars-backward $pathStops) (setq $p1 (point)) (goto-char $p0) (skip-chars-forward $pathStops) (setq $p2 (point)) (goto-char $p0) (buffer-substring-no-properties $p1 $p2)))) ($path (replace-regexp-in-string "^file:///" "/" (replace-regexp-in-string ":\\'" "" $inputStr)))) (cond ((string-equal system-type "darwin") (shell-command (format "open -a Google\\ Chrome.app \"%s\"" $path))) ((string-equal system-type "windows-nt") ;; "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" 2019-11-09 (let ((process-connection-type nil)) (start-process "" nil "powershell" "start-process" "chrome" $path ))) ((string-equal system-type "gnu/linux") (shell-command (format "google-chrome-stable \"%s\"" $path))))))
Open in Firefox
(defun xah-html-open-link-in-firefox (&optional @fullpath) "open url under cursor in Firefox browser. Work in Windows, macOS. 2019-11-09 linux not yet. Version 2019-11-09" (interactive) (let ($path) (if @fullpath (progn (setq $path @fullpath)) (let (($inputStr (if (use-region-p) (buffer-substring-no-properties (region-beginning) (region-end)) (let ($p0 $p1 $p2 ($pathStops "^ ย \t\n\"`'โโโโ|[]{}ใใ<>ใใใใใใใใใใยซยปโนโบโฎโฏโฌโญใใยทใ\\")) (setq $p0 (point)) (skip-chars-backward $pathStops) (setq $p1 (point)) (goto-char $p0) (skip-chars-forward $pathStops) (setq $p2 (point)) (goto-char $p0) (buffer-substring-no-properties $p1 $p2))))) (setq $path (replace-regexp-in-string "^file:///" "/" (replace-regexp-in-string ":\\'" "" $inputStr))))) (cond ((string-equal system-type "darwin") (shell-command (format "open -a 'Firefox.app' \"%s\"" $path))) ((string-equal system-type "windows-nt") ;; "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" 2019-11-09 (let ((process-connection-type nil)) (start-process "" nil "powershell" "start-process" "firefox" $path ))) ((string-equal system-type "gnu/linux") (shell-command (format "firefox \"%s\"" $path))))))
Open in Brave browser
(defun xah-html-open-in-brave () "Open the current file or `dired' marked files in Brave browser. If the file is not saved, save it first. Version 2019-11-10" (interactive) (let* ( ($file-list (if (string-equal major-mode "dired-mode") (dired-get-marked-files) (list (buffer-file-name)))) ($do-it-p (if (<= (length $file-list) 5) t (y-or-n-p "Open more than 5 files? ")))) (when $do-it-p (cond ((string-equal system-type "darwin") (mapc (lambda ($fpath) (shell-command (format "open -a 'Brave Browser.app' \"%s\"" $fpath))) $file-list)) ((string-equal system-type "windows-nt") ;; "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" 2019-11-09 (let ((process-connection-type nil)) (mapc (lambda ($fpath) (start-process "" nil "powershell" "start-process" "brave" $fpath )) $file-list))) ((string-equal system-type "gnu/linux") (mapc (lambda ($fpath) (shell-command (format "brave \"%s\"" $fpath))) $file-list))))))
(defun xah-html-open-link-in-brave (&optional @fullpath) "open url under cursor in Brave browser. Work in Mac OS only Version 2019-02-17" (interactive) (let ($path) (if @fullpath (progn (setq $path @fullpath)) (let (($inputStr (if (use-region-p) (buffer-substring-no-properties (region-beginning) (region-end)) (let ($p0 $p1 $p2 ($pathStops "^ ย \t\n\"`'โโโโ|[]{}ใใ<>ใใใใใใใใใใยซยปโนโบโฎโฏโฌโญใใยทใ\\")) (setq $p0 (point)) (skip-chars-backward $pathStops) (setq $p1 (point)) (goto-char $p0) (skip-chars-forward $pathStops) (setq $p2 (point)) (goto-char $p0) (buffer-substring-no-properties $p1 $p2))))) (setq $path (replace-regexp-in-string "^file:///" "/" (replace-regexp-in-string ":\\'" "" $inputStr))))) (cond ((string-equal system-type "darwin") (shell-command (format "open -a 'Brave Browser.app' \"%s\"" $path))) ((string-equal system-type "windows-nt") ;; "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" 2019-11-09 (let ((process-connection-type nil)) (start-process "" nil "powershell" "start-process" "brave" $path ))) ((string-equal system-type "gnu/linux") (shell-command (format "brave \"%s\"" $path))))))
Open in Safari
This is Mac only.
(defun xah-html-open-in-safari () "Open the current file or `dired' marked files in Mac's Safari browser. If the file is not saved, save it first. URL `http://xahlee.info/emacs/emacs/emacs_dired_open_file_in_ext_apps.html' Version 2018-02-26" (interactive) (let* ( ($file-list (if (string-equal major-mode "dired-mode") (dired-get-marked-files) (list (buffer-file-name)))) ($do-it-p (if (<= (length $file-list) 5) t (y-or-n-p "Open more than 5 files? ")))) (when $do-it-p (cond ((string-equal system-type "darwin") (mapc (lambda ($fpath) (when (buffer-modified-p ) (save-buffer)) (shell-command (format "open -a Safari.app \"%s\"" $fpath))) $file-list))))))