Command Rhythmbox from Emacs09 Jul 2015
I might have mentioned before that I'm using GNU/Linux on all of my
computers. The particular flavor is Ubuntu, although it shouldn't
matter much, since I can count the graphical applications that I use
at all, besides Emacs, on one hand. They are: Firefox, Evince,
Rhythmbox and VLC. Of course, as most true Emacs-ers, I strive to
reduce this number to zero. So I got quite excited when I saw
helm-rhythmbox show up in
my package list. It works great: you can play and enqueue tracks with
completion without leaving Emacs. Big thanks to
@mrBliss, and, of course, the authors
dbus.el which makes interaction with D-Bus possible through
I'm not as big a fan of Helm as I used to be, so I quickly implemented an Ivy equivalent:
(defun counsel-rhythmbox-enqueue-song (song) "Let Rhythmbox enqueue SONG." (let ((service "org.gnome.Rhythmbox3") (path "/org/gnome/Rhythmbox3/PlayQueue") (interface "org.gnome.Rhythmbox3.PlayQueue")) (dbus-call-method :session service path interface "AddToQueue" (rhythmbox-song-uri song)))) ;;;###autoload (defun counsel-rhythmbox () "Choose a song from the Rhythmbox library to play or enqueue." (interactive) (unless (require 'helm-rhythmbox nil t) (error "Please install `helm-rhythmbox'")) (unless rhythmbox-library (rhythmbox-load-library) (while (null rhythmbox-library) (sit-for 0.1))) (ivy-read "Rhythmbox: " (helm-rhythmbox-candidates) :action '(1 ("Play song" helm-rhythmbox-play-song) ("Enqueue song" counsel-rhythmbox-enqueue-song))))
I listed the whole code just to show how easy it is to interact with
D-Bus, and also to show-off the shiny new multi-action interface of
ivy-read. Besides being discoverable via C-o, the
multi-action interface is extensible as well. Here's how to add a
"Dequeue" action without touching the original code:
(defun counsel-rhythmbox-dequeue-song (song) "Let Rhythmbox dequeue SONG." (let ((service "org.gnome.Rhythmbox3") (path "/org/gnome/Rhythmbox3/PlayQueue") (interface "org.gnome.Rhythmbox3.PlayQueue")) (dbus-call-method :session service path interface "RemoveFromQueue" (rhythmbox-song-uri song)))) (ivy-set-actions 'counsel-rhythmbox '(("Dequeue song" counsel-rhythmbox-dequeue-song)))
counsel-rhythmbox-dequeue-song is a clone of
counsel-rhythmbox-enqueue-song with only the method change from
RemoveFromQueue (I blind-guessed the name, but there
should be a reference somewhere). If you got tired of having a whole
three actions to choose from, you can revert to the initial two with:
(ivy-set-actions 'counsel-rhythmbox nil)
And here's how the updated C-o option panel now looks like:
A bit of descriptions:
- j moves to the next one of the 18 current candidates.
- k moves to the previous candidate.
- h moves to the first candidate.
- l moves to the last candidate.
- g calls the current action without exiting.
- d calls the current action and exits.
- s moves to the next action.
- w moves to the previous action.
- i and C-o close the options panel without exiting.
- o closes the panel and exits.
hydra, each action has a short docstring, like
song" that should describe what it does. Here are a few usage
- If I wanted to play the first song and enqueue the third and the sixth and exit the minibuffer, I would press gsjjgjjjd.
- If I wanted to play the third and enqueue all the following, I would press jjgsjcjjjjjjjjjjjo. The many j is just me holding j until the selection reaches the end, then I simply exit without doing anything else by pressing o. The way c works is that it toggles the "calling" state - a state where the current action is called whenever a different candidate is selected.
Almost forgot, if this little intro got you excited, the packages that you should install from MELPA are: