0

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))))))
10
  • Show your code.
    – phils
    Jun 4, 2022 at 23:01
  • @phils, while the question was more aimed on how to follow the manual's advice (independent on the background), I now added the code.
    – Phoenix
    Jun 5, 2022 at 17:33
  • emacs.stackexchange.com/tags/elisp/info
    – Drew
    Jun 5, 2022 at 17:56
  • let-binding display-buffer-alist will only affect the synchronous parts of your call to async-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 someone let-bind display-buffer-alist before.
    – phils
    Jun 6, 2022 at 1:04
  • 1
    C-h i g (elisp)Buffer Display Action Alists describes the ALIST arguments.
    – phils
    Jun 6, 2022 at 10:42

1 Answer 1

0

You maybe want this:

(add-to-list 'display-buffer-alist
             (cons (lambda (bufname _action)
                     (string= bufname (nth 0 lProgramBuffers)))
                   (cons 'display-buffer-no-window
                         '((allow-no-window . t)))))
11
  • Thanks! It does appear to work. Though mind to explain its contents, please? I prefer to use code I understand in the event that I need to make amendments.
    – Phoenix
    Jun 6, 2022 at 9:44
  • If you read C-h v display-buffer-alist again in the context of this code, you should be able to figure it out. The cons cells are providing the (CONDITION . (FUNCTIONS . ALIST)) structure.
    – phils
    Jun 6, 2022 at 10:36
  • Unfortunately I fail to understand the lambda function in your implementation. To my understanding lambda is a nameless function, but I cannot see where from "bufname" as well as "_action" is fed and when testing it isolated in "scratch" it produces a more complex result than I expected and cannot backtrace it completely. With that understanding the remainder is not as trivial.
    – Phoenix
    Jun 6, 2022 at 14:33
  • I marked the answer as solution to the problem I had since implementing it as is (a.k.a. copy'n'paste) worked. However, the ultimate goal of my question was to learn how to add valid elements to display-buffer-alist in a way that I can reproduce them. This I still cannot as I do not know how to properly create and format a condition even after dissecting the construct presented.
    – Phoenix
    Jun 6, 2022 at 14:46
  • 1
    With more background, the docs will make more sense. I highly recommend working through C-h i g (eintr). I expect you'll know some things already, but that you'll learn a lot of things you didn't understand before, and that it will help you to understand other docs in future.
    – phils
    Jun 7, 2022 at 7:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.