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