aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--emms.el114
1 files changed, 97 insertions, 17 deletions
diff --git a/emms.el b/emms.el
index f63a867..c5ce905 100644
--- a/emms.el
+++ b/emms.el
@@ -100,6 +100,16 @@ songs, increase this number."
:type 'number
:group 'emms)
+(defcustom emms-shuffle-function 'emms-shuffle-all
+ "*The function to use for shuffling the playlist."
+ :type 'function
+ :group 'emms)
+
+(defcustom emms-sort-function 'emms-sort-all
+ "*The function to use for sorting the playlist."
+ :type 'function
+ :group 'emms)
+
(defcustom emms-sort-lessp-function 'emms-sort-track-name-less-p
"*Function for comparing two EMMS tracks.
The function should return non-nil if and only if the first track
@@ -279,14 +289,32 @@ This function uses `emms-show-format' to format the current track."
(message "%s" string))))
(defun emms-shuffle ()
- "Shuffle the EMMS playlist."
+ "Shuffle the current playlist.
+This uses `emms-shuffle-function'."
+ (interactive)
+ (call-interactively emms-shuffle-function))
+
+(defun emms-shuffle-all ()
+ "Shuffle the whole playlist.
+This is a suitable value for `emms-shuffle-function'."
(interactive)
- (emms-playlist-shuffle))
+ (with-current-emms-playlist
+ (emms-playlist-shuffle (point-min)
+ (point-max))))
(defun emms-sort ()
- "Sort the EMMS playlist."
+ "Sort the current playlist.
+This uses `emms-shuffle-function'."
(interactive)
- (emms-playlist-sort))
+ (call-interactively emms-sort-function))
+
+(defun emms-sort-all ()
+ "Sort the whole playlist.
+This is a suitable value for `emms-sort-function'."
+ (interactive)
+ (with-current-emms-playlist
+ (emms-playlist-sort (point-min)
+ (point-max))))
(defun emms-toggle-repeat-playlist ()
"Toggle whether emms repeats the playlist after it is done.
@@ -579,18 +607,69 @@ This uses `emms-playlist-insert-track-function'."
(apply source args)
(run-hooks emms-playlist-source-inserted-hook))))
-;;; FIXME!
-(defun emms-playlist-shuffle (&optional beg end)
- "Shuffle the playlist between BEG and END."
- nil)
-
-;;; FIXME!
-(defun emms-playlist-sort (&optional beg end)
- "Sort the playlist between BEG and END.
-This uses `emms-sort-lessp-function'."
- ;; That exists!
- nil)
-
+(defun emms-playlist-shuffle (beg end)
+ "Shuffle the tracks in the current buffer between BEG and END."
+ (interactive "r")
+ (save-excursion
+ (goto-char beg)
+ (let* ((tracks (vconcat (emms-playlist-extract-tracks beg end)))
+ (len (length tracks))
+ (i 0))
+ (emms-shuffle-vector tracks)
+ (while (< i len)
+ (emms-playlist-insert-track (aref tracks i))
+ (setq i (1+ i))))))
+
+(defun emms-playlist-sort (beg end)
+ "Sort the tracks in the current buffer between BEG and END."
+ (interactive "r")
+ (save-excursion
+ (goto-char beg)
+ (mapc 'emms-playlist-insert-track
+ (sort (emms-playlist-extract-tracks beg end)
+ emms-sort-lessp-function))))
+
+(defun emms-playlist-extract-tracks (beg end)
+ "Return a list of tracks between BEG and END, and delete them."
+ (let* ((beg (if (emms-playlist-track-at beg)
+ (car (emms-property-region beg 'emms-track))
+ beg))
+ (end (if (emms-playlist-track-at end)
+ (cdr (emms-property-region beg 'emms-track))
+ end))
+ (tracks (emms-playlist-tracks-in-region beg end)))
+ (delete-region beg end)
+ tracks))
+
+(defun emms-playlist-tracks-in-region (beg end)
+ "Return all tracks between BEG and END."
+ (let ((tracks nil)
+ (donep nil))
+ (save-restriction
+ (narrow-to-region beg end)
+ (condition-case nil
+ (emms-playlist-first)
+ (error
+ (setq donep t)))
+ (while (not donep)
+ (setq tracks (cons (emms-playlist-track-at (point))
+ tracks))
+ (condition-case nil
+ (emms-playlist-next)
+ (error
+ (setq donep t)))))
+ tracks))
+
+(defun emms-shuffle-vector (vector)
+ "Shuffle VECTOR."
+ (let ((i (- (length vector) 1)))
+ (while (>= i 0)
+ (let* ((r (random (1+ i)))
+ (old (aref vector r)))
+ (aset vector r (aref vector i))
+ (aset vector i old))
+ (setq i (- i 1))))
+ vector)
;;; Sources
@@ -666,7 +745,8 @@ See emms-source-file.el for some examples."
(cdr source)))
,sources)
,(when shufflep
- '(emms-playlist-shuffle))))
+ '(emms-playlist-shuffle (point-min)
+ (point-max)))))
;;; Players