2016-04-12 Showing some of those Async Shell Command buffers

Last time, I showed how to make those pesky *Async Shell Command* buffers disappear (or more precisely, how not to make them appear in the first place). I briefly mentioned that sometimes it might be useful to actually see them. Well, here’s the way.

(add-to-list 'display-buffer-alist '("^*Async Shell Command*" . (display-buffer-no-window)))

(defun async-shell-dispatch (orig-fun command &optional output-buffer error-buffer)
  "If OUTPUT-BUFFER is '(4) (i.e., C-u), temporarily turn off
blocking of displaying the output-buffer."
  (if (equal output-buffer '(4))
      (let ((display-buffer-alist
	     (remove '("^*Async Shell Command*" . (display-buffer-no-window)) display-buffer-alist)))
	(funcall orig-fun command nil error-buffer))
    (funcall orig-fun command output-buffer error-buffer)))

(advice-add 'async-shell-command :around 'async-shell-dispatch)

This is clearly a quick-and-dirty hack, but at least Emacs makes it possible. Here’s a short explanation: I wrap the async-shell-command in an advice, and call it from within it, but with one twist: if the prefix argument is C-u, I temporarily remove the very same thing I added to display-buffer-alist earlier. (Of course, it works because display-buffer-alist is a special variable, not a lexically scoped one.) Needless to say that this “solution” is extremely brittle and definitely a textbook example of bad practices – don’t try this at home, kids! – so if you have a better idea, make sure to leave it in the comments!

In the meantime, I’m now going to raise this subject on the emacs-devel mailing list, since I’d like stock Emacs to be able to do something like this without such terrible hacks.

CategoryEnglish, CategoryBlog, CategoryEmacs