branch: externals/mpdired commit ec768308ac026f508cba33c5be3e52b4e894dbfe Author: Manuel Giraud <man...@ledu-giraud.fr> Commit: Manuel Giraud <man...@ledu-giraud.fr>
a recursive parser for listall --- mpdired.el | 72 +++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 17 deletions(-) diff --git a/mpdired.el b/mpdired.el index f6d511cf21..4f2ecf8b64 100644 --- a/mpdired.el +++ b/mpdired.el @@ -4,24 +4,61 @@ (defcustom mpdired-port (or (getenv "MPD_PORT") 6600) "Host for MPD.") -(defun my-filter (proc string) - (when (buffer-live-p (process-buffer proc)) - (with-current-buffer (process-buffer proc) - (let ((moving (= (point) (process-mark proc)))) - (save-excursion - ;; Insert the text, advancing the process marker. - (goto-char (process-mark proc)) - (insert string) - (set-marker (process-mark proc) (point))) - (if moving (goto-char (process-mark proc))) - (when (re-search-backward "^OK$" nil t) - (goto-char (point-min)) - (set-buffer-modified-p nil) - (message "Fini")))))) +(defun mpdired--subdir-p (dir-a dir-b) + (let ((pos (string-search dir-a dir-b))) + (and pos (zerop pos)))) + +(defvar mpdired--parse-end nil) + +(defun mpdired--parse-listall-1 (current accum) + ;; Recursively rebuild the directory hierarchy from a "listall" + ;; command into a list. In the output, a directory is list which + ;; `car' is its name and its `cdr' is the files or other directory + ;; it contains. + (catch 'exit + (while (not (or mpdired--parse-end + (setq mpdired--parse-end + (re-search-forward "^OK$" (line-end-position) t 1)))) + ;; Look for file or directory line by line (I'm not interested + ;; in playlist) + (re-search-forward "^\\(file\\|directory\\): \\(.*\\)$" (line-end-position) t 1) + (let ((type (match-string 1)) + (new (match-string 2))) + (cond ((string= "file" type) (push new accum)) + ((string= "directory" type) + ;; This new directory is either a subdir of the current + ;; one or a new directory of the same level of the + ;; current one. In this last case we need to go one + ;; line backward and quit the loop. + (cond ((mpdired--subdir-p current new) + (forward-line) + (push (mpdired--parse-listall-1 new (list new)) accum)) + (t (forward-line -1) + (throw 'exit t)))))) + (forward-line))) + (reverse accum)) + +(defun mpdired--parse-listall () + ;; Called from *mpdired-work* + (goto-char (point-min)) + (setq mpdired--parse-end nil) + ;; XXX Empty string is the directory name of the toplevel directory. + (mpdired--parse-listall-1 "" (list ""))) + +(defun mpdired-present-listall (contact) + ;; Called from *mpdired-work* + (let ((out (get-buffer-create (format "*MPDired (%s:%d)*" + (car contact) (cadr contact)))) + (content (mpdired--parse-listall))) + (with-current-buffer out + (erase-buffer) + (dolist (e content) + (cond ((stringp e) (insert (format "%s\n" e))) + ((consp e) (insert (format ">%s\n" (car e))))))))) (defun msg-me (process event) - (princ - (format "Process: %s had the event '%s'" process event))) + (unless (string-search "connection broken" event) + (message "Process: %s had the event '%s'" process event))) (defvar mpdired-process nil) @@ -31,7 +68,8 @@ (file-exists-p (expand-file-name host))) (defun mpc-connect () - (with-current-buffer (get-buffer-create "*mpc*") + (with-current-buffer (get-buffer-create "*mpdired-work*") + (setq-local buffer-read-only nil) (erase-buffer) (let* ((localp (mpdired-local-p mpdired-host)) (host (if localp (expand-file-name mpdired-host) mpdired-host)))