Function: mpc-songs-jump-to
mpc-songs-jump-to is an interactive and byte-compiled function defined
in mpc.el.gz.
Signature
(mpc-songs-jump-to SONG-FILE &optional POSN)
Documentation
Jump to song SONG-FILE; interactively, this is the song at point.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/mpc.el.gz
(defun mpc-songs-jump-to (song-file &optional posn)
"Jump to song SONG-FILE; interactively, this is the song at point."
(interactive
(let* ((event last-nonmenu-event)
(posn (event-end event)))
(with-selected-window (posn-window posn)
(goto-char (posn-point posn))
(list (get-text-property (point) 'mpc-file)
posn))))
(let* ((plbuf (mpc-proc-cmd "playlist"))
(re (if song-file
;; Newer MPCs apparently include "file: " in the buffer.
(concat "^\\([0-9]+\\):\\(?:file: \\)?"
(regexp-quote song-file) "$")))
(sn (with-current-buffer plbuf
(goto-char (point-min))
(when (and re (re-search-forward re nil t))
(match-string 1)))))
(cond
((null re) (posn-set-point posn))
((null sn) (user-error "This song is not in the playlist"))
((null (with-current-buffer plbuf (re-search-forward re nil t)))
;; song-file only appears once in the playlist: no ambiguity,
;; we're good to go!
(mpc-cmd-play sn))
(t
;; The song appears multiple times in the playlist. If the current
;; buffer holds not only the destination song but also the current
;; song, then we will move in the playlist to the same relative
;; position as in the buffer. Otherwise, we will simply choose the
;; song occurrence closest to the current song.
(with-selected-window (posn-window posn)
(let* ((cur (and (markerp overlay-arrow-position)
(marker-position overlay-arrow-position)))
(dest (save-excursion
(goto-char (posn-point posn))
(line-beginning-position)))
(lines (when cur (* (if (< cur dest) 1 -1)
(count-lines cur dest)))))
(with-current-buffer plbuf
(goto-char (point-min))
;; Start the search from the current song.
(forward-line (string-to-number
(or (cdr (assq 'song mpc-status)) "0")))
;; If the current song is also displayed in the buffer,
;; then try to move to the same relative position.
(if lines (forward-line lines))
;; Now search the closest occurrence.
(let* ((next (save-excursion
(when (re-search-forward re nil t)
(cons (point) (match-string 1)))))
(prev (save-excursion
(when (re-search-backward re nil t)
(cons (point) (match-string 1)))))
(sn (cdr (if (and next prev)
(if (< (- (car next) (point))
(- (point) (car prev)))
next prev)
(or next prev)))))
(cl-assert sn)
(mpc-proc-cmd (concat "play " sn))))))))))