I wrote a simple function for Emacs that ends in calling async-shell-command
with a music player. All good so far, but the command pops up the standard-out buffer.
Its help text reads (among other things):
To run COMMAND without displaying the output
in a window you can configure ‘display-buffer-alist’ to use the action
‘display-buffer-no-window’ for the buffer ‘*Async Shell Command*’.
Trying to get this override set temporary for calling the command, I used let
to define display-buffer-alist
. While the buffer does not pop up anymore, I get an error in the messages related around display-buffer-assq-regexp
every time:
display-buffer-assq-regexp: Wrong type argument: integerp, (nil (allow-no-window . t))
Depending on what I tried, this also came up with:
display-buffer-assq-regexp: Wrong number of arguments: #<subr regexp-quote>, 2
I searched the entire built-in Emacs documentation for display-buffer-alist
as well as for display-buffer-no-window
, but trying as I might, I cannot get rid of the error message.
With the notoriously sparse documentation, I kindly ask if anyone can point me to or provide me an example on how to use the advice provided in the help text of async-shell-command
:
How do I use display-buffer-no-window
to "fill" display-buffer-alist
without generating errors?
EDIT
Added code:
(defun music-player ()
"Starts a music player with a randomized (shuffled) list of all songs"
(interactive)
(let ((sPlayer "/usr/bin/mpv")
(lPlayerArguments '("--player-operation-mode=pseudo-gui" "--volume=50" "--playlist="))
(lMusic (directory-files-recursively (concat (getenv "HOME") "/Media/Music") "\\.mp3$\\|\\.m4a$"))
(sPlaylist (concat (getenv "HOME") "/Media/Music/play.list")))
(unless (get-buffer sPlaylist)
(create-file-buffer sPlaylist))
(set-buffer (concat (file-name-base sPlaylist) (file-name-extension sPlaylist t)))
(erase-buffer)
(insert (mapconcat 'identity lMusic "\n"))
(shell-command-on-region (buffer-end -1) (buffer-end 1) "shuf" (concat (file-name-base sPlaylist) (file-name-extension sPlaylist t)) t)
(write-file sPlaylist)
(kill-buffer (concat (file-name-base sPlaylist) (file-name-extension sPlaylist t)))
(let ((lProgramBuffers '("*Player stdout*" "*Player stderr*")))
(create-file-buffer (nth 0 lProgramBuffers))
(create-file-buffer (nth 1 lProgramBuffers))
(let ((display-buffer-alist
'((substring-no-properties (regexp-quote (nth 0 lProgramBuffers)))
(display-buffer-no-window (nth 0 lProgramBuffers) display-buffer-alist))))
(async-shell-command
(concat sPlayer " " (mapconcat 'identity lPlayerArguments " ") "\"" sPlaylist "\"")
(nth 0 lProgramBuffers) (nth 1 lProgramBuffers))))))
let
-bindingdisplay-buffer-alist
will only affect the synchronous parts of your call toasync-shell-command
. The binding will no longer be in effect by the time the asynchronous process finishes, so you need to be sure that's sufficient. I'm not sure I've ever seen someonelet
-binddisplay-buffer-alist
before.C-h i g (elisp)Buffer Display Action Alists
describes theALIST
arguments.