Some improvement for the previous patch (previous one still required to
apply this one).

Now you can use SPC to add stuff to the playlist while browsing without
leaving the menu. Also I added some playlist editing stuff to
mpd-browse-playlist:

 - use 'd' to remove the selected song
 - use 'S-Up' to move the selected song up
 - use 'S-down' to move the selected song down

See *mpd-playlist-menu-map*.

-- 

Morgan Veyret (pa...@appart.kicks-ass.net)
http://appart.kicks-ass.net/patzy
>From 3c2208ad8f9763407a7155f1828d288e4fadfa82 Mon Sep 17 00:00:00 2001
From: Morgan Veyret <pa...@appart.kicks-ass.net>
Date: Sat, 21 Feb 2009 00:15:26 +0100
Subject: [PATCH] Added playlist edition through mpd-browse-playlist menu.

Also:
 - cleaned mpd-menu code
 - added mpd-remove-track, mpd-swap-tracks commands
 - added the possibility to add things to the playlist while browsing
   without exiting the menu
---
 contrib/mpd.lisp |  191 +++++++++++++++++++++++++++++++-----------------------
 1 files changed, 111 insertions(+), 80 deletions(-)

diff --git a/contrib/mpd.lisp b/contrib/mpd.lisp
index db2bcd4..6931206 100644
--- a/contrib/mpd.lisp
+++ b/contrib/mpd.lisp
@@ -84,6 +84,8 @@
          mpd-next
          mpd-stop
          mpd-play-track
+          mpd-remove-track
+          mpd-swap-tracks
          mpd-search-genre
          mpd-search-album
          mpd-search-title
@@ -424,36 +426,79 @@ Volume
 
 (defvar *mpd-volume-step* 5)
 
