Skip to content

Commit

Permalink
Treat playlists as standard buffers
Browse files Browse the repository at this point in the history
Instead of treating (current) playlists as their own datatype, just
treating them as buffers (which, after all, they are) means we can
inherit lots of functionality (like killing and renaming) from the
embark buffer keymaps. This also means users who write their own
buffer actions will be able to use these on playlist buffers.
Retain (and slightly rewrite) the remaining functions which
consult-emms-embark still has to do itself.

Fixes #6
  • Loading branch information
Hugo-Heagren committed Dec 26, 2021
1 parent 1cefd48 commit bd95e6b
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 67 deletions.
60 changes: 20 additions & 40 deletions consult-emms-embark.el
Original file line number Diff line number Diff line change
Expand Up @@ -93,59 +93,39 @@ Selected track is added to the current playlist."

;;;; Playlists

(defun consult-emms-embark--get-buffer-text-property (playlist-name)
"Return text property 'consult-emms--buffer of PLAYLIST-NAME."
(get-text-property 0 'consult-emms--buffer playlist-name))

(defun consult-emms-embark--with-buffer-from-text-property (playlist-name &rest body)
"Execute BODY with playlist from PLAYLIST-NAME as current."
(consult-emms--with-current-playlist
(consult-emms-embark--get-buffer-text-property playlist-name) body))

(defun consult-emms-embark--write-playlist (playlist-name)
"Write PLAYLIST-NAME to file."
(consult-emms-embark--with-buffer-from-text-property
playlist-name (call-interactively 'emms-playlist-save)))

(defun consult-emms-embark--kill-playlist (playlist-name)
"Kill playlist buffer extracted from PLAYLIST-NAME."
(kill-buffer
(consult-emms-embark--get-buffer-text-property playlist-name)))
(defun consult-emms-embark--write-playlist (playlist)
"Write PLAYLIST to a file (prompts for filename)."
;; If the playlist is the current buffer, EMMS won't raise
;; exceptions about the buffer not being current (which the user
;; likely knows already if they are using `consult-emms'!)
(with-current-buffer playlist
(consult-emms--with-current-playlist
playlist (call-interactively 'emms-playlist-save))))

(defun consult-emms-embark--clear-playlist (playlist-name)
"Clear playlist extracted from PLAYLIST-NAME."
(consult-emms-embark--with-buffer-from-text-property
playlist-name (emms-playlist-clear)))
"Clear playlist in buffer PLAYLIST-NAME."
(with-current-buffer playlist-name
(emms-playlist-clear)))

(defun consult-emms-embark--shuffle-playlist (playlist-name)
"Shuffle playlist extracted from PLAYLIST-NAME."
(consult-emms-embark--with-buffer-from-text-property
playlist-name (emms-shuffle)))

(defun consult-emms-embark--rename-playlist (playlist-name)
"Rename playlist extracted from PLAYLIST-NAME."
(let ((buffer
(consult-emms-embark--get-buffer-text-property playlist-name)))
(with-current-buffer buffer
(call-interactively 'rename-buffer))))
"Shuffle playlist in buffer PLAYLIST-NAME."
(with-current-buffer playlist-name (emms-shuffle)))

(defun consult-emms-embark--insert-playlist (playlist-name)
"Append playlist extracted from PLAYLIST-NAME to other playlist."
(let ((new-playlist (consult-emms--choose-buffer))
(orig-playlist
(consult-emms-embark--get-buffer-text-property playlist-name)))
"Append playlist in buffer PLAYLIST-NAME to another playlist."
(let ((new-playlist (consult-emms--choose-buffer)))
(with-current-buffer new-playlist
(save-excursion
(goto-char (point-max))
(insert-buffer orig-playlist)))))
(let ((inhibit-read-only t))
(save-excursion
(goto-char (point-max))
(insert-buffer playlist-name))))))

(embark-define-keymap consult-emms-embark-playlist-actions
"Keymap for actions on playlists in `consult-emms'."
:parent embark-buffer-map
("W" '("Write to file" . consult-emms-embark--write-playlist))
("k" '("Kill playlist" . consult-emms-embark--kill-playlist))
("c" '("Clear playlist" . consult-emms-embark--clear-playlist))
("s" '("Shuffle playlist" . consult-emms-embark--shuffle-playlist))
("r" '("Rename playlist buffer" . consult-emms-embark--rename-playlist))
("i" '("Insert into playlist" . consult-emms-embark--insert-playlist)))

(add-to-list 'embark-keymap-alist '(playlist . consult-emms-embark-playlist-actions))
Expand Down
51 changes: 24 additions & 27 deletions consult-emms.el
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,22 @@ as a symbol. THINGS can be a string or a symbol."
(symbol-name thing)
thing))))

(defun consult-emms--list-playlists ()
"Get a list of names of EMMS playlist buffers."
(mapcar 'buffer-name
(emms-metaplaylist-mode-sorted-buffer-list)))

(defmacro consult-emms--with-current-playlist (buffer &rest body)
"Execute BODY with BUFFER as `emms-playlist-buffer'."
`(let ((emms-playlist-buffer ,buffer))
"Execute BODY with BUFFER as `emms-playlist-buffer'.
BUFFER is a string, the name of a buffer."
`(let ((emms-playlist-buffer (get-buffer ,buffer)))
,@body))

(defun consult-emms--with-chosen-current-playlist (&rest body)
(defmacro consult-emms--with-chosen-current-playlist (&rest body)
"Make a chosen EMMS playlist current and execute BODY."
(let ((buffer (consult-emms--choose-buffer)))
(consult-emms--with-current-playlist buffer body)))
`(let ((buffer (consult-emms--choose-buffer)))
(consult-emms--with-current-playlist buffer ,@body)))

(defun consult-emms--track-name-get (track-name name &optional default)
"Return the value of NAME property of track TRACK-NAME.
Expand Down Expand Up @@ -379,11 +386,10 @@ of the tracks's line in BUFFER."

(defun consult-emms--playlist-source-from-buffer (buffer)
"Make a source for `consult-emms-playlists' from BUFFER."
(let* ((name (buffer-name buffer))
(hist-sym (intern (concat "consult-emms--" name "-buffer-history"))))
(let ((hist-sym (intern (concat "consult-emms--" buffer "-buffer-history"))))
`(:items ,(consult-emms--get-tracks-playlist-buffer buffer)
:category track
:name ,name
:name ,buffer
:sort nil
:action (lambda (str) (consult-emms--play-track-by-pos
,buffer (get-text-property 0 'consult-emms-track-pos str))))))
Expand All @@ -394,7 +400,9 @@ of the tracks's line in BUFFER."
(get-text-property 0 'consult-emms-track-pos (car found))))

(defun consult-emms--playlist (buffer)
"Select a track from EMMS buffer BUFFER."
"Select a track from EMMS buffer BUFFER.
BUFFER is a string, is the name of a buffer."
;; `consult-emms--playlist-source-from-buffer' does most of the work
;; of forming the args for us, and it's a good idea to avoid code
;; duplication, so we use it here. BUT, it forms a source for
Expand All @@ -413,34 +421,23 @@ of the tracks's line in BUFFER."
(filtered-args (cl-loop for (key value) on raw-args by 'cddr
if (member key allowed)
collect key and collect value))
(read-args (append `(:prompt ,(format "EMMS playlist <%s>: " (string-trim (buffer-name buffer)))
(read-args (append `(:prompt ,(format "EMMS playlist <%s>: " buffer)
:lookup consult-emms--lookup-playlist-pos)
filtered-args))
(track (apply 'consult--read `(,items ,@read-args))))
(consult-emms--play-track-by-pos buffer track)))

(defun consult-emms--lookup-buffer-text-property (_ candidates cand)
"Lookup CAND in CANDIDATES list and return property 'consult-emms--buffer."
(when-let (found (member cand candidates))
(get-text-property 0 'consult-emms--buffer (car found))))

(defun consult-emms--choose-buffer ()
"Choose one of the currently open EMMS playlists.
Each candidate in the list is a string, the name of the buffer
with whitespace trimmed from the ends, with a property
'consult-emms--buffer, the value of which is the buffer itself.
Returns the buffer object. The list if fetched with
`emms-metaplaylist-mode-sorted-buffer-list'."
(let ((playlist-list (mapcar (lambda (buffer) (propertize
(string-trim (buffer-name buffer))
'consult-emms--buffer buffer))
(emms-metaplaylist-mode-sorted-buffer-list))))
Each candidate in the list is the name of a buffer. The list is
fetched with `consult-emms--list-playlists', then
transformed with `buffer-name'."
(let ((playlist-list (consult-emms--list-playlists)))
(consult--read playlist-list
:prompt "EMMS Playlist: "
:require-match t
:default (buffer-name emms-playlist-buffer)
:lookup #'consult-emms--lookup-buffer-text-property
:category 'playlist
:sort nil)))

Expand All @@ -461,7 +458,7 @@ Returns the buffer object. The list if fetched with
"Select a track from an EMMS buffer. Each buffer is a category."
(interactive)
(let ((playlists (mapcar 'consult-emms--playlist-source-from-buffer
(emms-metaplaylist-mode-sorted-buffer-list))))
(consult-emms--list-playlists))))
(consult--multi playlists
:require-match t
:prompt "Track: "
Expand All @@ -477,7 +474,7 @@ Returns the buffer object. The list if fetched with
(defun consult-emms-current-playlist ()
"Select a track from the current EMMS playlist."
(interactive)
(consult-emms--playlist emms-playlist-buffer))
(consult-emms--playlist (buffer-name emms-playlist-buffer)))

(provide 'consult-emms)

Expand Down

0 comments on commit bd95e6b

Please sign in to comment.