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)  | 