+(defun mpd-menu (title options keymap &optional initial-selection)
+  (let ((*menu-map* keymap))
+    (multiple-value-bind (choice selection)
+        (select-from-menu (current-screen) options title initial-selection)
+      (cond
+        ((null choice)
+         (throw 'stumpwm::error "Abort."))
+        (t (values choice selection))))))
 
-(defcommand mpd-browse-playlist () ()
-  (let ((status (mpd-send-command "status")))
-    (finish-output)
-    (labels ((pick (options)
-                   (let ((selection
-                          (select-from-menu (current-screen) options
-                                            "Play song in playlist"
-                                            (if (equal
-                                                 (assoc-value :state status)
-                                                 "play")
-                                                (parse-integer
-                                                 (assoc-value :song status))
-                                              0))))
-                     (cond
-                      ((null selection)
-                       (throw 'stumpwm::error "Abort."))
-                      (t selection)))))
-      (let* ((response (mpd-send-command "playlistinfo"))
-             (result (mapcar #'cadr (remove-if (lambda (item)
-                                                 (not (equal :file
-                                                             (first item))))
-                                               response))))
-          (let* ((choice (pick result))
-               (song-number (position choice result)))
-          (mpd-send-command (format nil "play ~d" song-number)))))))
+(defun mpd-menu-action (action-type)
+  (lambda (menu)
+    (declare (ignore menu))
+    (setf *current-menu-input* "")
+    (throw :menu-quit
+      (values action-type
+              (mpd-menu-selected-item menu)))))
+
+;; playlist navigation/edition
+(defvar *mpd-playlist-menu-map* nil)
+;(when (null *mpd-playlist-menu-map*)
+  (setf *mpd-playlist-menu-map*
+        (let ((m (make-sparse-keymap)))
+          (define-key m (kbd "C-p") 'menu-up)
+          (define-key m (kbd "Up") 'menu-up)
+          (define-key m (kbd "k") 'menu-up)
+
+          (define-key m (kbd "C-n") 'menu-down)
+          (define-key m (kbd "Down") 'menu-down)
+          (define-key m (kbd "j") 'menu-down)
+          (define-key m (kbd "C-g") 'menu-abort)
+          (define-key m (kbd "ESC") 'menu-abort)
+
+          (define-key m (kbd "S-Up") (mpd-menu-action :mpd-playlist-move-up))
+          (define-key m (kbd "S-Down") (mpd-menu-action 
:mpd-playlist-move-down))
+          (define-key m (kbd "d") (mpd-menu-action :mpd-playlist-delete))
+          (define-key m (kbd "RET") (mpd-menu-action :mpd-playlist-play))
+          m));)
+
+(defcommand mpd-browse-playlist (&optional current-song) ()
+  (let* ((status (mpd-send-command "status"))
+         (response (mpd-send-command "playlistinfo"))
+         (options (mapcar #'cadr (remove-if (lambda (item)
+                                              (not (equal :file
+                                                          (first item))))
+                                            response))))
+    (multiple-value-bind (action choice)
+        (mpd-menu "Current playlist" options *mpd-playlist-menu-map*
+                  (if current-song
+                      current-song
+                      (if (equal (assoc-value :state status) "play")
+                          (parse-integer (assoc-value :song status))
+                          0)))
+      (let ((song-number (position choice options)))
+        (case action
+          (:mpd-playlist-move-up
+           (if (= song-number 1)
+               (mpd-browse-playlist song-number)
+               (progn (mpd-swap-tracks song-number (1- song-number))
+                      (mpd-browse-playlist (1- song-number)))))
+          (:mpd-playlist-move-down
+           (if (= song-number (length options))
+             (mpd-browse-playlist song-number)
+             (progn (mpd-swap-tracks song-number (1+ song-number))
+                    (mpd-browse-playlist (1+ song-number)))))
+          (:mpd-playlist-delete
+           (mpd-remove-track song-number)
+           (mpd-browse-playlist song-number))
+          (:mpd-playlist-play
+           (mpd-play-track song-number)))))))
 
 (defcommand-alias select-song-from-playlist browse-playlist)
 
-;; special menu map for browsing commands
+;; database  browsing
 (defvar *mpd-browse-menu-map* nil)
 (when (null *mpd-browse-menu-map*)
   (setf *mpd-browse-menu-map*
@@ -467,45 +512,14 @@ Volume
           (define-key m (kbd "j") 'menu-down)
           (define-key m (kbd "C-g") 'menu-abort)
           (define-key m (kbd "ESC") 'menu-abort)
-          (define-key m (kbd "RET") 'mpd-menu-action)
 
-          (define-key m (kbd "Right") 'mpd-menu-next)
-          (define-key m (kbd "Left") 'mpd-menu-previous)
-          m)))
+          (define-key m (kbd "RET") (mpd-menu-action :mpd-browse-add-and-quit))
+          (define-key m (kbd "SPC") (mpd-menu-action :mpd-browse-add))
 
+          (define-key m (kbd "Right") (mpd-menu-action :mpd-browse-next))
+          (define-key m (kbd "Left") (mpd-menu-action :mpd-browse-previous))
+          m)))
 
-(defun mpd-menu-next (menu)
-  (declare (ignore menu))
-  (setf *current-menu-input* "")
-  (throw :menu-quit
-    (values :mpd-menu-next
-            (mpd-menu-selected-item menu))))
-
-(defun mpd-menu-previous (menu)
-  (declare (ignore menu))
-  (setf *current-menu-input* "")
-  (throw :menu-quit
-    (values :mpd-menu-previous
-            (mpd-menu-selected-item menu))))
-
-(defun mpd-menu-action (menu)
-  (declare (ignore menu))
-  (setf *current-menu-input* "")
-  (throw :menu-quit
-    (values :mpd-menu-action
-            (mpd-menu-selected-item menu))))
-
-(defun mpd-menu-selected-item (menu)
-  (nth (menu-state-selected menu) (menu-state-table menu)))
-
-(defun mpd-browse-menu (title options)
-  (let ((*menu-map* *mpd-browse-menu-map*))
-    (multiple-value-bind (choice selection)
-        (select-from-menu (current-screen) options title 0)
-      (cond
-        ((null choice)
-         (throw 'stumpwm::error "Abort."))
-        (t (values choice selection))))))
 
 (defcommand mpd-browse-artists (&optional genre) ()
   (let* ((response (mpd-send-command
@@ -517,14 +531,17 @@ Volume
                                                          (first item))))
                                            response))))
         (multiple-value-bind (action choice)
-            (mpd-browse-menu "Select artist" options)
+            (mpd-menu "Select artist" options *mpd-browse-menu-map*)
           (case action
-            (:mpd-menu-action
+            (:mpd-browse-add-and-quit
              (mpd-search-and-add-artist choice t))
-            (:mpd-menu-previous
+            (:mpd-browse-add
+             (mpd-search-and-add-artist choice t)
+             (mpd-browse-artists genre))
+            (:mpd-browse-previous
              (unless %interactivep%
                (mpd-browse-genres)))
-            (:mpd-menu-next
+            (:mpd-browse-next
                (mpd-browse-albums choice genre))))))
 
 (defcommand mpd-browse-genres () ()
@@ -534,11 +551,14 @@ Volume
                                                            (first item))))
                                              response))))
         (multiple-value-bind (action choice)
-            (mpd-browse-menu "Select genre" options)
+            (mpd-menu "Select genre" options *mpd-browse-menu-map*)
           (case action
-            (:mpd-menu-action
+            (:mpd-browse-add-and-quit
              (mpd-search-and-add-genre choice t))
-            (:mpd-menu-next
+            (:mpd-browse-add
+             (mpd-search-and-add-genre choice t)
+             (mpd-browse-genres))
+            (:mpd-browse-next
                (mpd-browse-artists choice))))))
 
 (defcommand mpd-browse-albums (&optional artist genre) ((:string "Artist: "))
@@ -550,14 +570,17 @@ Volume
                                               (not (equal :album (first 
item))))
                                              response))))
         (multiple-value-bind (action choice)
-            (mpd-browse-menu "Select album" options)
+            (mpd-menu "Select album" options *mpd-browse-menu-map*)
           (case action
-            (:mpd-menu-action
+            (:mpd-browse-add-and-quit
              (mpd-search-and-add-album choice t))
-            (:mpd-menu-previous
+            (:mpd-browse-add
+             (mpd-search-and-add-album choice t)
+             (mpd-browse-albums artist genre))
+            (:mpd-browse-previous
              (unless %interactivep%
                (mpd-browse-artists genre)))
-            (:mpd-menu-next
+            (:mpd-browse-next
                (mpd-browse-tracks choice artist))))))
 
 (defcommand mpd-browse-tracks (album &optional artist) ((:string "Album: "))
@@ -567,15 +590,18 @@ Volume
                                               (not (equal :title (first 
item))))
                                              response))))
         (multiple-value-bind (action choice)
-            (mpd-browse-menu "Select track" options)
+            (mpd-menu "Select track" options *mpd-browse-menu-map*)
           (case action
-            (:mpd-menu-action
+            (:mpd-browse-add-and-quit
              (mpd-search-and-add-title choice t))
-            (:mpd-menu-previous
+            (:mpd-browse-add
+             (mpd-search-and-add-title choice t)
+             (mpd-browse-tracks album artist))
+            (:mpd-browse-previous
              (unless %interactivep%
                (mpd-browse-albums artist)))))))
 
