EMACS-DOCUMENT

=============>集思广益

在Emacs中控制Rhythmbox

我之前应该提到过,我的所有电脑都用的是GNU/Linux. 具体来说用的是Ubuntu, 不过也无所谓是哪个具体发行版了,因为我用过的图形化应用除了Emacs之外,一只手就能数的清楚. 他们分别是: Firefox, Evince, Rhythmbox 以及 VLC. 当然,跟大多数Emacs真爱用户一样,我也在想方设法地将尽可能少地使用这些软件,转而用Emacs来实现. 因此,你可以想象当我看到helm-rhythmbox 这个package时,有多么的的兴奋. 这样一来我就可以不用离开Emacs也能播放和添加音乐了,而且还能享受到Emacs提供的自动补全功能. 这真的要感谢 @mrBliss, 以及 dbus.el(它使得可以通过Elisp与D-Bus交互成为可能).

我一向对Helm不是很感冒,一次我快速完成了一个Ivy的等价实现:

(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))))

我把整个代码都列出来只是为了说明与D-Bus交互是多么的容易,也顺便展示一下ivy-read新增的multi-action接口. multi-action接口是可扩展的,你可以通过 C-o 来查看该接口. 下面是一个例子,无需修改源代码就可以添加一个"Dequeue"的动作:

(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-songcounsel-rhythmbox-enqueue-song 几乎一模一样,只不过调用的方法从 AddToQueue 变成了 RemoveFromQueue (我是瞎猜猜到的这个名字,不过应该能找到手册的) 如果你想恢复原始的actions,只需要:

(ivy-set-actions 'counsel-rhythmbox nil)

新的 C-o 面板的说明如下:

  • j 移动到下一个候选项
  • k 移动到上一个候选项
  • h 移动到第一个候选项
  • l 移动到最后那个候选项
  • g 执行当前选中的动作,但不退出ivy.
  • d 执行当前选中的动作,且退出ivy.
  • s 移动到下一个动作.
  • w 移动到前一个动作.
  • i / C-o 关闭这个面板,但不退出ivy.
  • o 关闭这个面板且退出ivy.

hydra 类似, 每个动作都有一段简短的说明,比如"Play song"就说明了这个动作是做什么的. 下面是一些有用的场景描述:

  • 假设我想播放第一个歌曲,然后将第三个和第六个歌曲加入播放队列,然后再退出minibuffer,则我只需要按下 gsjjgjjjd.
  • 假设我想先播放第三首歌曲,然后将剩下所有的歌曲加入播放队列,则我需要按下 jjgsjcjjjjjjjjjjjo. 这里一堆的 j 其实表示的是按下 j 直到选中了最后一个候选项为止, 然后我我按下 o 退出ivy即可. 这里的 c 的作用是反转"calling"状态 - a state where the current action is called whenever a different candidate is selected.

差点忘了,如果你想要这项功能的话,你需要从MELPA安装 helm-rhythmboxcounsel 这两个package.