branch: externals/mpdired
commit 6da84bce768efb5a920c8b78bf99763aeb0f730f
Author: Manuel Giraud <man...@ledu-giraud.fr>
Commit: Manuel Giraud <man...@ledu-giraud.fr>

    functional playlist view
---
 mpdired.el | 109 ++++++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 79 insertions(+), 30 deletions(-)

diff --git a/mpdired.el b/mpdired.el
index 7fb8a2a855..e6cd3aa6fa 100644
--- a/mpdired.el
+++ b/mpdired.el
@@ -1,8 +1,10 @@
 (defcustom mpdired-host (or (getenv "MPD_HOST") "localhost")
-  "Host for MPD.")
+  "Host for MPD."
+  :type 'string)
 
 (defcustom mpdired-port (or (getenv "MPD_PORT") 6600)
-  "Host for MPD.")
+  "Host for MPD."
+  :type 'integer)
 
 (defvar-keymap mpdired-mode-map
   :doc "Local keymap for MPDired."
@@ -12,7 +14,8 @@
   "p"   'mpdired-previous-line
   "q"   'bury-buffer
   "C-m" 'mpdired-listall-at-point
-  "^"   'mpdired-goto-parent)
+  "^"   'mpdired-goto-parent
+  "o"   'mpdired-toggle-view)
 
 (defun mpdired--subdir-p (dir-a dir-b)
   (let ((pos (string-search dir-a dir-b)))
@@ -56,13 +59,29 @@
   (reverse accum))
 
 (defun mpdired--parse-listall ()
-  ;; Called from *mpdired-work*
+  ;; Called from the communication buffer.
   (goto-char (point-min))
   (setq mpdired--parse-endp nil)
   ;; XXX Empty string is the directory name of the toplevel directory.
   ;; It have the good property of being a prefix of any string.
   (mpdired--parse-listall-1 "" (list "")))
 
+(defun mpdired--parse-playlist ()
+  ;; Called from the communication buffer.
+  (goto-char (point-min))
+  (setq mpdired--parse-endp nil)
+  (let (result)
+    (while (not (or mpdired--parse-endp
+                   (setq mpdired--parse-endp
+                         (re-search-forward "^OK$" (line-end-position) t 1))))
+      ;; Look for file with id in the playlist
+      (when (re-search-forward "^\\([0-9]+\\):file: \\(.*\\)$" 
(line-end-position) t 1)
+       (let ((id (string-to-number (match-string 1)))
+             (name (match-string 2)))
+         (push (cons id name) result)))
+      (forward-line))
+    (reverse result)))
+
 (defun mpdired-mode ()
   "Major mode for MPDired."
   (kill-all-local-variables)
@@ -88,6 +107,7 @@
   "Current directory of the browser view.")
 
 ;; State variables for the main buffer
+(defvar-local mpdired--view nil)
 (defvar-local mpdired--comm-buffer nil
   "Communication buffer associated to this MPDired buffer.")
 
@@ -99,8 +119,12 @@
         (insert (propertize (car entry) 'face 'dired-directory))
         (put-text-property (line-beginning-position) (line-end-position) 'type 
'directory))))
 
+(defun mpdired--insert-song (song)
+  (insert (propertize (cdr song) 'face 'dired-ignored))
+  (put-text-property (line-beginning-position) (line-end-position) 'id (car 
song)))
+
 (defun mpdired--present-listall (proc)
-  ;; Called from *mpdired-work*
+  ;; Called by filter of the communication buffer.
   (let* ((peer-info (process-contact proc t))
         (peer-host (plist-get peer-info :host))
         (peer-service (plist-get peer-info :service))
@@ -122,7 +146,7 @@
               (data (cdr content)))
          ;; Insert the content
          (save-excursion
-           (if top (insert (propertize top 'face 'bold) ":\n"))
+           (if top (insert (propertize top 'face 'dired-header) ":\n"))
            (dolist (e (butlast data))
              (mpdired--insert-entry e)
              (insert "\n"))
@@ -135,13 +159,33 @@
                (t
                 (goto-char (point-min))
                 (if top (mpdired-next-line))))
-         ;; Set mode and memorize directory
+         ;; Set mode and memorize stuff
          (mpdired-mode)
          (setq mpdired--directory (when top top)
-               mpdired--comm-buffer (process-buffer proc)))))))
+               mpdired--comm-buffer (process-buffer proc)
+               mpdired--view 'browser))))))
 
