From 8027bb23119322eaf6c4601fbd4e3ae31b88961f Mon Sep 17 00:00:00 2001 From: Michael Olson Date: Wed, 31 May 2006 20:38:00 +0000 Subject: Make handling of multiple playlist buffers less error-prone. darcs-hash:20060531203810-1bfb2-7a5c8ca307d33ea501871a6222ab76ad4ada498d.gz --- emms-playlist-mode.el | 3 +- emms-streams.el | 34 +++++++++++++++-------- emms.el | 77 +++++++++++++++++++++++++++++++++++++++------------ 3 files changed, 83 insertions(+), 31 deletions(-) diff --git a/emms-playlist-mode.el b/emms-playlist-mode.el index 3f673cb..4f6ac2a 100644 --- a/emms-playlist-mode.el +++ b/emms-playlist-mode.el @@ -440,7 +440,8 @@ This preserves the current EMMS buffer." (type (emms-track-get track 'type))) (emms-playlist-select (point)) (run-hooks 'emms-player-stopped-hook) - (switch-to-buffer (setq emms-playlist-buffer (emms-playlist-new))) + (switch-to-buffer + (emms-playlist-set-playlist-buffer (emms-playlist-new))) (emms-add-playlist name))) ;;; -------------------------------------------------------- diff --git a/emms-streams.el b/emms-streams.el index bf67b05..10c0d05 100644 --- a/emms-streams.el +++ b/emms-streams.el @@ -83,10 +83,8 @@ needed info.") (defvar emms-stream-last-stream nil "The last stream added/played by EMMS.") -(defvar emms-stream-owns-buffer nil - "Indicate whether the current EMMS playlist buffer is owned by -emms-streams.") -(make-variable-buffer-local 'emms-stream-owns-buffer) +(defvar emms-stream-playlist-buffer nil + "The EMMS playlist buffer associated with emms-streams.") ;; Format: (("descriptive name" url feed-number type)) ;; type could be either url or playlist. If url, then it represents a @@ -174,9 +172,7 @@ emms-streams.") (set-buffer (get-buffer-create emms-stream-buffer-name)) (erase-buffer) (when (string= emms-stream-default-action "play") - (save-excursion - (with-current-buffer (setq emms-playlist-buffer (emms-playlist-new)) - (setq emms-stream-owns-buffer t)))) + (emms-stream-create-playlist)) (emms-stream-mode) (switch-to-buffer emms-stream-buffer-name)) @@ -198,6 +194,22 @@ emms-streams.") (set-buffer-modified-p nil) (message "EMMS Stream Menu")) +(defun emms-stream-create-playlist () + "Create a new EMMS playlist and associate it with emms-streams. +This is used when `emms-stream-default-action' is \"play\"." + (save-excursion + (setq emms-stream-playlist-buffer + (emms-playlist-set-playlist-buffer (emms-playlist-new))))) + +(defun emms-stream-kill-playlist () + "Delete the EMMS playlist associated with emms-streams, if one exists." + (when (buffer-live-p emms-stream-playlist-buffer) + (save-excursion + (if (eq emms-stream-playlist-buffer emms-playlist-buffer) + (emms-playlist-current-kill) + (kill-buffer emms-stream-playlist-buffer))) + (setq emms-stream-playlist-buffer nil))) + (defun emms-stream-popup-revert () "Revert to the window-configuration from before if there is one, otherwise just remove the special bindings from the stream menu." @@ -496,11 +508,7 @@ Don't forget to save your modifications !" (defun emms-stream-quit () (interactive) - (save-excursion - (when (and (buffer-live-p emms-playlist-buffer) - (with-current-emms-playlist emms-stream-owns-buffer)) - (emms-stop) - (emms-playlist-current-kill))) + (emms-stream-kill-playlist) (kill-this-buffer) (run-hooks 'emms-stream-quit-hook)) @@ -508,8 +516,10 @@ Don't forget to save your modifications !" (interactive) (if (string= emms-stream-default-action "play") (progn + (emms-stream-kill-playlist) (setq emms-stream-default-action "add") (message "Default action is now add")) + (emms-stream-create-playlist) (setq emms-stream-default-action "play") (message "Default action is now play"))) diff --git a/emms.el b/emms.el index 0731202..02ce9dd 100644 --- a/emms.el +++ b/emms.el @@ -425,6 +425,25 @@ If POS is nil, use current buffer location." (match-string-no-properties num string) (match-string num string))) +(defun emms-delete-if (predicate seq) + "Remove all items satisfying PREDICATE in SEQ. +This is a destructive function: it reuses the storage of SEQ +whenever possible." + ;; remove from car + (while (when (funcall predicate (car seq)) + (setq seq (cdr seq)))) + ;; remove from cdr + (let ((ptr seq) + (next (cdr seq))) + (while next + (when (funcall predicate (car next)) + (setcdr ptr (if (consp next) + (cdr next) + nil))) + (setq ptr (cdr ptr)) + (setq next (cdr ptr)))) + seq) + ;;; Tracks @@ -488,6 +507,12 @@ Otherwise, return the type and the name with a colon in between." (defvar emms-playlist-buffer nil "The current playlist buffer, if any.") +(defvar emms-playlist-buffers nil + "The list of EMMS playlist buffers. +You should use the `emms-playlist-buffer-list' function to +retrieve a current list of EMMS buffers. Never use this variable +for that purpose.") + (defvar emms-playlist-selected-marker nil "The marker for the currently selected track.") (make-variable-buffer-local 'emms-playlist-selected-marker) @@ -538,34 +563,50 @@ If called interactively, the new buffer is also selected." (when (not (eq major-mode emms-playlist-default-major-mode)) (funcall emms-playlist-default-major-mode)) (setq emms-playlist-buffer-p t)) + (add-to-list 'emms-playlist-buffers buf) (when (interactive-p) (switch-to-buffer buf)) buf)) (defun emms-playlist-buffer-list () "Return a list of EMMS playlist buffers. -The first element will be the most recently-created playlist, and -so on." - (let ((lis nil)) - (mapc (lambda (buf) - (with-current-buffer buf - (when emms-playlist-buffer-p - (setq lis (cons buf lis))))) - (buffer-list)) - (nreverse lis))) +The first element is guaranteed to be the current EMMS playlist +buffer, if it exists, otherwise the slot will be used for the +other EMMS buffers. The list will be in newest-first order." + ;; prune dead buffers + (setq emms-playlist-buffers (emms-delete-if (lambda (buf) + (not (buffer-live-p buf))) + emms-playlist-buffers)) + ;; add new buffers + (mapc (lambda (buf) + (when (buffer-live-p buf) + (with-current-buffer buf + (when (and emms-playlist-buffer-p + (not (memq buf emms-playlist-buffers))) + (setq emms-playlist-buffers + (cons buf emms-playlist-buffers)))))) + (buffer-list)) + ;; force current playlist buffer to head position + (when (and (buffer-live-p emms-playlist-buffer) + (not (eq (car emms-playlist-buffers) emms-playlist-buffer))) + (setq emms-playlist-buffers (cons emms-playlist-buffer + (delete emms-playlist-buffer + emms-playlist-buffers)))) + emms-playlist-buffers) (defun emms-playlist-current-kill () "Kill the current EMMS playlist buffer and switch to the next one." (interactive) - (let ((new (cadr (emms-playlist-buffer-list)))) - (if (buffer-live-p new) - (progn - (when (buffer-live-p emms-playlist-buffer) - (kill-buffer emms-playlist-buffer)) - (setq emms-playlist-buffer new) - (switch-to-buffer emms-playlist-buffer)) - (with-current-buffer emms-playlist-buffer - (bury-buffer))))) + (when (buffer-live-p emms-playlist-buffer) + (let ((new (cadr (emms-playlist-buffer-list)))) + (if new + (let ((old emms-playlist-buffer)) + (setq emms-playlist-buffer new + emms-playlist-buffers (cdr emms-playlist-buffers)) + (kill-buffer old) + (switch-to-buffer emms-playlist-buffer)) + (with-current-buffer emms-playlist-buffer + (bury-buffer)))))) (defun emms-playlist-current-clear () "Clear the current playlist. -- cgit v1.2.3