(or emacs irrelevant)

Start a process from dired

Here 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)