dired-mode, I use an external quicklook tool on OSX called
qlmanage, which pops open a window displaying a human readable image of the file with mouse scrolling capabilities. If I hit the space bar,
qlmanage either displays the file or the process is deleted -- e.g., essentially an on/off switch.
I am having trouble figuring out how to move up or down in a
dired-mode buffer, such that
qlmanage will automatically display an image of the current line -- if an image is already being displayed -- but only do so after the previous process has successfully been killed with
delete-process. A successful kill of the
qlmanage process will return a
9 or the event string will equal
killed\n. I believe it is necessary to spawn a new process and sentinel when
(= 9 (process-exit-status p); however, I am still confused by the nesting despite having had a few cups of coffee. I would like to have one function
dired-qlmanage that serves both purposes -- i.e., on/off with the space bar, or show next image if one is already displayed when moving up or down.
CAVEAT: The goal is to avoid having more than one active
qlmanage process at any given moment in time, which is why I am using a
FYI: "Deleting a running process sends a signal to terminate it (and its child processes, if any), and calls the process sentinel." [Emphasis added.] https://www.gnu.org/software/emacs/manual/html_node/elisp/Deleting-Processes.html
(require 'dired) (require 'cl) (defun dired-kill-last-process-named (name) "Function initially written by @wvxvw, and revised by @lawlist." (let (p) (cl-loop with name-re = (format "^%s\\(?:<\\([[:digit:]]+\\)>\\)?" (regexp-quote name)) for process in (process-list) for pname = (process-name process) if (string-match name-re pname) collect (cons (string-to-number (or (match-string 1 pname) "0")) process) into processes finally (let ((process (cdar (cl-sort processes '> :key 'car)))) (when (and process (get-process process)) (delete-process process) (setq p process)))) p)) (defun dired-qlmanage () (interactive) (unless (dired-kill-last-process-named "qlmanage") (let ((current-node (dired-get-file-for-visit))) (set-process-sentinel (start-process "qlmanage" nil "/usr/bin/qlmanage" "-p" current-node) (lambda (p e) (setq e (replace-regexp-in-string "\n$" "" e)) (cond ((= 9 (process-exit-status p)) ;; Should we spawn a new process with sentinel here? (message "killed (9): %s | %s | %s" p e (process-exit-status p))) ((= 0 (process-exit-status p)) (message "finished (0): %s | %s | %s" p e (process-exit-status p))) (t (message "unknown (?): %s | %s | %s" p e (process-exit-status p))))))))) (defun my-dired-previous-line (arg) (interactive "^p") (dired-previous-line arg) (dired-qlmanage)) (defun my-dired-next-line (arg) (interactive "^p") (dired-next-line arg) (dired-qlmanage)) (defun my-dired-quicklook () (interactive) (dired-qlmanage)) (eval-after-load "dired" '(progn (define-key dired-mode-map [down] 'my-dired-next-line) (define-key dired-mode-map [up] 'my-dired-previous-line) (define-key dired-mode-map (kbd "SPC") 'my-dired-quicklook)))