consult-emms 提供了非常完善的 emms
索引:支持 artist、album、track 和 genre 四种类型的检索,结合 Global interactive Emacs functions 中的函数,就可以全局切换 emms 中的曲目,效果如下:
不过需要稍微修改下 consult-emms--playlist
这个函数:
(with-eval-after-load 'consult-emms
(defun consult-emms--playlist (buffer)
"Select a track from EMMS buffer BUFFER.
BUFFER is a string, 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
;; `consult--multi', which is different from the arg list taken by
;; `consult--read', so we have to transform it a bit.
(let* ((raw-args (consult-emms--playlist-source-from-buffer buffer))
(items (plist-get raw-args :items))
(action (plist-get raw-args :action))
;; TODO Get this list programatically
(allowed '(:prompt :predicate :require-match ;; Keywords in `consult--read'
:history :default :keymap
:category :initial :narrow
:add-history :annotate :state
:preview-key :sort :group
:inherit-input-method))
;; Use only arg keys used by `consult--read'
(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>: " buffer))
filtered-args))
;; Lots of the actions use text properties as variables, so
;; make sure they persist through minibuffer choice
(minibuffer-allow-text-properties t)
(raw-track (apply 'consult--read `(,items ,@read-args)))
(track (cl-loop for item in items
until (string= item raw-track)
finally return item)))
;; Using the action extracted above guarantees that the behaviour
;; will be the same as with the corresponding source
(unless (string-empty-p raw-track)
(funcall action track)))))
这样个人感觉 emms 的体验就和主流音乐播放器差不多了,甚至功能更强。