]> code.delx.au - gnu-emacs/blobdiff - lisp/mpc.el
Speed up CC Mode fontification with less accurate functions extending region
[gnu-emacs] / lisp / mpc.el
index 7d684d24c0f22d43c3a1e3c57a1ac2551f8d1f68..aa7fee6adb61ea38069057b0e668f86623a2cfc8 100644 (file)
@@ -1,6 +1,6 @@
 ;;; mpc.el --- A client for the Music Player Daemon   -*- lexical-binding: t -*-
 
-;; Copyright (C) 2006-2015 Free Software Foundation, Inc.
+;; Copyright (C) 2006-2016 Free Software Foundation, Inc.
 
 ;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
 ;; Keywords: multimedia
@@ -265,10 +265,7 @@ defaults to 6600 and HOST defaults to localhost."
       (let ((v (match-string 3 host)))
         (setq host (match-string 2 host))
         (when (and (stringp v) (not (string= "" v)))
-          (setq port
-                (if (string-match "[^[:digit:]]" v)
-                    (string-to-number v)
-                  v)))))
+          (setq port v))))
     (when (file-name-absolute-p host)
       ;; Expand file name because `file-name-absolute-p'
       ;; considers paths beginning with "~" as absolute
@@ -796,6 +793,22 @@ The songs are returned as alists."
   ;; (setq mpc-queue-back nil mpc-queue nil)
   )
 
+(defun mpc-cmd-consume (&optional arg)
+  "Set consume mode state."
+  (mpc-proc-cmd (list "consume" arg) #'mpc-status-refresh))
+
+(defun mpc-cmd-random (&optional arg)
+  "Set random (shuffle) mode state."
+  (mpc-proc-cmd (list "random" arg) #'mpc-status-refresh))
+
+(defun mpc-cmd-repeat (&optional arg)
+  "Set repeat mode state."
+  (mpc-proc-cmd (list "repeat" arg) #'mpc-status-refresh))
+
+(defun mpc-cmd-single (&optional arg)
+  "Set single mode state."
+  (mpc-proc-cmd (list "single" arg) #'mpc-status-refresh))
+
 (defun mpc-cmd-pause (&optional arg callback)
   "Pause or resume playback of the queue of songs."
   (let ((cb callback))
@@ -810,6 +823,9 @@ The songs are returned as alists."
   (mpc-proc-cmd "play")
   (mpc-status-refresh))
 
+(defun mpc-cmd-seekcur (time)
+  (mpc-proc-cmd (list "seekcur" time) #'mpc-status-refresh))
+
 (defun mpc-cmd-add (files &optional playlist)
   "Add the songs FILES to PLAYLIST.
 If PLAYLIST is t or nil or missing, use the main playlist."
@@ -1010,30 +1026,29 @@ If PLAYLIST is t or nil or missing, use the main playlist."
                                                (substring time (match-end 0))
                                              time)))))
                     (`Cover
-                     (if-let ((dir (file-name-directory
-                                    (mpc-file-local-copy (cdr (assq 'file info)))))
-                              (covers '(".folder.png" "cover.jpg" "folder.jpg"))
-                              (cover (cl-loop for file in (directory-files dir)
-                                              if (member (downcase file) covers)
-                                              return (concat dir file)))
-                              (file (with-demoted-errors "MPC: %s"
-                                      (mpc-file-local-copy cover))))
-                         (let (image)
-                           ;; (debug)
-                           (push `(equal ',dir (file-name-directory (cdr (assq 'file info)))) pred)
-                           (if (null size) (setq image (create-image file))
-                             (let ((tempfile (make-temp-file "mpc" nil ".jpg")))
-                               (call-process "convert" nil nil nil
-                                             "-scale" size file tempfile)
-                               (setq image (create-image tempfile))
-                               (mpc-tempfiles-add image tempfile)))
-                           (setq size nil)
-                           (propertize dir 'display image))
-                       ;; Make sure we return something on which we can
-                       ;; place the `mpc-pred' property, as
-                       ;; a negative-cache.  We could also use
-                       ;; a default cover.
-                       (progn (setq size nil) " ")))
+                     (let ((dir (file-name-directory (cdr (assq 'file info)))))
+                       ;; (debug)
+                       (push `(equal ',dir (file-name-directory (cdr (assq 'file info)))) pred)
+                       (if-let ((covers '(".folder.png" "cover.jpg" "folder.jpg"))
+                                (cover (cl-loop for file in (directory-files (mpc-file-local-copy dir))
+                                                if (member (downcase file) covers)
+                                                return (concat dir file)))
+                                (file (with-demoted-errors "MPC: %s"
+                                        (mpc-file-local-copy cover))))
+                           (let (image)
+                             (if (null size) (setq image (create-image file))
+                               (let ((tempfile (make-temp-file "mpc" nil ".jpg")))
+                                 (call-process "convert" nil nil nil
+                                               "-scale" size file tempfile)
+                                 (setq image (create-image tempfile))
+                                 (mpc-tempfiles-add image tempfile)))
+                             (setq size nil)
+                             (propertize dir 'display image))
+                         ;; Make sure we return something on which we can
+                         ;; place the `mpc-pred' property, as
+                         ;; a negative-cache.  We could also use
+                         ;; a default cover.
+                         (progn (setq size nil) " "))))
                     (_ (let ((val (cdr (assq tag info))))
                          ;; For Streaming URLs, there's no other info
                          ;; than the URL in `file'.  Pretend it's in `Title'.
@@ -1109,16 +1124,29 @@ If PLAYLIST is t or nil or missing, use the main playlist."
     ;; is applied elsewhere :-(
     ;; (define-key map [(double mouse-2)] 'mpc-play-at-point)
     (define-key map "p" 'mpc-pause)
+    (define-key map "s" 'mpc-toggle-play)
     (define-key map ">" 'mpc-next)
     (define-key map "<" 'mpc-prev)
-    (define-key map "g" nil)
+    (define-key map "g" 'mpc-seek-current)
     map))
 
 (easy-menu-define mpc-mode-menu mpc-mode-map
   "Menu for MPC.el."
   '("MPC.el"
-    ["Next track" mpc-next]
-    ["Previous track" mpc-prev]
+    ["Play/Pause" mpc-toggle-play]      ;FIXME: Add one of ⏯/▶/⏸ in there?
+    ["Next Track" mpc-next]             ;FIXME: Add ⇥ there?
+    ["Previous Track" mpc-prev]         ;FIXME: Add ⇤ there?
+    ["Seek Within Track" mpc-seek-current]
+    "--"
+    ["Repeat Playlist" mpc-toggle-repeat :style toggle
+     :selected (member '(repeat . "1") mpc-status)]
+    ["Shuffle Playlist" mpc-toggle-shuffle :style toggle
+     :selected (member '(random . "1") mpc-status)]
+    ["Repeat Single Track" mpc-toggle-single :style toggle
+     :selected (member '(single . "1") mpc-status)]
+    ["Consume Mode" mpc-toggle-consume :style toggle
+     :selected (member '(consume . "1") mpc-status)]
+    "--"
     ["Add new browser" mpc-tagbrowser]
     ["Update DB" mpc-update]
     ["Quit" mpc-quit]))
@@ -1828,7 +1856,8 @@ A value of t means the main playlist.")
         (mpc-volume-widget
          (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)))))
+    (when (buffer-live-p status-buf)
+      (with-current-buffer status-buf (force-mode-line-update)))))
 
 (defvar mpc-volume-step 5)
 
@@ -2333,6 +2362,30 @@ This is used so that they can be compared with `eq', which is needed for
     (mpc-status-stop)
     (if proc (delete-process proc))))
 
+(defun mpc-toggle-consume ()
+  "Toggle consume mode: removing played songs from the playlist."
+  (interactive)
+  (mpc-cmd-consume
+   (if (string= "0" (cdr (assq 'consume (mpc-cmd-status)))) "1" "0")))
+
+(defun mpc-toggle-repeat ()
+  "Toggle repeat mode."
+  (interactive)
+  (mpc-cmd-repeat
+   (if (string= "0" (cdr (assq 'repeat (mpc-cmd-status)))) "1" "0")))
+
+(defun mpc-toggle-single ()
+  "Toggle single mode."
+  (interactive)
+  (mpc-cmd-single
+   (if (string= "0" (cdr (assq 'single (mpc-cmd-status)))) "1" "0")))
+
+(defun mpc-toggle-shuffle ()
+  "Toggle shuffling of the playlist (random mode)."
+  (interactive)
+  (mpc-cmd-random
+   (if (string= "0" (cdr (assq 'random (mpc-cmd-status)))) "1" "0")))
+
 (defun mpc-stop ()
   "Stop playing the current queue of songs."
   (interactive)
@@ -2350,6 +2403,22 @@ This is used so that they can be compared with `eq', which is needed for
   (interactive)
   (mpc-cmd-pause "0"))
 
+(defun mpc-seek-current (pos)
+  "Seek within current track."
+  (interactive
+   (list (read-string "Position to go ([+-]seconds): ")))
+  (mpc-cmd-seekcur pos))
+
+(defun mpc-toggle-play ()
+  "Toggle between play and pause.
+If stopped, start playback."
+  (interactive)
+  (if (member (cdr (assq 'state (mpc-cmd-status))) '("stop"))
+      (mpc-cmd-play)
+    (if (member (cdr (assq 'state (mpc-cmd-status))) '("pause"))
+        (mpc-resume)
+      (mpc-pause))))
+
 (defun mpc-play ()
   "Start playing whatever is selected."
   (interactive)