diff options
-rw-r--r-- | lisp/emms-metaplaylist-mode.el | 160 |
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) |