]> code.delx.au - gnu-emacs/blobdiff - lisp/mpc.el
Update copyright year to 2015
[gnu-emacs] / lisp / mpc.el
index bd61c261246077d341e2d3b996d9a4ba61402a83..76c08dbcbebece30aa2a1e0495d46c591d0988d7 100644 (file)
@@ -1,6 +1,6 @@
-;;; mpc.el --- A client for the Music Player Daemon   -*- coding: utf-8; lexical-binding: t -*-
+;;; mpc.el --- A client for the Music Player Daemon   -*- lexical-binding: t -*-
 
-;; Copyright (C) 2006-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2006-2015 Free Software Foundation, Inc.
 
 ;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
 ;; Keywords: multimedia
@@ -491,9 +491,13 @@ to call FUN for any change whatsoever.")
     (cancel-timer mpc--status-timer)
     (setq mpc--status-timer nil)))
 (defun mpc--status-timer-run ()
-  (with-demoted-errors "MPC: %s"
+  (with-demoted-errors "MPC: %S"
     (when (process-get (mpc-proc) 'ready)
-      (with-local-quit (mpc-status-refresh)))))
+      (let* ((buf (mpc-proc-buffer (mpc-proc) 'status))
+             (win (get-buffer-window buf t)))
+        (if (not win)
+            (mpc--status-timer-stop)
+          (with-local-quit (mpc-status-refresh)))))))
 
 (defvar mpc--status-idle-timer nil)
 (defun mpc--status-idle-timer-start ()
@@ -518,10 +522,8 @@ to call FUN for any change whatsoever.")
           ;; client starts playback, we may get a chance to notice it.
           (run-with-idle-timer 10 t 'mpc--status-idle-timer-run))))
 (defun mpc--status-idle-timer-run ()
-  (when (process-get (mpc-proc) 'ready)
-    (with-demoted-errors "MPC: %s"
-        (with-local-quit (mpc-status-refresh))))
-  (mpc--status-timer-start))
+  (mpc--status-timer-start)
+  (mpc--status-timer-run))
 
 (defun mpc--status-timers-refresh ()
   "Start/stop the timers according to whether a song is playing."
@@ -889,9 +891,7 @@ If PLAYLIST is t or nil or missing, use the main playlist."
   :type '(choice (const nil) directory))
 
 (defcustom mpc-data-directory
-  (if (and (not (file-directory-p "~/.mpc"))
-           (file-directory-p "~/.emacs.d"))
-      "~/.emacs.d/mpc" "~/.mpc")
+  (locate-user-emacs-file "mpc" ".mpc")
   "Directory where MPC.el stores auxiliary data."
   :type 'directory)
 
@@ -1022,7 +1022,12 @@ If PLAYLIST is t or nil or missing, use the main playlist."
                          (when (and (null val) (eq tag 'Title))
                            (setq val (cdr (assq 'file info))))
                          (push `(equal ',val (cdr (assq ',tag info))) pred)
-                         val)))))
+                         (cond
+                          ((not (and (eq tag 'Date) (stringp val))) val)
+                          ;; For "date", only keep the year!
+                          ((string-match "[0-9]\\{4\\}" val)
+                           (match-string 0 val))
+                          (t val)))))))
                (space (when size
                         (setq size (string-to-number size))
                         (propertize " " 'display
@@ -1139,7 +1144,8 @@ If PLAYLIST is t or nil or missing, use the main playlist."
   "Major mode for the features common to all buffers of MPC."
   (buffer-disable-undo)
   (setq buffer-read-only t)
-  (setq-local tool-bar-map mpc-tool-bar-map)
+  (if (boundp 'tool-bar-map)            ; not if --without-x
+      (setq-local tool-bar-map mpc-tool-bar-map))
   (setq-local truncate-lines t))
 
 ;;; The mpc-status-mode buffer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1616,7 +1622,7 @@ Return non-nil if a selection was deactivated."
           (setq active
                 (if (listp active) (mpc-intersection active vals) vals))))
 
-      (when (and (listp active))
+      (when (listp active)
         ;; Remove the selections if they are all in conflict with
         ;; other constraints.
         (let ((deactivate t))
@@ -1630,8 +1636,14 @@ Return non-nil if a selection was deactivated."
               (setq selection nil)
               (mapc 'delete-overlay mpc-select)
               (setq mpc-select nil)
-              (mpc-tagbrowser-all-select)))))
-
+              (mpc-tagbrowser-all-select))))
+
+        ;; Don't bother splitting the "active" elements to the first part if
+        ;; they're the same as the selection.
+        (when (equal (sort (copy-sequence active) #'string-lessp)
+                     (sort (copy-sequence selection) #'string-lessp))
+          (setq active 'all)))
+      
       ;; FIXME: This `mpc-sort' takes a lot of time.  Maybe we should
       ;; be more clever and presume the buffer is mostly sorted already.
       (mpc-sort (if (listp active) active))
@@ -1793,7 +1805,9 @@ A value of t means the main playlist.")
   ;; Maintain the volume.
   (setq mpc-volume
         (mpc-volume-widget
-         (string-to-number (cdr (assq 'volume mpc-status))))))
+         (string-to-number (cdr (assq 'volume mpc-status)))))
+  (let ((status-buf (mpc-proc-buffer (mpc-proc) 'status)))
+    (when status-buf (with-current-buffer status-buf (force-mode-line-update)))))
 
 (defvar mpc-volume-step 5)
 
@@ -1808,9 +1822,14 @@ A value of t means the main playlist.")
                         (char-after (posn-point posn))))
                     '(?◁ ?<))
               (- mpc-volume-step) mpc-volume-step))
-         (newvol (+ (string-to-number (cdr (assq 'volume mpc-status))) diff)))
-    (mpc-proc-cmd (list "setvol" newvol) 'mpc-status-refresh)
-    (message "Set MPD volume to %s%%" newvol)))
+         (curvol (string-to-number (cdr (assq 'volume mpc-status))))
+         (newvol (max 0 (min 100 (+ curvol diff)))))
+    (if (= newvol curvol)
+        (progn
+          (message "MPD volume already at %s%%" newvol)
+          (ding))
+      (mpc-proc-cmd (list "setvol" newvol) 'mpc-status-refresh)
+      (message "Set MPD volume to %s%%" newvol))))
 
 (defun mpc-volume-widget (vol &optional size)
   (unless size (setq size 12.5))
@@ -1858,7 +1877,7 @@ This is used so that they can be compared with `eq', which is needed for
 `text-property-any'.")
 (defun mpc-songs-hashcons (name)
   (or (gethash name mpc-songs-hashcons) (puthash name name mpc-songs-hashcons)))
-(defcustom mpc-songs-format "%2{Disc--}%3{Track} %-5{Time} %25{Title} %20{Album} %20{Artist} %10{Date}"
+(defcustom mpc-songs-format "%2{Disc--}%3{Track} %-5{Time} %25{Title} %20{Album} %20{Artist} %5{Date}"
   "Format used to display each song in the list of songs."
   :type 'string)
 
@@ -2008,14 +2027,16 @@ This is used so that they can be compared with `eq', which is needed for
              posn))))
   (let* ((plbuf (mpc-proc-cmd "playlist"))
          (re (if song-file
-                (concat "^\\([0-9]+\\):" (regexp-quote 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) (error "This song is not in the playlist"))
+     ((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!
@@ -2325,7 +2346,7 @@ This is used so that they can be compared with `eq', which is needed for
     (if (mpc-playlist-add)
         (if (member (cdr (assq 'state (mpc-cmd-status))) '("stop"))
             (mpc-cmd-play))
-      (error "Don't know what to play"))))
+      (user-error "Don't know what to play"))))
 
 (defun mpc-next ()
   "Jump to the next song in the queue."
@@ -2589,7 +2610,8 @@ This is used so that they can be compared with `eq', which is needed for
             (mpc-cmd-move (let ((poss '()))
                             (dotimes (i (length songs))
                                      (push (+ i (length pl)) poss))
-                            (nreverse poss)) dest-pos mpc-songs-playlist)
+                            (nreverse poss))
+                            dest-pos mpc-songs-playlist)
             (message "Added %d songs" (length songs)))))
         (mpc-songs-refresh))
       (t