Start a process from dired
04 Jan 2015Here are the standard dired
functions for starting processes:
- ! calls
dired-do-shell-command
- & calls
dired-do-async-shell-command
While the second one is usually better than the first one, having the
benefit of not locking up Emacs, it's still not convenient enough for
me. The reason is pretty simple: I want to keep the processes that I
started even when I close Emacs (like opened PDFs or videos). This is
a non-issue for people with months-long emacs-uptime
, but for me an
Emacs session lasts on the order of hours, since I mess about with
Elisp a lot. Below, I'll share some of my dired
process-related
customizations.
Ignore running processes when closing Emacs
Usually there's nothing wrong with just killing a spawned process,
like an ipython
shell or something.
;; add `flet'
(require 'cl)
(defadvice save-buffers-kill-emacs
(around no-query-kill-emacs activate)
"Prevent \"Active processes exist\" query on exit."
(flet ((process-list ())) ad-do-it))
Guess programs by file extension
With this setup, usually there's no need to manually type in the command name.
(require 'dired-x)
(setq dired-guess-shell-alist-user
'(("\\.pdf\\'" "evince" "okular")
("\\.\\(?:djvu\\|eps\\)\\'" "evince")
("\\.\\(?:jpg\\|jpeg\\|png\\|gif\\|xpm\\)\\'" "eog")
("\\.\\(?:xcf\\)\\'" "gimp")
("\\.csv\\'" "libreoffice")
("\\.tex\\'" "pdflatex" "latex")
("\\.\\(?:mp4\\|mkv\\|avi\\|flv\\|ogv\\)\\(?:\\.part\\)?\\'"
"vlc")
("\\.\\(?:mp3\\|flac\\)\\'" "rhythmbox")
("\\.html?\\'" "firefox")
("\\.cue?\\'" "audacious")))
Add nohup
According to info nohup
:
`nohup' runs the given COMMAND with hangup signals ignored, so that the command can continue running in the background after you log out.
In my case, it means that the processes started by Emacs can continue running even when Emacs is closed.
(require 'dired-aux)
(defvar dired-filelist-cmd
'(("vlc" "-L")))
(defun dired-start-process (cmd &optional file-list)
(interactive
(let ((files (dired-get-marked-files
t current-prefix-arg)))
(list
(dired-read-shell-command "& on %s: "
current-prefix-arg files)
files)))
(let (list-switch)
(start-process
cmd nil shell-file-name
shell-command-switch
(format
"nohup 1>/dev/null 2>/dev/null %s \"%s\""
(if (and (> (length file-list) 1)
(setq list-switch
(cadr (assoc cmd dired-filelist-cmd))))
(format "%s %s" cmd list-switch)
cmd)
(mapconcat #'expand-file-name file-list "\" \"")))))
The dired-filelist-cmd
is necessary because vlc
weirdly
doesn't make a playlist when given a list of files.
Then I bind it to r - a nice shortcut not bound
by default in dired
:
(define-key dired-mode-map "r" 'dired-start-process)