-
+;;misc. commands
 (defcommand mpd-connect () ()
   (message "~a" (init-mpd-connection)))
 
@@ -644,7 +670,7 @@ Passed an argument of zero and if crossfade is on, toggles 
crossfade off."
 (defcommand mpd-prev () ()
   (mpd-send-command "previous"))
 
-(defcommand mpd-set-volume (vol) ((rest "Set volume to: "))
+(defcommand mpd-set-volume (vol) ((:number "Set volume to: "))
   (mpd-send-command (format nil "setvol ~a" vol)))
 
 (defcommand mpd-volume-up () ()
@@ -690,7 +716,13 @@ Passed an argument of zero and if crossfade is on, toggles 
crossfade off."
       (message "~a files in playlist" (length result)))))
 
 (defcommand mpd-add-file (file) ((:rest "Add file to playlist: "))
-  (mpd-send-command (format nil "add \"~a\"" file)))
+  (mpd-format-command "add \"~a\"" file))
+
+(defcommand mpd-remove-track (track-number) ((:number "Delete track number: "))
+  (mpd-format-command "delete ~d" track-number))
+
+(defcommand mpd-swap-tracks (track-1 track-2) ()
+  (mpd-format-command "swap ~d ~d" track-1 track-2))
 
 ;;search and add commands
 (defcommand mpd-search-and-add-artist (what &optional (exact-search nil))
@@ -781,7 +813,6 @@ Passed an argument of zero and if crossfade is on, toggles 
crossfade off."
 (defvar *mpd-map* nil)
 
 ;;Key map
-;;FIXME: maybe some inferior mode would be a good idea (see resize in 
user.lisp)
 (fill-keymap *mpd-search-map*
              (kbd "a") "mpd-search-artist"
              (kbd "A") "mpd-search-album"
-- 
1.6.0.3

_______________________________________________
Stumpwm-devel mailing list
Stumpwm-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/stumpwm-devel

Reply via email to