aboutsummaryrefslogtreecommitdiff
path: root/emms-playlist-limit.el
blob: 429d5b2adba610b5f7a2feca645087d096482773 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
;;; emms-playlist-limit.el --- limit playlist by various info

;; Copyright (C) 2007 William Xu

;; Author: William Xu <william.xwl@gmail.com>
;; Keywords: emms, limit

;; EMMS is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.

;; EMMS is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with EMMS; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
;; Boston, MA 02110-1301, USA.

;;; Code:

(require 'emms-playlist-mode)

;;; User Interfacs

;;;###autoload
(defun emms-playlist-limit (arg)
  "Turn on emms limit if ARG is positive, off otherwise."
  (interactive "p")
  (if (and arg (> arg 0))
      (add-hook 'emms-playlist-source-inserted-hook
                'emms-playlist-limit-update-tracks)
    (remove-hook 'emms-playlist-source-inserted-hook
                 'emms-playlist-limit-update-tracks)))

(defmacro define-emms-playlist-limit (attribute)
  "Macro for defining emms playlist limit functions."
  `(defun ,(intern (format "emms-playlist-limit-to-%s" attribute)) (regexp)
     ,(format "Limit to playlists that have %s that matches REGEXP." attribute)
     (interactive
      (list
       (let* ((curr
               (or (emms-track-get
                    (emms-playlist-track-at) (quote ,attribute))
                   (emms-track-get
                    (emms-playlist-selected-track) (quote ,attribute))))
              (fmt (if curr
                       (format "Limit to artist (regexp = %s): " curr)
                     (format "Limit to artist (regexp): "))))
         (read-string fmt))))
     (when (string= regexp "")
       (setq regexp (emms-track-get (emms-playlist-track-at) (quote ,attribute))))
     (emms-playlist-limit-do (quote ,attribute) regexp)))

(define-emms-playlist-limit info-artist)
(define-emms-playlist-limit info-album)
(define-emms-playlist-limit info-year)
(define-emms-playlist-limit info-genre)
(define-emms-playlist-limit name)

(defun emms-playlist-limit-to-all ()
  "Show all tracks again."
  (interactive)
  (emms-playlist-limit-do nil nil))

(define-key emms-playlist-mode-map (kbd "/ n") 'emms-playlist-limit-to-name)
(define-key emms-playlist-mode-map (kbd "/ a") 'emms-playlist-limit-to-info-artist)
(define-key emms-playlist-mode-map (kbd "/ t") 'emms-playlist-limit-to-info-title)
(define-key emms-playlist-mode-map (kbd "/ b") 'emms-playlist-limit-to-info-album)
(define-key emms-playlist-mode-map (kbd "/ y") 'emms-playlist-limit-to-info-year)
(define-key emms-playlist-mode-map (kbd "/ g") 'emms-playlist-limit-to-info-genre)
(define-key emms-playlist-mode-map (kbd "/ /") 'emms-playlist-limit-to-all)


;;; Low Level Functions

(defvar emms-playlist-limit-tracks nil
  "All tracks in playlist buffer.")

(defun emms-playlist-limit-update-tracks ()
  "Update `emms-playlist-limit-tracks'."
  (setq emms-playlist-limit-tracks
        (append emms-playlist-limit-tracks
                (emms-playlist-tracks-in-region
                 (point-min) (point-max)))))

(defun emms-playlist-limit-do (name value)
  "Limit by NAME with VALUE.
e.g.,
    (emms-playlist-limit-do 'info-artist \"Jane Zhang\")

When NAME is nil, show all tracks again.

See `emms-info-mp3find-arguments' for possible options."
  (with-current-emms-playlist
    (save-excursion
      (emms-playlist-ensure-playlist-buffer)
      (let ((curr (emms-playlist-current-selected-track))
            (tracks
             (emms-playlist-tracks-in-region (point-min) (point-max))))
        (erase-buffer)
        (run-hooks 'emms-playlist-cleared-hook)
        (if name
            (mapc (lambda (track)
                    (let ((track-value (emms-track-get track name)))
                      (when (and track-value (string-match value track-value))
                        (emms-playlist-insert-track track))))
                  tracks)
          (mapc (lambda (track)
                  (emms-playlist-insert-track track))
                emms-playlist-limit-tracks))
        (let ((pos (text-property-any (point-min) (point-max)
                                      'emms-track curr)))
          (if pos
              (emms-playlist-select pos)
            (emms-playlist-first)))))))


(provide 'emms-playlist-limit)

;;; emms-playlist-limit.el ends here