Last time I
started a small library called Racket and
today I extended it to add functionality for managing a simple
‘favourite tracks’ playlist. The playlist is stored in a format called
m3u (the only reason being because it’s the least
complicated one that VLC uses). The format is simply like this:
#EXTM3U
file:///path/to/track/1.ogg
file:///path/to/track/2.wav
To start I defined a custom variable called
racket-favourites-playlist which stores the path of the
playlist:
(defcustom racket-favourites-playlist "~/Music/playlists/Favourites.m3u"
"File path where favourites playlist is stored."
:type 'string
:group 'racket)
Next I added some simple functions to play the playlist in EMMS:
(defun racket-add-favourites ()
"Add favourites playlist"
(interactive)
(emms-add-playlist-file racket-favourites-playlist))
(defun racket-play-favourites ()
"Play favourites playlist"
(interactive)
(emms-play-playlist-file racket-favourites-playlist))
Next comes the fun part: to add the current playing track to the
playlist, so that I can quickly add a track I love with a custom
keybinding. To find the filename of the current track, I can use the
mouthful of a function
emms-score-current-selected-track-filename. The function
I made avoids making any changes if the track is already in the
playlist, and adds an extra newline to the end of the file if one is
missing.
(defun racket-add-track-to-favourites ()
"Add current track to favourites"
(interactive)
(let ((line (concat "file://" (emms-score-current-selected-track-filename))))
(with-current-buffer (or (get-file-buffer racket-favourites-playlist)
(find-file-noselect racket-favourites-playlist))
(save-excursion
(beginning-of-buffer)
(if (search-forward-regexp
(concat "^" (regexp-quote line) "$")
nil t)
;; Don’t do anything if the track is already added
(message "The track is already inside the playlist.")
;; Add to playlist
(progn
(end-of-buffer)
(unless (eq ?\C-j (char-before))
(insert "\n"))
(insert line "\n")
(save-buffer)
(message "Track added to playlist.")))))))
I also made two more functions: one to remove the current track from
favourites and another to open the playlist file so I can easily
reorder it. You can find
the full code for Racket here. Finally, I bound each of these functions to a key combination under
C-SPC r (C-SPC is where I define all my custom
keybindings and the r stands for Racket). You can see
the code for that here.