-(defun mpdired--present-playlist ()
-  (message "I should do something"))
+(defun mpdired--present-playlist (proc)
+  ;; Called by filter of the communication buffer.
+  (let* ((peer-info (process-contact proc t))
+        (peer-host (plist-get peer-info :host))
+        (peer-service (plist-get peer-info :service))
+        (peer-localp (eq (plist-get peer-info :family) 'local))
+        (buffer-name (mpdired--main-name peer-host peer-service peer-localp))
+        (content (mpdired--parse-playlist)))
+    (with-current-buffer (get-buffer-create buffer-name)
+      (let ((inhibit-read-only t))
+       (erase-buffer)
+       ;; Insert the content
+       (save-excursion
+         (dolist (song (butlast content))
+           (mpdired--insert-song song)
+           (insert "\n"))
+         (mpdired--insert-song (car (last content))))
+       ;; Set mode and memorize stuff
+       (mpdired-mode)
+       (setq mpdired--comm-buffer (process-buffer proc)
+             mpdired--view 'playlist)))))
 
 (defun mpdired--filter (proc string)
   (when (buffer-live-p (process-buffer proc))
@@ -158,7 +202,7 @@
          (cond ((eq mpdired--last-command 'listall)
                 (mpdired--present-listall proc))
                ((eq mpdired--last-command 'playlist)
-                (mpdired--present-playlist))))))))
+                (mpdired--present-playlist proc))))))))
 
 (defun mpdired--sentinel (process event)
   (message "Process: %s had the event '%s'" process event))
@@ -206,14 +250,8 @@
              mpdired--ascending-p ascending-p)
        (process-send-string process (format "listall \"%s\"\n" path))))))
 
-(defun mpdired-listall (path)
-  ;; Always reparse host should the user have changed it.
-  (let* ((localp (mpdired--local-p mpdired-host))
-        (host (if localp (expand-file-name mpdired-host) mpdired-host))
-        (service (if localp host mpdired-port))
-        (comm-name (mpdired--comm-name host service localp)))
-    (mpdired--maybe-init host service localp)
-    (mpdired-listall-internal path nil comm-name)))
+(defun mpdired-listall (path comm-buffer)
+  (mpdired-listall-internal path nil comm-buffer))
 
 (defun mpdired-playlist-internal (&optional buffer)
   (with-current-buffer (or buffer mpdired--comm-buffer)
@@ -224,15 +262,8 @@
        (setq mpdired--last-command 'playlist)
        (process-send-string process "playlist\n")))))
 
-(defun mpdired-playlist ()
-  (interactive)
-  ;; Always reparse host should the user have changed it.
-  (let* ((localp (mpdired--local-p mpdired-host))
-        (host (if localp (expand-file-name mpdired-host) mpdired-host))
-        (service (if localp host mpdired-port))
-        (comm-name (mpdired--comm-name host service localp)))
-    (mpdired--maybe-init host service localp)
-    (mpdired-playlist-internal comm-name)))
+(defun mpdired-playlist (comm-buffer)
+  (mpdired-playlist-internal comm-buffer))
 
 (defun mpdired-next-line ()
   (interactive)
@@ -275,6 +306,24 @@
        (mpdired-listall-internal parent t)
       (message "You are at the toplevel."))))
 
-(defun mpdired-test-me ()
+(defun mpdired-toggle-view ()
+  (interactive)
+  (if (eq mpdired--view 'browser)
+      (mpdired-playlist-internal)
+    (if mpdired--directory
+       (mpdired-listall-internal mpdired--directory)
+      (mpdired-listall-internal ""))))
+
+;; Main entry point
+(defun mpdired ()
   (interactive)
-  (mpdired-listall ""))
+  ;; Get user's host and service current setting.
+  (let* ((localp (mpdired--local-p mpdired-host))
+        (host (if localp (expand-file-name mpdired-host) mpdired-host))
+        (service (if localp host mpdired-port))
+        (comm-name (mpdired--comm-name host service localp))
+        (main-name (mpdired--main-name host service localp)))
+    (mpdired--maybe-init host service localp)
+    ;; Defaults to playlist view
+    (mpdired-playlist comm-name)
+    (pop-to-buffer main-name)))

Reply via email to