aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lisp/emms-metaplaylist-mode.el160
1 files changed, 110 insertions, 50 deletions
diff --git a/lisp/emms-metaplaylist-mode.el b/lisp/emms-metaplaylist-mode.el
index 572b7b9..e1ccda7 100644
--- a/lisp/emms-metaplaylist-mode.el
+++ b/lisp/emms-metaplaylist-mode.el
@@ -1,6 +1,6 @@
;;; emms-metaplaylist-mode.el --- A major mode for lists of Emms playlists
-;; Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+;; Copyright (C) 2006, 2007, 2008, 2009, 2017 Free Software Foundation, Inc.
;; Author: Yoni Rabkin <yrk@gnu.org>
@@ -42,7 +42,7 @@
:prefix "emms-metaplaylist-mode-"
:group 'multimedia)
-(defcustom emms-metaplaylist-mode-buffer-name "*Emms Playlists*"
+(defcustom emms-metaplaylist-mode-buffer-name "*Emms Playlist Buffers*"
"*Name of the buffer in which Emms playlists will be listed."
:type 'string
:group 'emms-metaplaylist-mode)
@@ -81,13 +81,16 @@
(defconst emms-metaplaylist-mode-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map text-mode-map)
- (define-key map (kbd "n") 'next-line)
- (define-key map (kbd "p") 'previous-line)
+ (define-key map (kbd "n") 'next-line)
+ (define-key map (kbd "p") 'previous-line)
(define-key map (kbd "RET") 'emms-metaplaylist-mode-goto-current)
- (define-key map (kbd "q") 'kill-this-buffer)
- (define-key map (kbd "?") 'describe-mode)
- (define-key map (kbd "SPC") 'emms-metaplaylist-set-active)
- (define-key map (kbd "c") 'emms-metaplaylist-new-buffer)
+ (define-key map (kbd "SPC") 'emms-metaplaylist-mode-set-active)
+ (define-key map (kbd "g") 'emms-metaplaylist-mode-update)
+ (define-key map (kbd "C") 'emms-metaplaylist-mode-new-buffer)
+ (define-key map (kbd "C-k") 'emms-metaplaylist-mode-kill-buffer)
+ (define-key map (kbd "c") 'emms-metaplaylist-mode-center-current)
+ (define-key map (kbd "q") 'kill-this-buffer)
+ (define-key map (kbd "?") 'describe-mode)
map)
"Keymap for `emms-metaplaylist-mode'.")
@@ -98,62 +101,115 @@
(defun emms-metaplaylist-mode-goto-current ()
"Switch to the buffer at point."
(interactive)
- (switch-to-buffer
- (buffer-substring (point-at-bol)
- (point-at-eol))))
+ (let ((buffer (get-buffer
+ (buffer-substring (point-at-bol)
+ (point-at-eol)))))
+ (emms-playlist-set-playlist-buffer buffer)
+ (switch-to-buffer buffer)))
+
+(defun emms-metaplaylist-mode-write (playlists)
+ "Print the sorted list of PLAYLISTS."
+ (delete-region (point-min) (point-max))
+ (mapc (lambda (buf)
+ (let ((inhibit-read-only t))
+ (insert (buffer-name buf))
+ (add-text-properties
+ (point-at-bol) (point-at-eol)
+ (list 'face
+ (if (eq buf emms-playlist-buffer)
+ 'emms-metaplaylist-mode-current-face
+ 'emms-metaplaylist-mode-face)))
+ (newline)))
+ playlists))
+
+;; Emms' list changes order, and that's OK, but we want something
+;; stable for display purposes.
+(defun emms-metaplaylist-mode-sorted-buffer-list ()
+ "Return a sorted list of playlist buffers."
+ (sort
+ (copy-tree
+ (emms-playlist-buffer-list))
+ #'(lambda (a b)
+ (string< (buffer-name a)
+ (buffer-name b)))))
+
+(defun emms-metaplaylist-mode-center-current ()
+ "Center on the current playlist buffer"
+ (interactive)
+ (when (not emms-playlist-buffer)
+ (error "no current playlist buffer"))
+ (goto-char (point-min))
+ (when (not (search-forward-regexp
+ (or (buffer-name emms-playlist-buffer)
+ "")
+ (point-max) t))
+ (goto-char (point-min)))
+ (goto-char (point-at-bol)))
-;; Since there will never be a significantly large amount of playlist
-;; buffers co-existing at once, we allow ourselves not to keep
-;; state. We regenerate the playlists buffer anew on demand.
(defun emms-metaplaylist-mode-create ()
- "Create or recreate the meta-playlist buffer."
+ "Create the meta-playlist buffer."
(let ((name emms-metaplaylist-mode-buffer-name)
- (playlists (emms-playlist-buffer-list)))
+ (playlists (emms-metaplaylist-mode-sorted-buffer-list)))
(if playlists
- (progn
- (condition-case nil
- (kill-buffer name)
- (error nil))
- (get-buffer-create name)
- (with-current-buffer name
- (emms-metaplaylist-mode)
- (save-excursion
- (mapc (lambda (buf)
- (let ((inhibit-read-only t))
- (insert (buffer-name buf))
- (add-text-properties
- (point-at-bol) (point-at-eol)
- (list 'face
- (if (eq buf emms-playlist-buffer)
- 'emms-metaplaylist-mode-current-face
- 'emms-metaplaylist-mode-face)))
- (newline)))
- playlists))
- (current-buffer))) ; return the buffer as lisp obj
+ (with-current-buffer (get-buffer-create name)
+ (emms-metaplaylist-mode)
+ (emms-metaplaylist-mode-write playlists)
+ (emms-metaplaylist-mode-center-current)
+ (current-buffer))
(error "No Emms playlist buffers"))))
+(defun emms-metaplaylist-mode-assert-buffer ()
+ "Assert that we are in the metaplaylist mode buffer."
+ (when (not (eq (current-buffer)
+ (get-buffer emms-metaplaylist-mode-buffer-name)))
+ (error "not the metalplaylist buffer")))
+
+(defun emms-metaplaylist-mode-update ()
+ "Update the metalplaylist display."
+ (interactive)
+ (emms-metaplaylist-mode-assert-buffer)
+ (let ((inhibit-read-only t))
+ (emms-metaplaylist-mode-write
+ (emms-metaplaylist-mode-sorted-buffer-list)))
+ (emms-metaplaylist-mode-center-current))
+
+(defun emms-metaplaylist-mode-kill-buffer ()
+ "Kill the buffer at point"
+ (interactive)
+ (let ((buffer (get-buffer
+ (buffer-substring (point-at-bol)
+ (point-at-eol)))))
+ (when (not buffer)
+ (error "can't find buffer at point"))
+ (if (y-or-n-p (format "kill playlist buffer \"%s\"?"
+ (buffer-name buffer)))
+ (kill-buffer buffer)
+ (message "Buffer kill aborted."))
+ (emms-metaplaylist-mode-update)))
+
+
;;; --------------------------------------------------------
-;;; Playlist Management : creation, deletion (?)
+;;; Playlist Management
;;; --------------------------------------------------------
-(defun emms-metaplaylist-new-buffer (buffer-name)
- "Creates a new buffer called buffer-name, which will be ready
-to host EMMS tracks."
+(defun emms-metaplaylist-mode-new-buffer (buffer-name)
+ "Creates a new buffer playlist buffer BUFFER-NAME."
(interactive "sBuffer Name: ")
- (if(get-buffer buffer-name)
+ (if (get-buffer buffer-name)
(error "Buffer must not exist.")
(let ((buf (get-buffer-create buffer-name)))
(with-current-buffer buf
- (setq emms-playlist-buffer-p t)))
- (message "Buffer created")))
+ (emms-playlist-mode)
+ (setq emms-playlist-buffer-p t)))
+ (emms-metaplaylist-mode-update)))
-(defun emms-metaplaylist-set-active ()
+(defun emms-metaplaylist-mode-set-active ()
+ "Set the buffer at point to be the active playlist."
(interactive)
(emms-playlist-set-playlist-buffer
(get-buffer (buffer-substring (point-at-bol) (point-at-eol))))
- (let ((ici (point)))
- (emms-metaplaylist-mode-go)
- (goto-char ici)))
+ (emms-metaplaylist-mode-update))
+
;;; --------------------------------------------------------
;;; Mode entry
@@ -162,12 +218,16 @@ to host EMMS tracks."
(defun emms-metaplaylist-mode-go ()
"Single entry point to the metaplaylist interface."
(interactive)
- (emms-metaplaylist-mode-create)
- (switch-to-buffer emms-metaplaylist-mode-buffer-name))
+ (let ((mpm-buffer (get-buffer emms-metaplaylist-mode-buffer-name)))
+ (if mpm-buffer
+ (with-current-buffer mpm-buffer
+ (emms-metaplaylist-mode-update))
+ (setq mpm-buffer (emms-metaplaylist-mode-create)))
+ (switch-to-buffer mpm-buffer)))
(defun emms-metaplaylist-mode ()
"A major mode for Emms playlists."
-;; (interactive)
+ ;; (interactive)
(kill-all-local-variables)
(use-local-map emms-metaplaylist-mode-map)